-
Notifications
You must be signed in to change notification settings - Fork 3
[NEXT] 编写新功能 实战篇
身为Python零基础为了做bot自学到现在的我,自然是理解大家看到各类文档时候的心情,除了必要的理论说明之外,最好给我来个手把手教学。所以在这里,我们写一个简单的小插件,来体验一下给老帕写插件的流程。
老帕处理消息的流程从接收到 json
格式的上报开始:
- 先把
json
传递给预处理/Preprocessors
,预处理把json
逐个传递,每个预处理都会把处理后的json
返回来,并附加一个布尔值
表示是否停止这条消息的处理。总结:前置审核,生杀大权。 - 再把
json
传递给BOT命令/Plugins
,每个bot命令都提供了自己的关键字,一旦关键字命中,执行这个命令并返回内容。总结:正式干活。 - 如果没有命中任何命令,再把
json
传递给后处理/Postprocessors
,后处理再看有没有需要回复的,例如复读这种没有固定关键字的功能,每个后处理都会收到当前的json
和当前还没发出去的回复内容resp
,然后处理后返回resp
和HTTP状态码(200表示回复出去,204表示继续下一个处理)。总结:收尾工作。
由于预处理和后处理用到的机会比较少,先从BOT命令下手,来写个小插件。
我们这次先写一个非常简单的农历小插件,它的功能只有一个,有人在群里说“农历”两个字的时候,回复今天的农历。
首先,还是得复习一下插件结构:
Paarthurnax
|- plugins
| |- your_plugin
| | |- __init__.py
| | |- logic.py
所以我们从第一步开始,先把文件创建好,在 Paarthurnax/plugins
文件夹中,新建一个 nongli
文件夹,然后在里面放上必须存在的 __init__.py
和我们的主要逻辑实现 nongli.py
,最后文件夹结构看起来应该像这样:
Paarthurnax
|- plugins
| |- nongli
| | |- __init__.py
| | |- nongli.py
用Python来计算农历有多困难呢?当然是先去找个库啦。我帮你找好了,这个库叫Borax,当然先得安装它,pip install borax
相信会写Python的你早就会了。
对于bot命令,要求其实不高,只需要返回一个字符串,如果是空字符串,老帕就会无视,否则老帕就会把它原封不动发出去。
也就是说,只需要一个返回今天农历字符串的函数即可,我们打开 nongli.py
,写一个这个功能的函数叫 nongli
:
from borax.calendars.lunardate import LunarDate
def nongli():
today = LunarDate.today()
return today.strftime(r'今天是:%Y年%M月%D,%G')
没啥难度对吧,这一步应该很好搞定的。
下一步,我们开始告诉老帕这个插件怎么用,打开 __init__.py
,先来个空模板:
# Metadata for plugin
#
# bot_command template:
# 'keyword':
# [function,
# 0 - blocklist / 1 - allowlist,
# ['groupid1', 'groupid2'],
# cooldown in seconds,
# is message body required,
# is keyword regex,
# is suffix suppressed],
Metadata = {
'alert_functions': {
},
'bot_commands': {
},
'preprocessors': [
],
'postprocessors': [
],
}
至于说这个模板哪里找,随便打开一个自带插件都会有。
我们写的是bot命令,自然要放在 bot_commands
里。
在这里重新复习一下以前的 config.py
格式:
bot_commands = {
"关键词": [函数, 是否白名单, [群号], 冷却时间秒, 是否需要用户输入信息, 关键词是不是正则表达式, 是否要隐藏结束语]
}
- 关键词:就是说到哪个词触发命令。
- 函数:就是要执行的功能函数。
- 是否白名单:0是黑名单,1是白名单,黑名单模式下,后面列出的群号不能使用这个关键字;白名单模式下,只有后面列出的群号才能使用这个关键字。
- 群号:就是群号。一个list,可以写很多个。
- 冷却时间秒:多久才能用一次这个关键字,冷却中的关键字老帕会提示
技能冷却中
。 - 是否需要用户输入信息:比如今天的农历,那就不需要任何参数;如果是要求用户输入“农历 2020.09.25”然后计算当天的农历,那就是需要用户输入的信息。这两个的主要区别是,需要用户输入信息的,关键字是按照开头匹配,而且老帕回复时会自动at他/她/它/祂一下;不需要用户输入信息的,关键词必须完全命中。
- 关键词是不是正则表达式:就……关键词也可以是正则表达式,这样规则写起来更飘逸。改版之后老帕不再支持给同一个函数设置多个关键字,可以通过正则来写。
- 是否要隐藏结束语:老帕默认会在回复的最后补一句“更多命令请输入【帮助】”,毕竟是bot的传统艺能。设置为
True
就不会回复这句了。
回到我们的农历功能上,今天的农历,不需要用户去指定什么,也不想在后面带一条多余的内容,因此写出来就是:
import Paarthurnax.plugins.nongli.nongli as nl
Metadata = {
'alert_functions': {
},
'bot_commands': {
'农历': [nl.nongli, 0, [], 10, False, False, True],
},
'preprocessors': [
],
'postprocessors': [
],
}
保存,重启老帕,然后bot开起来,试一下:
就很不可思议是不是?但是管用!
对于更复杂的bot命令,无非就是需要接收 json
作为参数,也就是这样:
def complex_bot_command(json):
message = json['message']
# do stuff
return message
看过OneBot的上报格式之后,也不是很难理解。
至于其他几个的写法,预处理/Preprocessors
可以参考自定义头衔插件 p_customtitle
,后处理/Postprocessor
可以参考自定义回复插件 p_customreplies
。警报/Alert_functions
实际上真的很难用到,可以参考主要功能Warframe通报插件 p_warframe
。
从某些角度上讲,现在这种模式比以前加功能简单多了,而且还能通过网页调整设置。当然了,和以前一样,大概除了我也没人会给老帕写插件的吧……