Compare commits

...

4 Commits

Author SHA1 Message Date
Soulter 344f92e0e7 perf: 将内部基本消息对象统一为 AstrBotMessage
feat: 支持官方qq接口的Q群消息
2024-03-14 13:56:32 +08:00
Soulter fdabfef6a7 update: version 2024-03-13 21:28:18 +08:00
Soulter 6c5718f134 fix: 修复画图的报错 2024-03-13 21:27:48 +08:00
Soulter edfde51434 fix: 修复频道平台下未找到平台 qqchan 的实例的错误 2024-03-13 19:53:36 +08:00
9 changed files with 286 additions and 165 deletions
+1 -1
View File
@@ -8,5 +8,5 @@ configs/config.yaml
temp
cmd_config.json
addons/plugins/
data/
data/*
cookies.json
+4 -5
View File
@@ -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.7'
version = '3.1.10'
# 语言模型
REV_CHATGPT = 'rev_chatgpt'
@@ -244,7 +243,7 @@ def run_qqchan_bot(cfg: dict, global_object: GlobalObject):
try:
from model.platform.qq_official import QQOfficial
qqchannel_bot = QQOfficial(cfg=cfg, message_handler=oper_msg, global_object=global_object)
global_object.platforms.append(RegisteredPlatform(platform_name="qq_official", platform_instance=qqchannel_bot, origin="internal"))
global_object.platforms.append(RegisteredPlatform(platform_name="qqchan", platform_instance=qqchannel_bot, origin="internal"))
qqchannel_bot.run()
except BaseException as e:
logger.log("启动QQ频道机器人时出现错误, 原因如下: " + str(e), gu.LEVEL_CRITICAL, tag="QQ频道")
@@ -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}次。')
# 检查是否是更换语言模型的请求
+31 -3
View File
@@ -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,
+3 -3
View File
@@ -49,7 +49,7 @@ class CommandOpenAIOfficial(Command):
elif self.command_start_with(message, "update"):
return True, self.update(message, role)
elif self.command_start_with(message, "", "draw"):
return True, self.draw(message)
return True, await self.draw(message)
elif self.command_start_with(message, "key"):
return True, self.key(message)
elif self.command_start_with(message, "switch"):
@@ -256,7 +256,7 @@ class CommandOpenAIOfficial(Command):
self.personality_str = message
return True, f"自定义人格已设置。 \n人格信息: {ps}", "set"
def draw(self, message):
async def draw(self, message):
if self.provider is None:
return False, "未启用 OpenAI 官方 API", "draw"
if message.startswith("/画"):
@@ -265,7 +265,7 @@ class CommandOpenAIOfficial(Command):
message = message[1:]
try:
# 画图模式传回3个参数
img_url = self.provider.image_chat(message)
img_url = await self.provider.image_chat(message)
return True, img_url, "draw"
except Exception as e:
if 'exceeded' in str(e):
+104
View File
@@ -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
@@ -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
-3
View File
@@ -5,9 +5,6 @@ from nakuru import (
GroupMessage,
FriendMessage,
)
from ._nakuru_translation_layer import (
NakuruGuildMessage,
)
from nakuru.entities.components import Plain, At, Image
+38 -24
View File
@@ -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群号。第二个参数是消息内容(消息内容可以是消息链列表,也可以是纯文字信息)。
+105 -49
View File
@@ -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_textimage_pathmsg_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)()