编写自己的代码
通过编写代码为bot增加功能并不是一件麻烦的事情,得益于 Python 入门(Python3 教程 | 菜鸟教程 (runoob.com))的简易性,通过阅读下面的教程,即使您不懂代码,也将具备最基本的开发能力。
前置:
- 一定的英语基础
- 使用搜索引擎解决问题的能力
- 一定的阅读和理解能力
- 耐心
1.准备开发工具
好的ide能够使开发事半功倍。
这里推荐VScode
和pycharm社区版
,你可以任选其一,我个人推荐pycharm
Python 的配置
然后是配置python,请注意,python环境请使用python3.9,否则会遇到依赖版本问题。
2.开始开发
从 Manyana 继续开发
- 请使用右键单击Manyana文件夹,选择带有pycharm图标的open as project。
- pycharm应当会自己根据requirements创建虚拟环境。
准备妥当后,可以开始开发了。
我们将以天气查询api为例,完成第一个api功能实现。
1. 在plugins创建一个功能函数
右键plugins文件夹,新建py文件(教程中的命名为test.py,你可以自己调整),我们开始定义函数。
同步方式请求
import requests #导入我们需要的依赖
def weather(city):
r=requests.get(f"https://api.lolimi.cn/API/weather/?city={city}") #我们看到,文档要求我们使用get或post请求皆可,我们使用简单的get请求
return r
print(weather("北京"))
运行这个py文件,我们得到输出
{
"code": 1,
"text": "获取成功",
"data": {
"city": "北京",
"cityEnglish": "beijing",
"temp": "999",
"tempn": "26",
"weather": "多云转小雨",
"wind": "南风转东南风",
"windSpeed": "<3级",
"time": "2024-06-12 08:00",
"warning": {
"windSpeed": "09",
"wind": "雷电",
"color": "黄色",
"warning": "市气象台2024年6月12日18时24分发布雷电黄色预警信号:预计,12日19时至13日05时,本市自西向东将出现雷阵雨,并伴有8级左右短时大风和小冰雹,局地短时雨强较大,影响城区的主要时段为12日22时至13日02时,请注意防范。(预警信息来源:国家预警信息发布中心)",
"time": "2024-06-15 18:37:56"
},
"current": {
"city": "北京",
"cityEnglish": "beijing",
"humidity": "35%",
"wind": "东南风",
"windSpeed": "1级",
"visibility": "17km",
"weather": "阴",
"weatherEnglish": "Overcast",
"temp": "34.8",
"fahrenheit": "94.6",
"air": "130",
"air_pm25": "130",
"date": "06月12日(星期三)",
"time": "18:35",
"image": "http://api.lolimi.cn/API/weather/cache/image/阴.png"
},
# ........后面的我先省略了
异步方式请求
是的,你完成了一个基础的函数,但这里有一个问题,假如你把它接入了bot,你会发现bot在执行天气查询指令的时候,似乎不能干其他的事情了,必须等天气查询结束才会进行别的回复,这极大地降低了bot的效率,因此我们需要使用异步的方式对其进行改写。
import asyncio #异步库
import json
import httpx
async def weatherQ(city): #async def 是异步函数的标识
async with httpx.AsyncClient() as client: #照抄就行
r= await client.get(f"https://api.lolimi.cn/API/weather/?city={city}") #请求的url
return r
asyncio.run(weatherQ("北京"))
同样的结果,但通过这种方式,我们将大大提高bot运行效率。
解析返回结果
你可能发现了,目前返回的这一堆并不美观,json是一种轻量级的数据交换格式,我们请求的结果就是一个json串,我们可以对其进行解析拿到我们想要的数据。
初识json解析
我们将以获取风向为例。
# 前后省略
"wind": "东南风"
想要拿到wind的值,我们可以观察上面的json,得知想要拿到warning我们需要经过 data>current>wind
于是我们可以改写上面的函数
import asyncio
import json
import httpx
async def weatherQ(city): #async def 是异步函数的标识
async with httpx.AsyncClient() as client: #照抄就行
r= await client.get(f"https://api.lolimi.cn/API/weather/?city={city}") #请求的url
data=r.json()
wind=data["data"]["current"]["wind"]
return wind
print(asyncio.run(weatherQ("北京")))
执行结果为
北风
解析并返回关键数据
我们将对其进行进一步改写
import asyncio
import json
import httpx
async def weatherQ(city): #async def 是异步函数的标识
async with httpx.AsyncClient() as client: #照抄就行
r= await client.get(f"https://api.lolimi.cn/API/weather/?city={city}") #请求的url
data=r.json()
weather=data["data"]["weather"]
wind=data["data"]["current"]["wind"]
windSpeed=data["data"]["current"]["windSpeed"]
return f"北京当前天气:{weather},风向:{wind,windSpeed}"
print(asyncio.run(weatherQ("北京")))
运行结果为
北京当前天气:晴,风向:('北风', '2级')
你可以解析并加入其他参数,我就不再演示了。
至此,我们完成了一个plugins函数,接下来我们使其与bot对接
2. 在run实现收发
在run文件夹下新建一个py文件,命名为myTest.py
# -*- coding:utf-8 -*-
from mirai import GroupMessage
from plugins.test import weatherQ
def main(bot, logger):
logger.info("启用天气查询") #logger对象,作为print的高级替代,你看到的Manyana蓝色和各种颜色字体都是它实现的。
@bot.on(GroupMessage) #监听群内事件
async def tellMeWeather(event: GroupMessage):
if str(event.message_chain).startswith("天气查询"): #如果消息以 天气查询 开头
try:
city = str(event.message_chain).replace("天气查询", "") #把 天气查询 替换为空,剩下的就是城市名
weatherResult =await weatherQ(city) #调用异步函数须使用await
logger.info(f"{city} 天气查询结果:{weatherResult}") #再logger一次让控制台看结果
await bot.send(event,weatherResult,True) #向群内发送
except:
logger.info("查询失败,请检查网络连接")
await bot.send(event, "查询失败,请检查网络连接")
好的,我们完成了run下的收发编写,接下来可以接入主程序了。
3. 在main.py导入
打开main.py
翻到末尾,你会看到这些
#前面的统统省略了
groupGames.main(bot, logger)
musicpick.main(bot, logger)
appCard.main(bot, logger)
aiDraw.main(bot, logger)
starRail.main(bot, logger)
bangumi.main(bot,logger)
draftBottle.main(bot,logger)
startVer()
bot.run(asgi_server=None)
这些和你刚才编写的myTest.py
一样,都是实现功能收发的函数,我们可以以同样的方式导入你的myTest.py
,只要在bot.run
之前导入即可。
#前面的统统省略了
myTest.main(bot,logger) #我们导入了刚才编写的myTest
groupGames.main(bot, logger)
musicpick.main(bot, logger)
appCard.main(bot, logger)
aiDraw.main(bot, logger)
starRail.main(bot, logger)
bangumi.main(bot,logger)
draftBottle.main(bot,logger)
startVer()
bot.run(asgi_server=None)
一般来说你的ide
会自动导入myTest.py
,如果没有,就在main.py
最前面加入一行
from run import myTest
4.测试看看
重新启动main.py
,在群内发送 天气查询北京 即可收到bot返回的结果。