From 9de56d8166ff02dcfc894eec21b66ead050141e5 Mon Sep 17 00:00:00 2001 From: KimigaiiWuyi <444835641@qq.com> Date: Wed, 8 Nov 2023 04:15:58 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E5=90=91core=E4=BC=A0=E9=80=92`sen?= =?UTF-8?q?der`=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GenshinUID/__init__.py | 58 +++++++++++++- GenshinUID/client.py | 178 +++++++++++++++++++++++++++++++++++++++-- GenshinUID/models.py | 3 +- GenshinUID/utils.py | 7 ++ 4 files changed, 236 insertions(+), 10 deletions(-) create mode 100644 GenshinUID/utils.py diff --git a/GenshinUID/__init__.py b/GenshinUID/__init__.py index 59795694..22985bae 100644 --- a/GenshinUID/__init__.py +++ b/GenshinUID/__init__.py @@ -145,20 +145,26 @@ async def get_all_message(bot: Bot, ev: Event): user_type = 'direct' group_id = str(ev.guild_id) msg_id = ev.id + sender = ev.author.dict() + sender['nickname'] = ev.author.username elif isinstance(ev, GroupAtMessageCreateEvent): sp_bot_id = 'qqgroup' user_type = 'group' group_id = str(ev.group_id) msg_id = ev.id + sender = ev.author.dict() elif isinstance(ev, C2CMessageCreateEvent): sp_bot_id = 'qqgroup' user_type = 'direct' group_id = None msg_id = ev.id + sender = ev.author.dict() # 群聊 elif isinstance(ev, GuildMessageEvent): user_type = 'group' group_id = str(ev.channel_id) + sender = ev.author.dict() + sender['nickname'] = ev.author.username if ev.member and ev.member.roles: if 4 in ev.member.roles: pm = 2 @@ -192,6 +198,7 @@ async def get_all_message(bot: Bot, ev: Event): user_id = str(ev.from_.id) msg_id = str(ev.message_id) + sender = ev.from_.dict() if isinstance(ev, GroupMessageEvent): user_type = 'group' group_id = str(ev.chat.id) @@ -215,6 +222,14 @@ async def get_all_message(bot: Bot, ev: Event): user_id = ev.author_id msg_id = ev.msg_id + sender = ev.event.author.dict() + sender.update( + { + 'name': ev.event.author.username, + 'nickname': ev.event.author.nickname, + 'avatar': ev.event.author.avatar, + } + ) if isinstance(ev, ChannelMessageEvent): user_type = 'group' group_id = ev.target_id @@ -240,6 +255,9 @@ async def get_all_message(bot: Bot, ev: Event): elif ev.sender.role == 'admin': pm = 3 + sender = ev.sender.dict(exclude_none=True) + sender['avatar'] = f'http://q1.qlogo.cn/g?b=qq&nk={user_id}&s=640' + if isinstance(ev, GroupMessageEvent): user_type = 'group' group_id = str(ev.group_id) @@ -262,6 +280,7 @@ async def get_all_message(bot: Bot, ev: Event): feishu_msg.data['url'] = feishu_msg.data['image_key'] user_id = ev.get_user_id() msg_id = ev.message_id + sender = {} if isinstance(ev, GroupEventMessage): user_type = 'group' group_id = ev.chat_id @@ -281,8 +300,12 @@ async def get_all_message(bot: Bot, ev: Event): if isinstance(ev, GroupMessageEvent) or isinstance( ev, PrivateMessageEvent ): - user_id = ev.get_user_id() msg_id = ev.msgId + sender = { + 'name': ev.sendMemberName, + 'nickname': ev.sendNickName, + 'avatar': f'http://q1.qlogo.cn/g?b=qq&nk={user_id}&s=640', + } if isinstance(ev, GroupMessageEvent): user_type = 'group' group_id = str(ev.peerUid) @@ -298,6 +321,7 @@ async def get_all_message(bot: Bot, ev: Event): TextMessageEvent, ) + sender = {} if isinstance(ev, TextMessageEvent): user_id = ev.from_wxid msg_id = ev.msgid @@ -348,7 +372,7 @@ async def get_all_message(bot: Bot, ev: Event): # self = raw_data['self'] # 返回 platform='xxx' user_id='wxid_xxxxx' # platform = self.platform # 机器人平台 # V12还支持频道等其他平台,速速Pr! - + sender = {} if isinstance(ev, GroupMessageEvent) or isinstance( ev, PrivateMessageEvent ): @@ -374,6 +398,35 @@ async def get_all_message(bot: Bot, ev: Event): else: logger.debug('[gsuid] 不支持该 onebotv12 事件...') return + elif bot.adapter.get_name() == 'Villa': + from nonebot.adapters.villa import SendMessageEvent + + sender = {} + if isinstance(ev, SendMessageEvent): + user_type = 'group' + msg_id = ev.msg_uid + group_id = f'{ev.villa_id}-{ev.room_id}' + else: + logger.debug('[gsuid] 不支持该 Villa 事件...') + return + elif bot.adapter.get_name() == 'Discord': + from nonebot.adapters.discord import ( + GuildMessageCreateEvent, + DirectMessageCreateEvent, + ) + + sender = {} + if isinstance(ev, GuildMessageCreateEvent): + user_type = 'group' + msg_id = str(ev.message_id) + group_id = str(int(ev.channel_id)) + elif isinstance(ev, DirectMessageCreateEvent): + msg_id = str(ev.message_id) + user_type = 'direct' + else: + logger.debug('[gsuid] 不支持该 Discord 事件...') + return + else: logger.debug(f'[gsuid] 不支持该 {bot.adapter.get_name()} 事件...') return @@ -404,6 +457,7 @@ async def get_all_message(bot: Bot, ev: Event): user_type=user_type, group_id=group_id, user_id=user_id, + sender=sender, content=message, msg_id=msg_id if msg_id else '', user_pm=pm, diff --git a/GenshinUID/client.py b/GenshinUID/client.py index 94f95922..85cc6bf4 100644 --- a/GenshinUID/client.py +++ b/GenshinUID/client.py @@ -14,6 +14,7 @@ from msgspec import json as msgjson from nonebot import get_bot, get_bots, get_driver from websockets.exceptions import ConnectionClosedError +from .utils import download_image from .models import MessageSend, MessageReceive bots: Dict[str, str] = {} @@ -246,6 +247,18 @@ class GsClient: msg.target_type, msg.msg_id, ) + elif msg.bot_id == 'villa': + await villa_send( + bot, + content, + image, + node, + at_list, + markdown, + buttons, + msg.target_id, + msg.target_type, + ) elif msg.bot_id == 'feishu': await feishu_send( bot, @@ -310,6 +323,77 @@ def del_file(path: Path): os.remove(path) +async def villa_send( + bot: Bot, + content: Optional[str], + image: Optional[str], + node: Optional[List[Dict]], + at_list: Optional[List[str]], + markdown: Optional[str], + buttons: Optional[Union[List[Dict], List[List[Dict]]]], + target_id: Optional[str], + target_type: Optional[str], +): + from nonebot.adapters.villa import Bot, Message, MessageSegment + from nonebot.adapters.villa.api import ( + PostMessageContent, + ImageMessageContent, + ) + + assert isinstance(bot, Bot) + + async def _send(content: Optional[str], image: Optional[str]): + if target_type == 'group' and target_id: + msg = Message() + villa_id, room_id = target_id.split('-') + + if image: + msg += MessageSegment.image(image) + if content: + msg += MessageSegment.text(content) + + if at_list and target_type == 'group': + for at in at_list: + msg += MessageSegment.mention_user( + int(at), villa_id=int(villa_id) + ) + + if markdown: + logger.warning('[gscore] villa暂不支持发送markdown消息') + if buttons: + logger.warning('[gscore] villa暂不支持发送buttons消息') + + content_info = await bot.parse_message_content(msg) + + if isinstance(content_info.content, PostMessageContent): + object_name = "MHY:Post" + elif isinstance(content_info.content, ImageMessageContent): + object_name = "MHY:Image" + else: + object_name = "MHY:Text" + + await bot.send_message( + villa_id=int(villa_id), + room_id=int(room_id), + object_name=object_name, + msg_content=content_info.json( + by_alias=True, exclude_none=True + ), + ) + + if node: + for _msg in node: + if _msg['type'] == 'image': + image = _msg['data'] + content = None + else: + image = None + content = _msg['data'] + await _send(content, image) + else: + await _send(content, image) + + async def onebot_send( bot: Bot, content: Optional[str], @@ -323,7 +407,9 @@ async def onebot_send( async def _send(content: Optional[str], image: Optional[str]): from nonebot.adapters.onebot.v11 import MessageSegment - result_image = MessageSegment.image(image) if image else '' + result_image = ( + MessageSegment.image(image.replace('link://', '')) if image else '' + ) _content = MessageSegment.text(content) if content else '' result_msg = _content + result_image if at_list and target_type == 'group': @@ -415,7 +501,10 @@ async def onebot_red_send( async def _send(content: Optional[str], image: Optional[str]): result_msg: Message = Message() if image: - img_bytes = base64.b64decode(image.replace('base64://', '')) + if image.startswith('link://'): + img_bytes = await download_image(image.replace('link://', '')) + else: + img_bytes = base64.b64decode(image.replace('base64://', '')) result_msg.append(MessageSegment.image(img_bytes)) if content: @@ -450,6 +539,64 @@ async def onebot_red_send( await _send(content, image) +async def discord_send( + bot: Bot, + content: Optional[str], + image: Optional[str], + node: Optional[List[Dict]], + at_list: Optional[List[str]], + markdown: Optional[str], + buttons: Optional[Union[List[Dict], List[List[Dict]]]], + target_id: Optional[str], + target_type: Optional[str], +): + from nonebot.adapters.discord.message import parse_message + from nonebot.adapters.discord import Bot, Message, MessageSegment + + assert isinstance(bot, Bot) + + async def _send(content: Optional[str], image: Optional[str]): + if target_id: + message = Message() + if image: + img_bytes = base64.b64decode(image.replace('base64://', '')) + message.append( + MessageSegment.attachment('temp.jpg', content=img_bytes) + ) + if content: + message.append(MessageSegment.text(content)) + + if at_list and target_type == 'group': + for at in at_list: + message.append(MessageSegment.mention_user(int(at))) + + if markdown: + logger.warning('[gscore] discord暂不支持发送markdown消息') + if buttons: + logger.warning('[gscore] discord暂不支持发送markdown消息') + + message_data = parse_message(message) + await bot.create_message( + channel_id=int(target_id), + nonce=None, + tts=False, + allowed_mentions=None, + **message_data, + ) + + if node: + for _msg in node: + if _msg['type'] == 'image': + image = _msg['data'] + content = None + else: + image = None + content = _msg['data'] + await _send(content, image) + else: + await _send(content, image) + + async def guild_send( bot: Bot, content: Optional[str], @@ -584,6 +731,8 @@ async def group_send( message = Message() if image: _image = image.replace('link://', '') + else: + _image = '' if content and image: data = f'{content}\n{_image}' @@ -682,12 +831,20 @@ async def kaiheila_send( target_id: Optional[str], target_type: Optional[str], ): + from nonebot.adapters.kaiheila import Bot + + assert isinstance(bot, Bot) + async def _send(content: Optional[str], image: Optional[str]): result = {} result['type'] = 1 if image: - img_bytes = base64.b64decode(image.replace('base64://', '')) - url = await bot.upload_file(img_bytes, 'GSUID-TEMP') # type:ignore + if image.startswith('link://'): + img_bytes = await download_image(image.replace('link://', '')) + else: + img_bytes = base64.b64decode(image.replace('base64://', '')) + + url = await bot.upload_file(img_bytes, 'GSUID-TEMP') result['type'] = 2 result['content'] = url elif file: @@ -696,7 +853,7 @@ async def kaiheila_send( store_file(path, file_content) with open(path, 'rb') as f: doc = f.read() - url = await bot.upload_file(doc, file_name) # type:ignore + url = await bot.upload_file(doc, file_name) result['content'] = url del_file(path) else: @@ -731,7 +888,10 @@ async def telegram_send( async def _send(content: Optional[str], image: Optional[str]): result = {} if image: - img_bytes = base64.b64decode(image.replace('base64://', '')) + if image.startswith('link://'): + img_bytes = await download_image(image.replace('link://', '')) + else: + img_bytes = base64.b64decode(image.replace('base64://', '')) result['photo'] = img_bytes if content: result['text'] = content @@ -805,8 +965,12 @@ async def feishu_send( msg = {'text': content} _type = 'text' elif image: + if image.startswith('link://'): + img_bytes = await download_image(image.replace('link://', '')) + else: + img_bytes = base64.b64decode(image.replace('base64://', '')) data = {"image_type": "message"} - files = {"image": base64.b64decode(image.replace('base64://', ''))} + files = {"image": img_bytes} params = { "method": "POST", "data": data, diff --git a/GenshinUID/models.py b/GenshinUID/models.py index 2c037d45..e85873b8 100644 --- a/GenshinUID/models.py +++ b/GenshinUID/models.py @@ -1,4 +1,4 @@ -from typing import Any, List, Literal, Optional +from typing import Any, Dict, List, Literal, Optional from msgspec import Struct @@ -15,6 +15,7 @@ class MessageReceive(Struct): user_type: Literal['group', 'direct', 'channel', 'sub_channel'] = 'group' group_id: Optional[str] = None user_id: Optional[str] = None + sender: Dict[str, Any] = {} user_pm: int = 3 content: List[Message] = [] diff --git a/GenshinUID/utils.py b/GenshinUID/utils.py new file mode 100644 index 00000000..0d996f04 --- /dev/null +++ b/GenshinUID/utils.py @@ -0,0 +1,7 @@ +import aiohttp + + +async def download_image(url: str): + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + return await response.read()