Open RF-Tar-Railt opened 1 year ago
Q: 如果对接形似 python-satori 或者极端一点的 avilla,网络通信的部分应如何处理?
A: 适配器的网络通信部分针对的是适配器通过网络通信与对应平台交互的情况。若适配器使用的是另外的sdk,则适配器本体不关心网络部分。但是相应的,适配器应对sdk做类似处理(e.g. 挂载运行任务,处理异常返回)
check_at_me:检查消息首部或尾部是否是 @bot_self, 如果是则移除,并且连带@后随的空格一并移除,设 to_me 为真。尾部 at 不强制要求。
/some_command@some_bot
的形式,这种似乎不符合 “尾部或首部” 的定义……?check_at_me:检查消息首部或尾部是否是 @bot_self, 如果是则移除,并且连带@后随的空格一并移除,设 to_me 为真。尾部 at 不强制要求。
Q: 存疑的,例如 Telegram 平台中,对于调用某个 Bot 的指令,可以用
/some_command@some_bot
的形式,这种似乎不符合 “尾部或首部” 的定义……?
按ddl说法,这种情况的 @ 确实得移除(只要是 @ 当前bot自己的)
可以在适配器编写教程中写一写吧
提案:对于存在 "回复消息" 的适配器,是否强制要求在消息段层面实现一个 MessageSegment.reply,或要求在 send 接口增加与 reply 相关的参数? (例如,feishu 适配器有专门的接口发送回复消息,tg适配器有专门的参数指定回复元素,而 red,sattori,qq 适配器则可以直接在 Message 中构造回复元素)
我的评价是: avilla.standard.core
新增:第 13条 MessageSegment.text
的 data 必须为 {"text": xxx}
更新:第 7条
@ssttkkl @Tian-que
新增:第14条 对于某些平台存在元素包含特殊子元素的情况(例如,kook平台的 KMarkdown 包含 mention, emoji等子元素),适配器应特殊处理,将这些子元素提取为单独的消息段。 @ssttkkl @Tian-que
更新第9条:
适配器应当在 Bot 上编写常用的方法/接口,并写明每个接口的输入类型和输出类型。如果对接协议不存在或未允许扩展api,请将Bot的getattr方法明确写为不支持(def __getattr__(self, item): raise NotImplementError
);否则需要编写 bot.pyi 或生成全部的可用方法,而不是完全让用户使用call_api。
希望能解决的问题
Nonebot现在的适配器很多,但是基本上都是各写各的,没有相对的统一结构,甚至存在代码质量的问题(e.g. Bilibili适配器)。
在这份issue中,我们提出了一个通用的适配器规范,其不会影响适配器的平台特性,并且能为用户提供更好的使用体验。
描述所需要的功能
以下规范依据文件名划分
adapter.py
exception.py
基于[4],适配器应继承
nonebot.exception
中的基础异常类型,声明适配器特定异常:event.py
Event
应存在time
字段,表示事件创建的时间。time 为datetime.datetime
类型。MessageEvent
应存在如下字段:to_me
: bool 类型,可选(因为主要是 is_tome 方法)。reply
: 一般为 reply 对应的原始消息/原始事件(由 reply 上的 msgid获取);同时也可以为自定义结构(e.g. ob12适配器下的Reply),但是应当挂载一个async def get_origin()
方法,以获取原始事件;若平台不存在回复元素,置空即可。message
/_message
: 适配器对应的 Message 类型。若原事件已存在 message字段并无法转换类型,则使用 _messageoriginal_message
: 适配器对应的 Message 类型,并且未经过 check_at_me, check_reply 等处理。message_id
: 消息id (有时与事件id等同),用于构造回复消息,撤回消息,编辑消息等操作;若平台不存在消息id,使用 "" 或随机生成即可。其中
_message
,original_message
可如下处理:bot.py
适配器应当在 handle_event内执行 check_reply, check_at_me, check_nickname。
reply
属性。在此之上,若回复的是 bot 自己的消息,则设 to_me 为真。适配器应当在 Bot 上编写常用的方法/接口,并写明每个接口的输入类型和输出类型。如果对接协议不存在或未允许扩展api,请将Bot的getattr方法明确写为不支持(
def __getattr__(self, item): raise NotImplementError
);否则需要编写 bot.pyi 或生成全部的可用方法,而不是完全让用户使用call_api。Bot 应声明自己的 adapter属性为适配器对应的 Adapter 类型:
message.py
适配器应在 message.py 内编写原始数据转为消息序列的方法(e.g. Message.from_guild_message)。
消息段应尽量使用子类消息段+父类消息段静态方法合集:
MessageSegment.text
的 data 必须为{"text": xxx}
。对于某些平台存在元素包含特殊子元素的情况(例如,kook平台的 KMarkdown 包含 mention, emoji等子元素),适配器应特殊处理,将这些子元素提取为单独的消息段。
utils.py
README.md
pyproject.toml