兼容多种适配器、调整收发消息格式

This commit is contained in:
Wuyi无疑 2023-03-11 17:04:19 +08:00
parent 0da24584df
commit 0e3aee4315
4 changed files with 128 additions and 61 deletions

View File

@ -20,22 +20,55 @@ gsclient: Optional[GsClient] = None
@get_message.handle() @get_message.handle()
async def send_char_adv(ev: Event): async def send_char_adv(ev: Event):
if gsclient is None: if gsclient is None:
return await start_client() return await connect()
# 通用字段获取
sessions = ev.get_session_id().split('_') sessions = ev.get_session_id().split('_')
group_id = sessions[-2] if len(sessions) >= 2 else None
user_id = str(ev.get_user_id()) user_id = str(ev.get_user_id())
messages = ev.get_message() messages = ev.get_message()
bot_id = messages.__class__.__module__.split('.')[2] raw_data = ev.__dict__
group_id = sessions[-2] if len(sessions) >= 2 else None
message: List[Message] = [] message: List[Message] = []
# ntchat
if '_message' in raw_data:
messages = raw_data['_message']
group_id = str(raw_data['channel_id'])
# qqguild
elif not messages and 'message' in raw_data:
messages = raw_data['message']
# ntchat
elif 'data' in raw_data:
if 'chatroom' in raw_data['data']['to_wxid']:
group_id = raw_data['data']['to_wxid']
if 'image' in raw_data['data']:
message.append(Message('image', raw_data['data']['image']))
if 'from_wxid' in raw_data['data']:
user_id = raw_data['data']['from_wxid']
if 'at_user_list' in raw_data['data']:
_at_list = raw_data['data']['at_user_list']
at_list = [Message('at', i) for i in _at_list]
message.extend(at_list)
bot_id = messages.__class__.__module__.split('.')[2]
# 处理消息
for _msg in messages: for _msg in messages:
if _msg.type == 'text': if _msg.type == 'text':
message.append(Message('text', _msg.data['text'])) message.append(
Message(
'text',
_msg.data['text']
if 'text' in _msg.data
else _msg.data['content'],
)
)
elif _msg.type == 'image': elif _msg.type == 'image':
message.append(Message('image', _msg.data['url'])) message.append(Message('image', _msg.data['url']))
elif _msg.type == 'at': elif _msg.type == 'at':
message.append(Message('at', _msg.data['qq'])) message.append(Message('at', _msg.data['qq']))
if not message: if not message:
return return
msg = MessageReceive( msg = MessageReceive(
bot_id=bot_id, bot_id=bot_id,
user_type='group' if group_id else 'direct', user_type='group' if group_id else 'direct',
@ -62,6 +95,11 @@ async def send_start_msg(matcher: Matcher):
@driver.on_bot_connect @driver.on_bot_connect
async def start_client(): async def start_client():
await start()
await connect()
async def connect():
global gsclient global gsclient
try: try:
gsclient = await GsClient().async_connect() gsclient = await GsClient().async_connect()

View File

@ -2,6 +2,7 @@ import asyncio
import subprocess import subprocess
from git.repo import Repo from git.repo import Repo
from nonebot.log import logger
from pip._internal import main as pip_install from pip._internal import main as pip_install
from .path import CORE_PATH, GSUID_PATH from .path import CORE_PATH, GSUID_PATH
@ -28,10 +29,8 @@ async def _install():
async def install(): async def install():
done, _ = await asyncio.wait([_install()]) done = await asyncio.gather(_install())
for future in done: logger.info(done)
if future.result is None:
return '安装出现错误, 请查看控制台信息!'
return '安装成功...' return '安装成功...'

View File

@ -3,15 +3,29 @@ import asyncio
from typing import Dict, List, Union, Optional from typing import Dict, List, Union, Optional
import websockets.client import websockets.client
from nonebot import get_bot
from nonebot.log import logger from nonebot.log import logger
from nonebot.adapters import Bot from nonebot.adapters import Bot
from msgspec import json as msgjson from msgspec import json as msgjson
from nonebot import get_bot, get_bots
from websockets.exceptions import ConnectionClosedError from websockets.exceptions import ConnectionClosedError
from .models import MessageSend, MessageReceive from .models import MessageSend, MessageReceive
BOT_ID = 'NoneBot2' BOT_ID = 'NoneBot2'
bots: Dict[str, str] = {}
def _get_bot(bot_id: str) -> Bot:
if 'onebot' in bot_id:
bot_id = 'onebot'
if bot_id not in bots:
for _bot_id in bots.keys():
if bot_id in _bot_id:
bot_id = _bot_id
break
bot_real_id = bots[bot_id]
bot = get_bot(bot_real_id)
return bot
class GsClient: class GsClient:
@ -29,53 +43,69 @@ class GsClient:
async def recv_msg(self): async def recv_msg(self):
try: try:
bot = get_bot() global bots
_bots = get_bots()
for bot_real_id in _bots:
bot = _bots[bot_real_id]
bot_id = bot.type.lower().replace(' ', '')
bots[bot_id] = bot_real_id
async for message in self.ws: async for message in self.ws:
msg = msgjson.decode(message, type=MessageSend) try:
logger.info(f'【接收】[gsuid-core]: {msg}') msg = msgjson.decode(message, type=MessageSend)
# 解析消息 logger.info(
content = '' f'【接收】[gsuid-core]: '
image: Optional[str] = None f'{msg.bot_id} - {msg.target_type} - {msg.target_id}'
node = [] )
if msg.content: # 解析消息
for _c in msg.content: if msg.bot_id == 'NoneBot2':
if _c.data: continue
if _c.type == 'text': bot = _get_bot(msg.bot_id)
content += _c.data content = ''
elif _c.type == 'image': image: Optional[str] = None
image = _c.data node = []
elif _c.type and _c.type.startswith('log'): if msg.content:
_type = _c.type.split('_')[-1].lower() for _c in msg.content:
getattr(logger, _type)(_c.data) if _c.data:
elif _c.type == 'node': if _c.type == 'text':
node = _c.data content += _c.data
else: elif _c.type == 'image':
pass image = _c.data
elif _c.type and _c.type.startswith('log'):
_type = _c.type.split('_')[-1].lower()
getattr(logger, _type)(_c.data)
elif _c.type == 'node':
node = _c.data
else:
pass
# 根据bot_id字段发送消息 # 根据bot_id字段发送消息
# OneBot v11 & v12 # OneBot v11 & v12
if msg.bot_id == 'onebot': if msg.bot_id == 'onebot':
await onebot_send( await onebot_send(
bot, bot,
content, content,
image, image,
node, node,
msg.target_id, msg.target_id,
msg.target_type, msg.target_type,
) )
# ntchat # ntchat
elif msg.bot_id == 'ntchat': elif msg.bot_id == 'ntchat':
await ntchat_send(bot, content, image, node, msg.target_id) await ntchat_send(
# 频道 bot, content, image, node, msg.target_id
elif msg.bot_id == 'qqguild': )
await guild_send( # 频道
bot, elif msg.bot_id == 'qqguild':
content, await guild_send(
image, bot,
node, content,
msg.target_id, image,
msg.target_type, node,
) msg.target_id,
msg.target_type,
)
except Exception as e:
logger.error(e)
except ConnectionClosedError: except ConnectionClosedError:
logger.warning(f'与[gsuid-core]断开连接! Bot_ID: {BOT_ID}') logger.warning(f'与[gsuid-core]断开连接! Bot_ID: {BOT_ID}')
@ -115,7 +145,7 @@ async def onebot_send(
target_type: Optional[str], target_type: Optional[str],
): ):
async def _send(content: Optional[str], image: Optional[str]): async def _send(content: Optional[str], image: Optional[str]):
result_image = f'[CQ:image,file=base64://{image}]' if image else '' result_image = f'[CQ:image,file={image}]' if image else ''
content = content if content else '' content = content if content else ''
result_msg = content + result_image result_msg = content + result_image
if target_type == 'group': if target_type == 'group':
@ -148,7 +178,7 @@ async def onebot_send(
if node: if node:
messages = [ messages = [
to_json( to_json(
f'[CQ:image,file=base64://{_msg["data"]}]' f'[CQ:image,file={_msg["data"]}]'
if _msg['type'] == 'image' if _msg['type'] == 'image'
else _msg['data'], else _msg['data'],
'小助手', '小助手',
@ -173,7 +203,7 @@ async def guild_send(
async def _send(content: Optional[str], image: Optional[str]): async def _send(content: Optional[str], image: Optional[str]):
result = {} result = {}
if image: if image:
img_bytes = base64.b64decode(image) img_bytes = base64.b64decode(image.replace('base64://', ''))
result['file_image'] = img_bytes result['file_image'] = img_bytes
if content: if content:
result['content'] = content result['content'] = content
@ -215,7 +245,7 @@ async def ntchat_send(
await bot.call_api( await bot.call_api(
'send_image', 'send_image',
to_wxid=target_id, to_wxid=target_id,
content=content, file_path=image,
) )
if node: if node:

6
poetry.lock generated
View File

@ -564,14 +564,14 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa
[[package]] [[package]]
name = "platformdirs" name = "platformdirs"
version = "3.1.0" version = "3.1.1"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "platformdirs-3.1.0-py3-none-any.whl", hash = "sha256:13b08a53ed71021350c9e300d4ea8668438fb0046ab3937ac9a29913a1a1350a"}, {file = "platformdirs-3.1.1-py3-none-any.whl", hash = "sha256:e5986afb596e4bb5bde29a79ac9061aa955b94fca2399b7aaac4090860920dd8"},
{file = "platformdirs-3.1.0.tar.gz", hash = "sha256:accc3665857288317f32c7bebb5a8e482ba717b474f3fc1d18ca7f9214be0cef"}, {file = "platformdirs-3.1.1.tar.gz", hash = "sha256:024996549ee88ec1a9aa99ff7f8fc819bb59e2c3477b410d90a16d32d6e707aa"},
] ]
[package.extras] [package.extras]