功能函数注册

# 简单说明

AmiyaBot 功能开发的关键模块一共有三个,分别是 core 模块下的 botMessageChain

  • bot 为主要入口,包含了消息和事件的注册器,以及一些注册工具函数。
  • Message 为接收的消息主体,内含预解析的消息内容,以及一些相关操作函数。Message 对象在此仅用于参数类型注解,供编辑器智能提示使用,任何时候,你都不需要实例化 Message 对象。
  • Chain 为 Mirai 消息链的创建工具。所有需要发送的消息,都必须由 Chain 类创建。核心会调用 Chain 类的 build 方法生成 Mirai 消息链。

编写功能函数的文件,统一创建在 function 目录内,目录层级不限。
了解以上内容,下面让我们注册一个简单的群聊功能。

# 创建功能函数文件

我们在 function 目录内创建一个 hello.py




 

.
└── functions
    ├── __init__.py
    └── hello.py
1
2
3
4

随后,在 __init__.py 内,添加刚刚新建的 hello 模块。



 


from . import (
    ...
    hello
)
1
2
3
4

# 注册一个功能

# 示例一

当对话内容带有 你好 关键字时,回复 你好,世界
在刚刚新建的 hello.py 内,编写如下代码。

from core import bot, Message, Chain


@bot.on_group_message(keywords='你好')
async def _(data: Message):
    return Chain(data).text('你好,世界')
1
2
3
4
5
6

现在,在你的群聊里发送 阿米娅你好,不出意外的话,你将会收到如下的回复。

hello_world_1
「这是个人迈出的一小步,但却是人类迈出的一大步。」———— 阿姆斯特朗

接下来,我们了解一下上述代码的构成。

# 功能函数装饰器

功能函数装饰器作用于你的业务逻辑主体函数,其选择监听接收消息的目标。目前装饰器分为 私聊(on_private_message)群聊(on_group_message)临时聊天(on_temp_message)





 





 





 



from core import bot


# 私聊
@bot.on_private_message(...)
async def _(data):
    ...


# 群聊
@bot.on_group_message(...)
async def _(data):
    ...


# 临时聊天
@bot.on_temp_message(...)
async def _(data):
    ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 参数列表

参数名 类型 释义 默认值
function_id String 功能ID,不唯一,仅用于记录该功能的使用数量
keywords KEYWORDS 触发关键字,支持字符串、正则、全等句(equal)或由它们构成的列表
verify VERIFY_CORO 自定义校验方法,当该参数被赋值时,keywords 将会失效
check_prefix PREFIX 是否校验前缀或指定需要校验的前缀 True
level Int 关键字校验成功后函数的候选默认等级 0

check_prefix 在私聊函数(on_private_message)内默认值为 False

# 接收不包含前缀或指定前缀的消息

AmiyaBot 默认需要对话中包含指定前缀才能进入消息分配器,我们认为机器人都应该遵守这一约定。但有时候,人性化一点也未必是一件坏事。
让我们回到 示例一 ,要触发示例一的功能,必须要求对话内容的前缀为 阿米娅 (指定的前缀之一),我们稍加修改,即可在对话没有携带指定前缀时,也能触发功能。

# 示例二





 





 



from core import bot, Message, Chain


# 在原来的基础上添加参数 check_prefix=False 可忽略前缀检查
@bot.on_group_message(keywords='你好', check_prefix=False)
async def _(data: Message):
    return Chain(data).text('你好,世界')


# 也可以让前缀检查临时改为你指定的单词
@bot.on_group_message(keywords='你好', check_prefix=['兔兔', '🐰'])
async def _(data: Message):
    return Chain(data).text('你好,世界')
1
2
3
4
5
6
7
8
9
10
11
12
13
hello_world_2

注意

除特定用法之外,任何时候都是需要检查指定前缀!

# 接收全等句式

全等句式指对话的内容完全为设定的句子,并非通过关键词触发,使用工具 bot.equal 即可达到效果。

# 示例三




 



from core import bot, Message, Chain


@bot.on_group_message(keywords=bot.equal('你好'))
async def _(data: Message):
    return Chain(data).text('你好,世界')
1
2
3
4
5
6

小技巧

示例三同样也能达到示例二的接收不包含前缀的消息的效果,因为全等句式不会检查前缀。

# 接收符合正则检查的句式

关键词传入 re.compile 对象,即可使用正则检查。

# 示例四

 




 



import re

from core import bot, Message, Chain


@bot.on_group_message(keywords=re.compile(r'你好,\d+'))
async def _(data: Message):
    return Chain(data).text('你好,世界')
1
2
3
4
5
6
7
8

# 组合多个和多种关键词

关键字支持由 字符串、正则、全等句 构成的列表,组合中包含全等句时,全等句依然会无视前缀检查。

# 示例五






 



import re

from core import bot, Message, Chain


@bot.on_group_message(keywords=['你好', '您好', bot.equal('你好'), re.compile(r'你好,(\d+)')])
async def _(data: Message):
    return Chain(data).text('你好,世界')
1
2
3
4
5
6
7
8

# 优先级

当关键词校验存在冲突时,可以通过指定优先级供消息分配器选择。
分配器的工作原理,是在完成检查之后,将通过校验的候选函数列表按优先级倒序排序,然后选取第一个执行。
所有函数的默认优先级都为 1,如果不指定优先级,分配器会按照加载的先后顺序选择。

# 示例六







 




 



from core import bot, Message, Chain


# 如果不指定优先级,当对话内容为 "世界你好" 时,第一个函数会首先通过校验并输出。
# 因为在模块加载阶段,第一个函数更早注册完毕。

@bot.on_group_message(keywords='你好', level=1)
async def _(data: Message):
    return Chain(data).text('你好,世界')


@bot.on_group_message(keywords='世界你好', level=2)
async def _(data: Message):
    return Chain(data).text('世界,你好')
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 自定义检查

内置的检查终究存在上限,如果需要制作复杂的功能,自定义检查必不可少。
自定义检查是一个协程函数,参数为 Message 对象,返回一个布尔值(必选)、优先级(可选)、关键词(可选)的元祖。

async def my_verify(data: Message):
    if ...:
        return True
    return False
1
2
3
4

在自定义检查里,你可以动态输出优先级的值。



 

 


async def my_verify(data: Message):
    if ...:
        return True, 2
    elif ...:
        return True, 1
    return False
1
2
3
4
5
6

输出关键词可将其赋值到 Verify 对象的 keywords 属性内,Verify 对象我们会在后续详细说明。

async def my_verify(data: Message):
    return True, 1, ['关键词', ...]
1
2

# 示例七










 



from core import bot, Message, Chain


async def my_verify(data: Message):
    if '你好' in data.text:
        return True
    return False


@bot.on_group_message(verify=my_verify)
async def _(data: Message):
    return Chain(data).text('你好,世界')
1
2
3
4
5
6
7
8
9
10
11
12

# 结语

现在,你已经知道功能的各种基本的注册方式了。下一节,我们去了解功能函数的参数 Message 对象。

上次更新: 12/14/2022, 12:49:25 PM