mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-10-21 16:05:19 +08:00
* feat(onebot): support main-port reverse and forward WebSocket connections * fix(onebot): keep protocol metadata out of business events * test(onebot): validate WS events and APIs against independent protocol peer --------- Co-authored-by: Hyu <[email protected]>
108 lines
4.2 KiB
Python
108 lines
4.2 KiB
Python
"""Independent OneBot v11 wire peer; no LangBot transport/converter imports.
|
|
|
|
Contract: https://github.com/botuniverse/onebot-11 (api/public.md,
|
|
communication/{ws,ws-reverse,http}.md and event/*.md).
|
|
Only test data is served; no real QQ account or vendor service is contacted.
|
|
"""
|
|
|
|
import asyncio
|
|
import json
|
|
|
|
|
|
class OneBotMock:
|
|
def __init__(self):
|
|
self.ready = asyncio.Event()
|
|
self.requests = []
|
|
self.send = None
|
|
self.response = None
|
|
self.user = {'user_id': 10001, 'nickname': 'Alice', 'sex': 'unknown', 'age': 20}
|
|
self.group = {'group_id': 20001, 'group_name': 'Mock group', 'member_count': 2, 'max_member_count': 200}
|
|
self.member = self.user | {'group_id': 20001, 'card': 'Card', 'role': 'admin', 'title': 'Title', 'join_time': 1}
|
|
|
|
async def run(self, send, receive):
|
|
self.send = send
|
|
self.ready.set()
|
|
while True:
|
|
request = json.loads(await receive())
|
|
self.requests.append(request)
|
|
if self.response is not None:
|
|
response = dict(self.response)
|
|
else:
|
|
response = self.handle(request)
|
|
await send(json.dumps(response | {'echo': request.get('echo')}))
|
|
|
|
def handle(self, request):
|
|
action, params = request['action'], request.get('params', {})
|
|
for key in ('user_id', 'group_id', 'message_id', 'duration'):
|
|
if key in params:
|
|
assert type(params[key]) is int, (action, key, params[key])
|
|
data = None
|
|
if action in ('send_msg', 'send_private_msg', 'send_group_msg'):
|
|
assert isinstance(params['message'], (list, str))
|
|
data = {'message_id': 123}
|
|
elif action == 'get_msg':
|
|
data = self.message('private', 'friend')
|
|
elif action == 'get_login_info':
|
|
data = {'user_id': 42, 'nickname': 'Mock bot'}
|
|
elif action == 'get_stranger_info':
|
|
data = self.user
|
|
elif action == 'get_friend_list':
|
|
data = [self.user | {'remark': 'Friend'}]
|
|
elif action == 'get_group_info':
|
|
data = self.group
|
|
elif action == 'get_group_list':
|
|
data = [self.group]
|
|
elif action == 'get_group_member_info':
|
|
data = self.member
|
|
elif action == 'get_group_member_list':
|
|
data = [self.member]
|
|
elif action == 'get_status':
|
|
data = {'online': True, 'good': True}
|
|
elif action == 'get_version_info':
|
|
data = {'app_name': 'onebot-test-peer', 'app_version': '1', 'protocol_version': 'v11'}
|
|
elif action in ('can_send_image', 'can_send_record'):
|
|
data = {'yes': True}
|
|
elif action in ('get_image', 'get_record'):
|
|
data = {'file': '/mock/media'}
|
|
elif action == 'get_forward_msg':
|
|
data = {'message': []}
|
|
elif action == 'get_group_honor_info':
|
|
data = {'group_id': 20001}
|
|
elif action not in {
|
|
'delete_msg',
|
|
'set_group_name',
|
|
'set_group_ban',
|
|
'set_group_kick',
|
|
'set_group_leave',
|
|
'set_friend_add_request',
|
|
'set_group_add_request',
|
|
'set_group_card',
|
|
'set_group_special_title',
|
|
'set_group_admin',
|
|
'set_group_whole_ban',
|
|
}:
|
|
return {'status': 'failed', 'retcode': 1404, 'data': None}
|
|
return {'status': 'ok', 'retcode': 0, 'data': data}
|
|
|
|
async def emit(self, payload):
|
|
await self.ready.wait()
|
|
await self.send(json.dumps({'time': 1700000000, 'self_id': 42} | payload))
|
|
|
|
def message(self, kind, subtype, message=None):
|
|
result = {
|
|
'post_type': 'message',
|
|
'message_type': kind,
|
|
'sub_type': subtype,
|
|
'time': 1700000000,
|
|
'self_id': 42,
|
|
'message_id': 9,
|
|
'user_id': 10001,
|
|
'message': message if message is not None else [{'type': 'text', 'data': {'text': 'hello'}}],
|
|
'raw_message': 'hello',
|
|
'font': 0,
|
|
'sender': self.user,
|
|
}
|
|
if kind == 'group':
|
|
result.update(group_id=20001, anonymous=None, sender=self.member)
|
|
return result
|