消息的接收与发送🔗
本章简单阐述以下内容:
MessageReceived
事件的应用- 关系对象
Relationship
的说明 - 选择器
Selector
的简单说明 - 辅助筛选器
Filter
的简单使用
MessageReceived 事件🔗
于序曲中, 我们有对 MessageReceived
事件的初步认识,
本节将继续阐述其各项特性, 并简单介绍 Avilla 中的主要操作接口: 关系对象 Relationship
.
将目光聚焦于序曲中我们所给出的代码片段.
@broadcast.receiver(MessageReceived)
async def on_message_received(event: MessageReceived, rs: Relationship):
if Selector.fragment().as_dyn().group("*").member("master-account").match(rs.ctx):
await rs.send_message("Hello, Avilla!")
MessageReceived
事件表示应用实例接受到来自某个平台的消息.
而为了后续指代方便, 我们将像是 QQ, Discord, Telegram 这种称为 Land
.
通常的, MessageReceived 会包含消息的内容, 接受到消息的账号, 事件发生或是接受事件时的时间这些信息.
消息的内容则包含消息的发送者, 消息是在哪里被发送的, 其所回复的另外一条消息(以 Selector 表示)等充分的信息. 关于其字段名称等信息请参阅 [avilla.core.event.message.MessageReceived]
关系对象 Relationship🔗
当接受到一条消息后, Avilla 会自动解析当前接受到消息的账号与消息发送者的关系,
将其总结为 Relationship
对象. Relationship
对象也是开发中最常见的操作接口.
Relationship.ctx
, 即片段中的 rs.ctx
, 我们可以根据上下文给出其定义,
因此其被称为 "上下文对象".
Relationship.mainline
表示 Avilla 解析到的上下文场景, 在此举个简单的例子吧, 如果 rs.ctx
指代的是群员, 那么 rs.mainline
就会指向群员和账号所在的群组, 以此类推.
选择器 Selector🔗
无论是 ctx
还是 mainline
, 他们都采用了 Selector
的方式表示.
选择器对象是 Avilla 设计中所采用的概念 "对象与数据分离" 的体现, 但在此不做过多介绍.
一个选择器通常是这样的:
Selector().group("...").member("...")
作为人类, 我们可以很直观的认识到这样一个选择器所指代的对象, 即 "群员",
而 Selector 还包含了机器可读的特性. 这个选择器可以被视为这样一个字典: {"group": "...", "member": "..."}
,
由于 Python 中的字典是有序的, 所以 Selector 所包含的信息可以在这两种表达方式间随意转换.
因其具有独特的数据结构, Selector 有着一套复杂的匹配方式, 这将会在后续章节中谈到.
关系对象不仅用于向开发者暴露上下文, 还用于对于不限于上下文对象和上下文场景的操作.
如片段中我们使用 rs.send_message
发送了消息, 这项功能的背后是由 Trait & Fn
系统提供支持, 同样这套系统亦会在后续章节中细细阐述.
发送消息🔗
rs.send_message
支持以字符串(str
), 消息元素(Element
), 消息元素列表(list[Element]
), 消息链(MessageChain
)作为需要发送的消息内容. 消息链的实现由 Graia Amnesia 提供支持.
await rs.send_message("字符串消息")
await rs.send_message(Notice(rs.ctx)) # @rs.ctx, 也通常被称为 At 的消息元素
await rs.send_message([Text("消息元素列表"), Notice(rs.ctx)])
await rs.send_message(MessageChain(...))
回复消息🔗
如果平台支持, 在调用 rs.send_message
时, 可以指定回复的消息.
回复消息需要一个指向消息本身的选择器 Selector, 你可以通过 MessageReceived.message.to_selector()
获取接收到的消息的选择器表达形式.
await rs.send_message(..., reply=event.message.to_selector()) # 注意, "reply=" 不能舍去.
筛选消息类型🔗
由于 MessageReceived
事件承载群聊, 私聊等方式的消息, 开发者有需求对消息进行筛选.
在这方面, Avilla 提供了 Filter
作为辅助.
from avilla.core.tools.filter import Filter
@broadcast.receiver(MessageReceived, dispatchers=[
Filter.rs().ctx.follows("group.member") # 仅对 rs.ctx 为 group.member 时可用.
Filter.rs().mainline.folllows("group=...") # 仅在 mainline 为 group=... 时可用.
])
async def on_message_received(event: MessageReceived, rs: Relationship):
if Selector.fragment().as_dyn().group("*").member("master-account").match(rs.ctx):
await rs.send_message("Hello, Avilla!")
[avilla.core.tools.filter.Filter] 还有很多功能, 在此希望读者能自行前去了解.