From 501d40fdeeb53ea43d6edd6f23c8d7cdf213fdbf Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Sat, 27 Jul 2024 23:45:59 +0800 Subject: [PATCH] perf --- ...22\344\273\266\345\274\200\345\217\221.md" | 134 ++++++++++++++++-- 1 file changed, 125 insertions(+), 9 deletions(-) diff --git "a/docs/\345\274\200\345\217\221/\346\217\222\344\273\266\345\274\200\345\217\221.md" "b/docs/\345\274\200\345\217\221/\346\217\222\344\273\266\345\274\200\345\217\221.md" index 571acfd..29820da 100644 --- "a/docs/\345\274\200\345\217\221/\346\217\222\344\273\266\345\274\200\345\217\221.md" +++ "b/docs/\345\274\200\345\217\221/\346\217\222\344\273\266\345\274\200\345\217\221.md" @@ -110,6 +110,131 @@ cmd_result = CommandResult( ) ``` +# 主动发送消息 + +插件可以主动给受支持的平台发送消息。(>=v3.3.3) + +采用 context.platforms 获取所有已注册(启用)的平台。 + +```py +platforms = context.platforms +``` + +`platfroms` 为一个列表,列表中的每个元素都是一个 RegisteredPlatform 对象。RegisteredPlatform 对象包含以下属性: + +- platform_name: str +- platform_instance: Platform +- origin: str = None # 注册来源 + +当前 AstrBot 内部支持的平台的 platform_name 有: + +- aiocqhttp +- qqchan +- nakuru + +其中,aiocqhttp 的稳定性最高,qqchan 和 nakuru 为实验性支持。 + +然后通过平台实例 `platform_instance` 的 send_msg 方法发送消息。send_msg 方法接收两个参数:`target` 和 `message`。`target` 为目标,`message` 为 `CommandResult` 对象。 + +## aiocqhttp + +`target` 接收一个 dict 类型的值引用。 + +- 要发给 QQ 下的某个用户,请添加 key `user_id`,值为 int 类型的 qq 号; +- 要发给某个群聊,请添加 key `group_id`,值为 int 类型的 qq 群号; + +## nakuru + +`target` 接收一个 dict 类型的值引用。 + +- 要发给 QQ 下的某个用户,请添加 key `user_id`,值为 int 类型的 qq 号; +- 要发给某个群聊,请添加 key `group_id`,值为 int 类型的 qq 群号; +- 要发给某个频道,请添加 key `guild_id`, `channel_id`。均为 int 类型。 + +guild_id 不是频道号。 + + +## qqchan + +`target` 接收一个 dict 类型的值引用。 + +- 如果目标是 QQ 群,请添加 key `group_openid`。 +- 如果目标是 频道消息,请添加 key `channel_id`。 +- 如果目标是 频道私聊,请添加 key `guild_id`。 + + +一个简单的示例: + +```py +import threading +from util.plugin_dev.api.v1.bot import Context, AstrMessageEvent, CommandResult +from util.plugin_dev.api.v1.config import * + +class HelloWorldPlugin: + """ + AstrBot 会传递 context 给插件。 + + - context.register_commands: 注册指令 + - context.register_task: 注册任务 + - context.message_handler: 消息处理器(平台类插件用) + """ + def __init__(self, context: Context) -> None: + self.context = context + self.context.register_commands("helloworld", "helloworld", "内置测试指令。", 1, self.helloworld) + + async def helloworld(self, message: AstrMessageEvent, context: Context): + await self.send_msg() + + async def send_msg(self): + platforms = self.context.platforms + platfrom = None + for p in platforms: + if p.platform_name == 'aiocqhttp': + platfrom = p + break + if platfrom: + inst = message.platform.platform_instance + await inst.send_msg({"user_id": 123456}, "Hello, World!") +``` + +一般来说,需要用到主动发送消息的场景一般是后台长任务。这时候,你可以使用 `context.register_task` 注册一个任务。 + +在下面的例子中,将演示一个每隔 5 秒发送一次消息的任务。 + +```py +import asyncio +from util.plugin_dev.api.v1.bot import Context, AstrMessageEvent, CommandResult +from util.plugin_dev.api.v1.config import * +from util.plugin_dev.api.v1.platform import * + +class HelloWorldPlugin: + def __init__(self, context: Context) -> None: + self.context = context + self.context.register_task(self.send_msg_per_minute(), "send_msg_per_minute") # 注册任务 + + async def send_msg_per_minute(self): + while True: + await asyncio.sleep(5) + for platform in self.context.platforms: # 遍历所有平台 + if platform.platform_name == 'aiocqhttp': # aiocqhttp + inst = platform.platform_instance # 获取平台实例 + await inst.send_msg({"user_id": 905617992}, CommandResult().message("你好")) # 发送消息给qq号为905617992的用户 + +``` +上面的例子使用了异步的方式来实现定时任务。当然可以使用 threading.Thread 来实现,不过不推荐。 + +# Context + +插件处理函数的参数之一。 + +它是一个上下文对象,包含了 AstrBot 实例中的一些共享数据。 + +在插件类的 `__init__` 方法中,你可以通过 `context` 参数获取到这个对象。 + +## 注册异步任务 + +如果你需要接入一个其他的平台,或者需要定时任务等,除了直接使用 threading.Thread 之外,你还可以使用 context.register_task 注册一个任务。 + # AstrMessageEvent 插件处理函数的参数之一。 @@ -140,14 +265,5 @@ raw_message: object 原平台的消息类 timestamp: int # 消息时间戳 ``` -# Context - -插件处理函数的参数之一。 - -它是一个上下文对象,包含了 AstrBot 实例中的一些共享数据。 - -## 注册异步任务 - -如果你需要接入一个其他的平台,或者需要定时任务等,除了直接使用 threading.Thread 之外,你还可以使用 context.register_task 注册一个任务。 🚧 施工中 🚧