diff --git a/model/platform/qq_aiocqhttp.py b/model/platform/qq_aiocqhttp.py index 84ffcf4f3..7bb1c4937 100644 --- a/model/platform/qq_aiocqhttp.py +++ b/model/platform/qq_aiocqhttp.py @@ -2,6 +2,7 @@ import time import traceback import logging from aiocqhttp import CQHttp, Event +from aiocqhttp.exceptions import ActionFailed from . import Platform from type.astrbot_message import * from type.message_event import * @@ -164,13 +165,29 @@ class AIOCQHTTP(Platform): message_chain = [Plain(text=message_chain), ] ret = [] - for segment in message_chain: + image_idx = [] + for idx, segment in enumerate(message_chain): d = segment.toDict() if isinstance(segment, Plain): d['type'] = 'text' if isinstance(segment, Image): - # d['data']['file'] = - pass + image_idx.append(idx) ret.append(d) - - await self.bot.send(message.raw_message, ret) \ No newline at end of file + try: + await self.bot.send(message.raw_message, ret) + except ActionFailed as e: + logger.error(traceback.format_exc()) + logger.error(f"回复消息失败: {e}") + if e.retcode == 1200: + # ENOENT + if not image_idx: + raise e + logger.info("检测到失败原因为文件未找到,猜测用户的协议端与 AstrBot 位于不同的文件系统上。尝试采用上传图片的方式发图。") + for idx in image_idx: + if ret[idx]['data']['file'].startswith('file://'): + logger.info(f"正在上传图片: {ret[idx]['data']['path']}") + image_url = await self.context.image_uploader.upload_image(ret[idx]['data']['path']) + logger.info(f"上传成功。") + ret[idx]['data']['file'] = image_url + ret[idx]['data']['path'] = image_url + await self.bot.send(message.raw_message, ret) \ No newline at end of file diff --git a/model/plugin/manager.py b/model/plugin/manager.py index 11d33a048..72841059d 100644 --- a/model/plugin/manager.py +++ b/model/plugin/manager.py @@ -165,7 +165,7 @@ class PluginManager(): try: # 尝试传入 ctx - obj = getattr(module, cls[0])(ctx=self.context) + obj = getattr(module, cls[0])(context=self.context) except: obj = getattr(module, cls[0])() diff --git a/type/command.py b/type/command.py index f09a0a00e..5411c2991 100644 --- a/type/command.py +++ b/type/command.py @@ -1,6 +1,6 @@ from typing import Union, List, Callable from dataclasses import dataclass -from nakuru.entities.components import Plain +from nakuru.entities.components import Plain, Image @dataclass @@ -26,8 +26,41 @@ class CommandResult(): self.command_name = command_name def message(self, message: str): + ''' + 快捷回复消息。 + + CommandResult().message("Hello, world!") + ''' self.message_chain = [Plain(message), ] return self + + def error(self, message: str): + ''' + 快捷回复消息。 + + CommandResult().error("Hello, world!") + ''' + self.success = False + self.message_chain = [Plain(message), ] + return self + + def url_image(self, url: str): + ''' + 快捷回复图片(网络url的格式)。 + + CommandResult().image("https://example.com/image.jpg") + ''' + self.message_chain = [Image.fromURL(url), ] + return self + + def file_image(self, path: str): + ''' + 快捷回复图片(本地文件路径的格式)。 + + CommandResult().image("image.jpg") + ''' + self.message_chain = [Image.fromFileSystem(path), ] + return self def _result_tuple(self): return (self.success, self.message_chain, self.command_name) diff --git a/type/types.py b/type/types.py index b3b63e45f..8773bfb48 100644 --- a/type/types.py +++ b/type/types.py @@ -51,7 +51,7 @@ class Context: `command_name`: 指令名,如 "help"。不需要带前缀。 `description`: 指令描述。 `priority`: 优先级越高,越先被处理。合理的优先级应该在 1-10 之间。 - `handler`: 指令处理函数。 + `handler`: 指令处理函数。函数参数:message: AstrMessageEvent, context: Context ''' self.plugin_command_bridge.register_command(plugin_name, command_name, description, priority, handler) diff --git a/util/plugin_dev/api/v1/types.py b/util/plugin_dev/api/v1/types.py index 96d07a775..eaaef76d5 100644 --- a/util/plugin_dev/api/v1/types.py +++ b/util/plugin_dev/api/v1/types.py @@ -1,5 +1,7 @@ ''' -插件类型 +插件类型、消息组件类型 ''' -from type.plugin import PluginType \ No newline at end of file +from type.plugin import PluginType + +from nakuru.entities.components import Image, Plain, At, Node, BaseMessageComponent \ No newline at end of file