Skip to content

Commit

Permalink
perf
Browse files Browse the repository at this point in the history
  • Loading branch information
Soulter committed Jul 27, 2024
1 parent b20a95e commit 501d40f
Showing 1 changed file with 125 additions and 9 deletions.
134 changes: 125 additions & 9 deletions docs/开发/插件开发.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

插件处理函数的参数之一。
Expand Down Expand Up @@ -140,14 +265,5 @@ raw_message: object 原平台的消息类
timestamp: int # 消息时间戳
```

# Context

插件处理函数的参数之一。

它是一个上下文对象,包含了 AstrBot 实例中的一些共享数据。

## 注册异步任务

如果你需要接入一个其他的平台,或者需要定时任务等,除了直接使用 threading.Thread 之外,你还可以使用 context.register_task 注册一个任务。

🚧 施工中 🚧

0 comments on commit 501d40f

Please sign in to comment.