From 344f92e0e72ec7e88a045f09a9bd99a20d903604 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Thu, 14 Mar 2024 13:56:32 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E5=B0=86=E5=86=85=E9=83=A8=E5=9F=BA?= =?UTF-8?q?=E6=9C=AC=E6=B6=88=E6=81=AF=E5=AF=B9=E8=B1=A1=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E4=B8=BA=20AstrBotMessage=20feat:=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=AE=98=E6=96=B9qq=E6=8E=A5=E5=8F=A3=E7=9A=84Q=E7=BE=A4?= =?UTF-8?q?=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- cores/qqbot/core.py | 7 +- cores/qqbot/types.py | 34 ++++- model/platform/_message_parse.py | 104 +++++++++++++ model/platform/_nakuru_translation_layer.py | 77 ---------- model/platform/_platfrom.py | 3 - model/platform/qq_gocq.py | 62 +++++--- model/platform/qq_official.py | 154 +++++++++++++------- 8 files changed, 282 insertions(+), 161 deletions(-) create mode 100644 model/platform/_message_parse.py delete mode 100644 model/platform/_nakuru_translation_layer.py diff --git a/.gitignore b/.gitignore index f7f601cca..33d25a74c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,5 @@ configs/config.yaml temp cmd_config.json addons/plugins/ -data/ +data/* cookies.json diff --git a/cores/qqbot/core.py b/cores/qqbot/core.py index 1eb97170c..68efc47c3 100644 --- a/cores/qqbot/core.py +++ b/cores/qqbot/core.py @@ -22,7 +22,6 @@ from nakuru import ( from nakuru.entities.components import Plain, At, Image from addons.baidu_aip_judge import BaiduJudge -from model.platform._nakuru_translation_layer import NakuruGuildMessage from model.provider.provider import Provider from model.command.command import Command from util import general_utils as gu @@ -44,7 +43,7 @@ frequency_time = 60 frequency_count = 10 # 版本 -version = '3.1.9' +version = '3.1.10' # 语言模型 REV_CHATGPT = 'rev_chatgpt' @@ -307,7 +306,7 @@ async def record_message(platform: str, session_id: str): db_inst.increment_stat_platform(curr_ts, platform, 1) _global_object.cnt_total += 1 -async def oper_msg(message: Union[GroupMessage, FriendMessage, GuildMessage, NakuruGuildMessage], +async def oper_msg(message: AstrBotMessage, session_id: str, role: str = 'member', platform: str = None, @@ -346,7 +345,7 @@ async def oper_msg(message: Union[GroupMessage, FriendMessage, GuildMessage, Nak return MessageResult("Hi~") # 检查发言频率 - if not check_frequency(message.user_id): + if not check_frequency(message.sender.user_id): return MessageResult(f'你的发言超过频率限制(╯▔皿▔)╯。\n管理员设置{frequency_time}秒内只能提问{frequency_count}次。') # 检查是否是更换语言模型的请求 diff --git a/cores/qqbot/types.py b/cores/qqbot/types.py index 32ec0a6f8..8e4e080f4 100644 --- a/cores/qqbot/types.py +++ b/cores/qqbot/types.py @@ -1,4 +1,3 @@ -from model.platform.qq_official import NakuruGuildMessage from model.provider.provider import Provider as LLMProvider from model.platform._platfrom import Platform from nakuru import ( @@ -6,11 +5,40 @@ from nakuru import ( FriendMessage, GuildMessage, ) +from nakuru.entities.components import BaseMessageComponent from typing import Union, List, ClassVar from types import ModuleType from enum import Enum from dataclasses import dataclass +class MessageType(Enum): + GROUP_MESSAGE = 'GroupMessage' # 群组形式的消息 + FRIEND_MESSAGE = 'FriendMessage' # 私聊、好友等单聊消息 + GUILD_MESSAGE = 'GuildMessage' # 频道消息 + +@dataclass +class MessageMember(): + user_id: str # 发送者id + nickname: str = None + +class AstrBotMessage(): + ''' + AstrBot 的消息对象 + ''' + tag: str # 消息来源标签 + type: MessageType # 消息类型 + self_id: str # 机器人的识别id + session_id: str # 会话id + message_id: str # 消息id + sender: MessageMember # 发送者 + message: List[BaseMessageComponent] # 消息链使用 Nakuru 的消息链格式 + message_str: str # 最直观的纯文本消息字符串 + raw_message: object + timestamp: int # 消息时间戳 + + def __str__(self) -> str: + return str(self.__dict__) + class PluginType(Enum): PLATFORM = 'platfrom' # 平台类插件。 LLM = 'llm' # 大语言模型类插件 @@ -107,14 +135,14 @@ class AstrMessageEvent(): ''' context: GlobalObject # 一些公用数据 message_str: str # 纯消息字符串 - message_obj: Union[GroupMessage, FriendMessage, GuildMessage, NakuruGuildMessage] # 消息对象 + message_obj: AstrBotMessage # 消息对象 platform: RegisteredPlatform # 来源平台 role: str # 基本身份。`admin` 或 `member` session_id: int # 会话 id def __init__(self, message_str: str, - message_obj: Union[GroupMessage, FriendMessage, GuildMessage, NakuruGuildMessage], + message_obj: AstrBotMessage, platform: RegisteredPlatform, role: str, context: GlobalObject, diff --git a/model/platform/_message_parse.py b/model/platform/_message_parse.py new file mode 100644 index 000000000..7358be2a8 --- /dev/null +++ b/model/platform/_message_parse.py @@ -0,0 +1,104 @@ +from nakuru.entities.components import Plain, At, Image, BaseMessageComponent +from nakuru import ( + GuildMessage, + GroupMessage, + FriendMessage +) +import botpy.message +from cores.qqbot.types import MessageType, AstrBotMessage, MessageMember +from typing import List, Union +import time + +# QQ官方消息类型转换 +def qq_official_message_parse(message: List[BaseMessageComponent]): + plain_text = "" + image_path = None # only one img supported + for i in message: + if isinstance(i, Plain): + plain_text += i.text + elif isinstance(i, Image) and image_path == None: + if i.path is not None: + image_path = i.path + else: + image_path = i.file + return plain_text, image_path + +# QQ官方消息类型 2 AstrBotMessage +def qq_official_message_parse_rev(message: Union[botpy.message.Message, botpy.message.GroupMessage], + message_type: MessageType) -> AstrBotMessage: + abm = AstrBotMessage() + abm.type = message_type + abm.timestamp = int(time.time()) + abm.raw_message = message + abm.message_id = message.id + abm.tag = "qqchan" + msg: List[BaseMessageComponent] = [] + + if message_type == MessageType.GROUP_MESSAGE: + abm.sender = MessageMember( + message.author.member_openid, + "" + ) + abm.message_str = message.content.strip() + abm.self_id = "unknown_selfid" + + msg.append(Plain(abm.message_str)) + if message.attachments: + for i in message.attachments: + if i.content_type.startswith("image"): + url = i.url + if not url.startswith("http"): + url = "https://"+url + img = Image.fromURL(url) + msg.append(img) + abm.message = msg + + elif message_type == MessageType.GUILD_MESSAGE or message_type == MessageType.FRIEND_MESSAGE: + # 目前对于 FRIEND_MESSAGE 只处理频道私聊 + try: + abm.self_id = str(message.mentions[0].id) + except: + abm.self_id = "" + + plain_content = message.content.replace("<@!"+str(abm.self_id)+">", "").strip() + msg.append(Plain(plain_content)) + if message.attachments: + for i in message.attachments: + if i.content_type.startswith("image"): + url = i.url + if not url.startswith("http"): + url = "https://"+url + img = Image.fromURL(url) + msg.append(img) + abm.message = msg + abm.message_str = plain_content + abm.sender = MessageMember( + str(message.author.id), + str(message.author.username) + ) + else: + raise ValueError(f"Unknown message type: {message_type}") + return abm + +def nakuru_message_parse_rev(message: Union[GuildMessage, GroupMessage, FriendMessage]) -> AstrBotMessage: + abm = AstrBotMessage() + abm.type = MessageType(message.type) + abm.timestamp = int(time.time()) + abm.raw_message = message + abm.message_id = message.message_id + + plain_content = "" + for i in message.message: + if isinstance(i, Plain): + plain_content += i.text + abm.message_str = plain_content + + abm.self_id = str(message.self_id) + abm.sender = MessageMember( + str(message.sender.user_id), + str(message.sender.nickname) + ) + abm.tag = "gocq" + abm.message = message.message + + return abm \ No newline at end of file diff --git a/model/platform/_nakuru_translation_layer.py b/model/platform/_nakuru_translation_layer.py deleted file mode 100644 index 5c1f7068e..000000000 --- a/model/platform/_nakuru_translation_layer.py +++ /dev/null @@ -1,77 +0,0 @@ -from nakuru.entities.components import Plain, At, Image -from botpy.message import Message, DirectMessage - -class NakuruGuildMember(): - tiny_id: int # 发送者识别号 - user_id: int # 发送者识别号 - title: str - nickname: str # 昵称 - role: int # 角色 - icon_url: str # 头像url - -class NakuruGuildMessage(): - type: str = "GuildMessage" - self_id: int # bot的qq号 - self_tiny_id: int # bot的qq号 - sub_type: str # 消息类型 - message_id: str # 消息id - guild_id: int # 频道号 - channel_id: int # 子频道号 - user_id: int # 发送者qq号 - message: list # 消息内容 - sender: NakuruGuildMember # 发送者信息 - raw_message: Message - - def __str__(self) -> str: - return str(self.__dict__) - -# gocq-频道SDK兼容层(发) -def gocq_compatible_send(gocq_message_chain: list): - plain_text = "" - image_path = None # only one img supported - for i in gocq_message_chain: - if isinstance(i, Plain): - plain_text += i.text - elif isinstance(i, Image) and image_path == None: - if i.path is not None: - image_path = i.path - else: - image_path = i.file - return plain_text, image_path - -# gocq-频道SDK兼容层(收) -def gocq_compatible_receive(message: Message) -> NakuruGuildMessage: - ngm = NakuruGuildMessage() - try: - ngm.self_id = message.mentions[0].id - ngm.self_tiny_id = message.mentions[0].id - except: - ngm.self_id = 0 - ngm.self_tiny_id = 0 - - ngm.sub_type = "normal" - ngm.message_id = message.id - ngm.guild_id = int(message.guild_id) - ngm.channel_id = int(message.channel_id) - ngm.user_id = int(message.author.id) - msg = [] - plain_content = message.content.replace("<@!"+str(ngm.self_id)+">", "").strip() - msg.append(Plain(plain_content)) - if message.attachments: - for i in message.attachments: - if i.content_type.startswith("image"): - url = i.url - if not url.startswith("http"): - url = "https://"+url - img = Image.fromURL(url) - msg.append(img) - ngm.message = msg - ngm.sender = NakuruGuildMember() - ngm.sender.tiny_id = int(message.author.id) - ngm.sender.user_id = int(message.author.id) - ngm.sender.title = "" - ngm.sender.nickname = message.author.username - ngm.sender.role = 0 - ngm.sender.icon_url = message.author.avatar - ngm.raw_message = message - return ngm diff --git a/model/platform/_platfrom.py b/model/platform/_platfrom.py index f3e1c027c..bf47937f3 100644 --- a/model/platform/_platfrom.py +++ b/model/platform/_platfrom.py @@ -5,9 +5,6 @@ from nakuru import ( GroupMessage, FriendMessage, ) -from ._nakuru_translation_layer import ( - NakuruGuildMessage, -) from nakuru.entities.components import Plain, At, Image diff --git a/model/platform/qq_gocq.py b/model/platform/qq_gocq.py index 6b13f3987..dc668dd7d 100644 --- a/model/platform/qq_gocq.py +++ b/model/platform/qq_gocq.py @@ -14,6 +14,8 @@ from typing import Union import time from ._platfrom import Platform +from ._message_parse import nakuru_message_parse_rev +from cores.qqbot.types import MessageType, AstrBotMessage, MessageMember class FakeSource: @@ -57,52 +59,58 @@ class QQGOCQ(Platform): @gocq_app.receiver("GroupMessage") async def _(app: CQHTTP, source: GroupMessage): if self.cc.get("gocq_react_group", True): + abm = nakuru_message_parse_rev(source) if isinstance(source.message[0], Plain): - await self.handle_msg(source, True) + await self.handle_msg(abm) elif isinstance(source.message[0], At): if source.message[0].qq == source.self_id: - await self.handle_msg(source, True) + await self.handle_msg(abm) else: return @gocq_app.receiver("FriendMessage") async def _(app: CQHTTP, source: FriendMessage): if self.cc.get("gocq_react_friend", True): + abm = nakuru_message_parse_rev(source) if isinstance(source.message[0], Plain): - await self.handle_msg(source, False) + await self.handle_msg(abm) else: return @gocq_app.receiver("GroupMemberIncrease") async def _(app: CQHTTP, source: GroupMemberIncrease): if self.cc.get("gocq_react_group_increase", True): - await app.sendGroupMessage(source.group_id, [ Plain(text = self.announcement) ]) - @gocq_app.receiver("Notify") - async def _(app: CQHTTP, source: Notify): - print(source) - if source.sub_type == "poke" and source.target_id == source.self_id: - await self.handle_msg(source, False) + # @gocq_app.receiver("Notify") + # async def _(app: CQHTTP, source: Notify): + # print(source) + # if source.sub_type == "poke" and source.target_id == source.self_id: + # await self.handle_msg(source) @gocq_app.receiver("GuildMessage") async def _(app: CQHTTP, source: GuildMessage): if self.cc.get("gocq_react_guild", True): + abm = nakuru_message_parse_rev(source) if isinstance(source.message[0], Plain): - await self.handle_msg(source, True) + await self.handle_msg(abm) elif isinstance(source.message[0], At): if source.message[0].qq == source.self_tiny_id: - await self.handle_msg(source, True) + await self.handle_msg(abm) else: return def run(self): self.client.run() - async def handle_msg(self, message: Union[GroupMessage, FriendMessage, GuildMessage, Notify], is_group: bool): - self.logger.log(f"{message.user_id} -> {self.parse_message_outline(message)}", tag="QQ_GOCQ") + async def handle_msg(self, message: AstrBotMessage): + self.logger.log(f"{message.sender.nickname}/{message.sender.user_id} -> {self.parse_message_outline(message)}", tag="QQ_GOCQ") + + assert isinstance(message.raw_message, (GroupMessage, FriendMessage, GuildMessage)) + is_group = message.type != MessageType.FRIEND_MESSAGE + # 判断是否响应消息 resp = False if not is_group: @@ -111,7 +119,7 @@ class QQGOCQ(Platform): for i in message.message: if isinstance(i, At): if message.type == "GuildMessage": - if i.qq == message.user_id or i.qq == message.self_tiny_id: + if i.qq == message.raw_message.user_id or i.qq == message.raw_message.self_tiny_id: resp = True if message.type == "FriendMessage": if i.qq == message.self_id: @@ -129,16 +137,18 @@ class QQGOCQ(Platform): # 解析 session_id if self.unique_session or not is_group: - session_id = message.user_id - elif message.type == "GroupMessage": - session_id = message.group_id - elif message.type == "GuildMessage": - session_id = message.channel_id + session_id = message.raw_message.user_id + elif message.type == MessageType.GROUP_MESSAGE: + session_id = message.raw_message.group_id + elif message.type == MessageType.GUILD_MESSAGE: + session_id = message.raw_message.channel_id else: - session_id = message.user_id + session_id = message.raw_message.user_id + + message.session_id = session_id # 解析 role - sender_id = str(message.user_id) + sender_id = str(message.raw_message.user_id) if sender_id == self.cc.get('admin_qq', '') or \ sender_id in self.cc.get('other_admins', []): role = 'admin' @@ -163,12 +173,16 @@ class QQGOCQ(Platform): self.waiting[session_id] = message async def reply_msg(self, - message: Union[GroupMessage, FriendMessage, GuildMessage, Notify], + message: Union[AstrBotMessage, GuildMessage, GroupMessage, FriendMessage], result_message: list): """ 插件开发者请使用send方法, 可以不用直接调用这个方法。 """ - source = message + if isinstance(message, AstrBotMessage): + source = message.raw_message + else: + source = message + res = result_message self.logger.log(f"{source.user_id} <- {self.parse_message_outline(res)}", tag="QQ_GOCQ") @@ -233,7 +247,7 @@ class QQGOCQ(Platform): await self.client.sendGroupMessage(source.group_id, res) return - async def send_msg(self, message: Union[GroupMessage, FriendMessage, GuildMessage, Notify], result_message: list): + async def send_msg(self, message: Union[GroupMessage, FriendMessage, GuildMessage, AstrBotMessage], result_message: list): ''' 提供给插件的发送QQ消息接口。 参数说明:第一个参数可以是消息对象,也可以是QQ群号。第二个参数是消息内容(消息内容可以是消息链列表,也可以是纯文字信息)。 diff --git a/model/platform/qq_official.py b/model/platform/qq_official.py index 5f1b1f2a7..bc417b42b 100644 --- a/model/platform/qq_official.py +++ b/model/platform/qq_official.py @@ -1,7 +1,7 @@ import io import botpy from PIL import Image as PILImage -from botpy.message import Message, DirectMessage +import botpy.message import re import asyncio import aiohttp @@ -11,29 +11,34 @@ from botpy.types.message import Reference from botpy import Client import time from ._platfrom import Platform -from ._nakuru_translation_layer import( - NakuruGuildMessage, - gocq_compatible_receive, - gocq_compatible_send +from ._message_parse import( + qq_official_message_parse_rev, + qq_official_message_parse ) -from typing import Union +from cores.qqbot.types import MessageType, AstrBotMessage, MessageMember +from typing import Union, List +from nakuru.entities.components import BaseMessageComponent # QQ 机器人官方框架 class botClient(Client): def set_platform(self, platform: 'QQOfficial'): self.platform = platform + + async def on_group_at_message_create(self, message: botpy.message.GroupMessage): + abm = qq_official_message_parse_rev(message, MessageType.GROUP_MESSAGE) + await self.platform.handle_msg(abm) # 收到频道消息 - async def on_at_message_create(self, message: Message): + async def on_at_message_create(self, message: botpy.message.Message): # 转换层 - nakuru_guild_message = gocq_compatible_receive(message) - await self.platform.handle_msg(nakuru_guild_message, True) + abm = qq_official_message_parse_rev(message, MessageType.GUILD_MESSAGE) + await self.platform.handle_msg(abm) # 收到私聊消息 - async def on_direct_message_create(self, message: DirectMessage): + async def on_direct_message_create(self, message: botpy.message.DirectMessage): # 转换层 - nakuru_guild_message = gocq_compatible_receive(message) - await self.platform.handle_msg(nakuru_guild_message, False) + abm = qq_official_message_parse_rev(message, MessageType.FRIEND_MESSAGE) + await self.platform.handle_msg(abm) class QQOfficial(Platform): @@ -51,15 +56,26 @@ class QQOfficial(Platform): self.secret = cfg['qqbot_secret'] self.unique_session = cfg['uniqueSessionMode'] self.logger: gu.Logger = global_object.logger - - self.intents = botpy.Intents( - public_guild_messages=True, - direct_message=cfg['direct_message_mode'] - ) - self.client = botClient( - intents=self.intents, - bot_log=False - ) + + try: + self.intents = botpy.Intents( + public_messages=True, + public_guild_messages=True, + direct_message=cfg['direct_message_mode'] + ) + self.client = botClient( + intents=self.intents, + bot_log=False + ) + except BaseException: + self.intents = botpy.Intents( + public_guild_messages=True, + direct_message=cfg['direct_message_mode'] + ) + self.client = botClient( + intents=self.intents, + bot_log=False + ) self.client.set_platform(self) def run(self): @@ -80,17 +96,27 @@ class QQOfficial(Platform): token=self.token ) - async def handle_msg(self, message: NakuruGuildMessage, is_group: bool): + async def handle_msg(self, message: AstrBotMessage): + assert isinstance(message.raw_message, (botpy.message.Message, botpy.message.GroupMessage, botpy.message.DirectMessage)) + is_group = message.type != MessageType.FRIEND_MESSAGE + _t = "/私聊" if not is_group else "" - self.logger.log(f"{message.sender.nickname}({message.sender.tiny_id}{_t}) -> {self.parse_message_outline(message)}", tag="QQ_OFFICIAL") + self.logger.log(f"{message.sender.nickname}({message.sender.user_id}{_t}) -> {self.parse_message_outline(message)}", tag="QQ_OFFICIAL") + # 解析出 session_id if self.unique_session or not is_group: session_id = message.sender.user_id else: - session_id = message.channel_id + if message.type == MessageType.GUILD_MESSAGE: + session_id = message.raw_message.channel_id + elif message.type == MessageType.GROUP_MESSAGE: + session_id = str(message.raw_message.group_openid) + else: + session_id = str(message.raw_message.author.id) + message.session_id = session_id # 解析出 role - sender_id = str(message.sender.tiny_id) + sender_id = message.sender.user_id if sender_id == self.cfg['admin_qqchan'] or \ sender_id in self.cfg['other_admins']: role = 'admin' @@ -107,7 +133,7 @@ class QQOfficial(Platform): if message_result is None: return - await self.reply_msg(is_group, message, message_result.result_message) + await self.reply_msg(message, message_result.result_message) if message_result.callback is not None: message_result.callback() @@ -116,20 +142,24 @@ class QQOfficial(Platform): self.waiting[session_id] = message async def reply_msg(self, - is_group: bool, - message: NakuruGuildMessage, + message: Union[botpy.message.Message, botpy.message.GroupMessage, botpy.message.DirectMessage, AstrBotMessage], res: Union[str, list]): ''' 回复频道消息 ''' - self.logger.log(f"{message.sender.nickname}({message.sender.tiny_id}) <- {self.parse_message_outline(res)}", tag="QQ_OFFICIAL") + if isinstance(message, AstrBotMessage): + source = message.raw_message + else: + source = message + assert isinstance(source, (botpy.message.Message, botpy.message.GroupMessage, botpy.message.DirectMessage)) + self.logger.log(f"{message.sender.nickname}({message.sender.user_id}) <- {self.parse_message_outline(res)}", tag="QQ_OFFICIAL") plain_text = '' image_path = '' msg_ref = None if isinstance(res, list): - plain_text, image_path = gocq_compatible_send(res) + plain_text, image_path = qq_official_message_parse(res) elif isinstance(res, str): plain_text = res @@ -154,8 +184,8 @@ class QQOfficial(Platform): image = PILImage.open(io.BytesIO(await response.read())) image_path = gu.save_temp_img(image) - if message.raw_message is not None and image_path == '': # file_image与message_reference不能同时传入 - msg_ref = Reference(message_id=message.raw_message.id, ignore_get_message_error=False) + if source is not None and image_path == '': # file_image与message_reference不能同时传入 + msg_ref = Reference(message_id=source.id, ignore_get_message_error=False) # 到这里,我们得到了 plain_text,image_path,msg_ref data = { @@ -163,10 +193,15 @@ class QQOfficial(Platform): 'msg_id': message.message_id, 'message_reference': msg_ref } - if is_group: - data['channel_id'] = str(message.channel_id) + if message.type == MessageType.GROUP_MESSAGE: + data['group_openid'] = str(source.group_openid) + elif message.type == MessageType.GUILD_MESSAGE: + data['channel_id'] = source.channel_id + elif message.type == MessageType.FRIEND_MESSAGE: + # 目前只处理频道私聊 + data['guild_id'] = source.guild_id else: - data['guild_id'] = str(message.guild_id) + raise ValueError(f"未知的消息类型: {message.type}") if image_path != '': data['file_image'] = image_path @@ -200,27 +235,48 @@ class QQOfficial(Platform): await self._send_wrapper(**data) async def _send_wrapper(self, **kwargs): - if 'channel_id' in kwargs: + if 'group_openid' in kwargs: + # QQ群组消息 + media = None + # qq群组消息需要自行上传,暂时不处理 + # if 'file_image' in kwargs: + # file_image_path = kwargs['file_image'] + # if file_image_path != "": + # media = await self.upload_img(file_image_path, kwargs['group_openid']) + # del kwargs['file_image'] + # if media is not None: + # kwargs['msg_type'] = 7 # 富媒体 + await self.client.api.post_group_message(media=media, **kwargs) + elif 'channel_id' in kwargs: + # 频道消息 + if 'file_image' in kwargs: + kwargs['file_image'] = kwargs['file_image'].replace("file://", "") await self.client.api.post_message(**kwargs) else: + # 频道私聊消息 + if 'file_image' in kwargs: + kwargs['file_image'] = kwargs['file_image'].replace("file://", "") await self.client.api.post_dms(**kwargs) - async def send_msg(self, channel_id: int, message_chain: list, message_id: int = None): + async def send_msg(self, + message_obj: Union[botpy.message.Message, botpy.message.GroupMessage, botpy.message.DirectMessage, AstrBotMessage], + message_chain: List[BaseMessageComponent], + ): ''' - 推送消息, 如果有 message_id,那么就是回复消息。 - ''' - _n = NakuruGuildMessage() - _n.channel_id = channel_id - _n.message_id = message_id - await self.reply_msg(_n, message_chain) - - async def send(self, message_obj, message_chain: list): - ''' - 发送信息。内容同 reply_msg。 + 发送消息。目前只支持被动回复消息(即拥有一个 botpy Message 类型的 message_obj 传入) ''' await self.reply_msg(message_obj, message_chain) - def wait_for_message(self, channel_id: int) -> NakuruGuildMessage: + async def send(self, + message_obj: Union[botpy.message.Message, botpy.message.GroupMessage, botpy.message.DirectMessage, AstrBotMessage], + message_chain: List[BaseMessageComponent], + ): + ''' + 发送消息。目前只支持被动回复消息(即拥有一个 botpy Message 类型的 message_obj 传入) + ''' + await self.reply_msg(message_obj, message_chain) + + def wait_for_message(self, channel_id: int) -> AstrBotMessage: ''' 等待指定 channel_id 的下一条信息,超时 300s 后抛出异常 ''' @@ -235,4 +291,4 @@ class QQOfficial(Platform): cnt += 1 if cnt > 300: raise Exception("等待消息超时。") - time.sleep(1) + time.sleep(1)()