Skip to content

[NEXT] 编写新功能 实战篇

Zack Zhou edited this page Sep 25, 2020 · 1 revision

身为Python零基础为了做bot自学到现在的我,自然是理解大家看到各类文档时候的心情,除了必要的理论说明之外,最好给我来个手把手教学。所以在这里,我们写一个简单的小插件,来体验一下给老帕写插件的流程。

复习时间

老帕处理消息的流程从接收到 json 格式的上报开始:

  1. 先把 json 传递给 预处理/Preprocessors,预处理把 json 逐个传递,每个预处理都会把处理后的 json 返回来,并附加一个 布尔值 表示是否停止这条消息的处理。总结:前置审核,生杀大权。
  2. 再把 json 传递给 BOT命令/Plugins,每个bot命令都提供了自己的关键字,一旦关键字命中,执行这个命令并返回内容。总结:正式干活。
  3. 如果没有命中任何命令,再把 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

结语

从某些角度上讲,现在这种模式比以前加功能简单多了,而且还能通过网页调整设置。当然了,和以前一样,大概除了我也没人会给老帕写插件的吧……

Clone this wiki locally