diff --git a/qqbot/QQBot.py b/qqbot/QQBot.py index 0af29a42..dabe40ef 100644 --- a/qqbot/QQBot.py +++ b/qqbot/QQBot.py @@ -154,15 +154,35 @@ async def reconnect(self): "seq": self.s, }})) - def send_group_message(self, group_id: str, content: str, reply_msg_id: str = "", image: str = None): + def ack_interaction(self, event: dict): + d = event['d'] + event_id = d['id'] + self._log.debug('Acking interaction %s...', event_id) + response = requests.put( + f'{self.base_url}/interactions/{event_id}', + headers=self.headers, + json={'code': 0}, + timeout=5, + ) + self._log.debug('HTTP response: %s', response.text) + + def send_group_message(self, group_id: str, content: str = None, reply_msg_id: str = "", image: str = None, markdown: dict = None): self._log.debug('Sending message %s to group %s...', content, group_id) post_data = { "content": content, "msg_type": 0, } + if image: + post_data['image'] = image + if markdown: + post_data = markdown + if 'content' not in post_data: + post_data['content'] = content or '' + if 'msg_type' not in post_data: + post_data['msg_type'] = 2 if reply_msg_id: post_data['msg_id'] = reply_msg_id - self._log.debug('Post data: %s', json.dumps(post_data, indent=2)) + self._log.debug(f"Post data to group: {json.dumps(post_data, indent=2)}") response = requests.post( f'{self.base_url}/v2/groups/{group_id}/messages', headers=self.headers, @@ -171,21 +191,42 @@ def send_group_message(self, group_id: str, content: str, reply_msg_id: str = "" ) self._log.debug('HTTP response: %s', response.text) - def reply_group_message(self, message:dict, content: str, image: str = None): + def reply_group_message(self, message:dict, content: str = None, image: str = None, markdown: dict = None): data = message['d'] group_id = data['group_openid'] reply_msg_id = data['id'] - self.send_group_message(group_id, content, reply_msg_id) + self.send_group_message(group_id, content, reply_msg_id, image, markdown) + + def update_channel_markdown(self, event: dict, markdown: dict): + d = event['d'] + event_id = d['id'] + message_id = d['data']['resolved']['message_id'] + channel_id = d['channel_id'] + post_data = markdown + post_data['msg_id'] = message_id + # post_data['event_id'] = event_id + self._log.debug(f"Post data to channel: {json.dumps(post_data, indent=2, ensure_ascii=False)}") + response = requests.post( + f'{self.base_url}/channels/{channel_id}/messages', + headers=self.headers, + json=post_data, + timeout=5, + ) + self._log.debug('HTTP response: %s', response.text) + - def send_channel_message(self, channel_id: str, content: str, reply_msg_id=-1, image: str = None): + def send_channel_message(self, channel_id: str, content: str = None, reply_msg_id=-1, image: str = None, markdown: dict = None): self._log.debug('Sending message %s to channel %s...', content, channel_id) post_data = { "content": content, } - if reply_msg_id != -1: - post_data['msg_id'] = reply_msg_id if image: post_data['image'] = image + if reply_msg_id != -1: + post_data['msg_id'] = reply_msg_id + if markdown: + post_data = markdown + self._log.debug(f"Post data to channel: {json.dumps(post_data, indent=2)}") response = requests.post( f'{self.base_url}/channels/{channel_id}/messages', headers=self.headers, @@ -194,11 +235,11 @@ def send_channel_message(self, channel_id: str, content: str, reply_msg_id=-1, i ) self._log.debug('HTTP response: %s', response.text) - def reply_channel_message(self, message:dict, content: str, image: str = None): + def reply_channel_message(self, message: dict, content: str = None, image: str = None, markdown: dict = None): data = message['d'] channel_id = data['channel_id'] reply_msg_id = data['id'] - self.send_channel_message(channel_id, content, reply_msg_id) + self.send_channel_message(channel_id, content, reply_msg_id, image, markdown) async def handle(self, message: dict): op = message['op'] @@ -264,3 +305,11 @@ def wrap(*args, **kwargs): kwargs['qqbot'] = self func(*args, **kwargs) return wrap + + def on_interaction_create(self, func: callable): + def wrap(*args, **kwargs): + func_meta = inspect.getfullargspec(func) + if "qqbot" in func_meta.args: + kwargs['qqbot'] = self + func(*args, **kwargs) + return wrap diff --git a/qqbot/events/__init__.py b/qqbot/events/__init__.py index 1c9d2fa8..ccdebe4c 100644 --- a/qqbot/events/__init__.py +++ b/qqbot/events/__init__.py @@ -1,3 +1,3 @@ -from .guilds import on_at_message_create +from .guilds import on_at_message_create, on_interaction_create from .groups import on_group_at_message_create \ No newline at end of file diff --git a/qqbot/events/groups.py b/qqbot/events/groups.py index db171126..fe2e191d 100644 --- a/qqbot/events/groups.py +++ b/qqbot/events/groups.py @@ -2,7 +2,7 @@ import re import logging from QQBot import QQBot -from .guilds import handle_quest, handle_search, handle_market, handle_luck +from .guilds import handle_quest, handle_search, handle_market, handle_luck, handle_house, msg_to_markdown _log = logging.getLogger("QQBot Groups") @@ -33,7 +33,8 @@ def on_group_at_message_create(message, qqbot: QQBot): ark = msg_object["ark"] else: msg = msg_object["message"] - msg = re.sub(r"https://garlandtools.cn/db/#item/\d+", "", msg) + # If you didn't add this domain to your trusted domain, you need to uncomment this line + # msg = re.sub(r"https://garlandtools.cn/db/#item/\d+", "", msg) if content.startswith("/market") or content.startswith("/mitem"): args_str = content.replace("/mitem", "/market item").replace("/market", "").strip() args = args_str.split(" ") @@ -48,6 +49,16 @@ def on_group_at_message_create(message, qqbot: QQBot): args.remove('') msg_object = handle_luck(args, user_id) msg = msg_object["message"] + if content.startswith("/house"): + args_str = content.replace("/house", "").strip() + args = args_str.split(" ") + while '' in args: + args.remove('') + msg_object = handle_house(args) + msg = msg_object["message"] + if content.startswith("/markdown"): + qqbot.reply_group_message(message, markdown=msg_to_markdown()) + return if msg: qqbot.log.info(msg) if image: diff --git a/qqbot/events/guilds.py b/qqbot/events/guilds.py index 9d0cde50..7eb26d0a 100644 --- a/qqbot/events/guilds.py +++ b/qqbot/events/guilds.py @@ -56,6 +56,8 @@ def handle_search(item_name): return { "message": ret_msg.strip() } ret_data = ret_data["data"] msg = "{}\n{}".format(ret_data["title"], ret_data["content"]) + if "url" in ret_data: + msg += "\n{}".format(ret_data["url"]) return { "message": msg, } @@ -133,8 +135,86 @@ def handle_luck(command_seg, user_id): msg = 'API error, please check log.' return { "message": msg } + +def handle_house(command_seg): + help_msg = """/house $server ($area) ($size) ($type): 查询 $server 服务器的 $area 区域房源信息 +/house upload: 查询如何上传房源信息 +例:/house 萌芽池 海雾村 小 部队 +Powered by 艾欧泽亚售楼中心""" + msg = help_msg + if len(command_seg) == 0 or command_seg[0].lower() == "help": + return { "message": msg } + command_len = len(command_seg) + server_name = command_seg[0] + area = command_seg[1] if command_len >= 2 else "" + size = command_seg[2] if command_len >= 3 else "" + r_type = "" + for k in ("部队", "个人"): + if k in command_seg: + r_type = k + break + post_data = { + "request": "house", + "data": { + "server": server_name, + "area": area, + "size": size, + "r_type": r_type, + } + } + r = requests.post(API_BASE, json=post_data) + ret_data = r.json() + _log.debug(json.dumps(ret_data, indent=2)) + if ret_data['rcode'] == '0': + msg = ret_data['data'] + else: + msg = 'API error, please check log.' + return { "message": msg } + +def msg_to_markdown(page=1): + keyboard_payload = { + 'keyboard': { + 'id': '102006036_1704906854', + }, + 'markdown': { + 'custom_template_id': '102006036_1701820636', + 'params': [{ + 'key': 'title0', + 'values': [f'标题{page}'] + },{ + 'key': 'desc0', + 'values': [f'简介{page}'] + },{ + 'key': 'title1', + 'values': [f'标题{page+1}'] + },{ + 'key': 'desc1', + 'values': [f'简介{page+1}'] + },{ + 'key': 'title2', + 'values': [f'标题{page+2}'] + },{ + 'key': 'desc2', + 'values': [f'简介{page+2}'] + },{ + 'key': 'title3', + 'values': [f'标题{page+3}'] + },{ + 'key': 'desc3', + 'values': [f'简介{page+3}'] + },{ + 'key': 'title4', + 'values': [f'标题{page+4}'] + },{ + 'key': 'desc4', + 'values': [f'简介{page+4}'] + }], + }, + } + return keyboard_payload + def on_at_message_create(message, qqbot): - _log.info(json.dumps(message, indent=2, ensure_ascii=False)) + _log.debug(json.dumps(message, indent=2, ensure_ascii=False)) data = message['d'] channel_id = data['channel_id'] user_id = data['author']['id'] @@ -174,10 +254,35 @@ def on_at_message_create(message, qqbot): args.remove('') msg_object = handle_luck(args, user_id) msg = msg_object["message"] + if content.startswith("/house"): + args_str = content.replace("/house", "").strip() + args = args_str.split(" ") + while '' in args: + args.remove('') + msg_object = handle_house(args) + msg = msg_object["message"] + # Wait for template audit even in sandbox environment + if content.startswith("/markdown"): + qqbot.reply_channel_message(message, markdown=msg_to_markdown()) + return if msg: qqbot.log.info(msg) if image: qqbot.log.info("Sending image %s", image) qqbot.reply_channel_message(message, content=msg, image=image) else: - qqbot.reply_channel_message(message, content=msg) \ No newline at end of file + qqbot.reply_channel_message(message, content=msg) + + +def on_interaction_create(event, qqbot): + _log.info(json.dumps(event, indent=2, ensure_ascii=False)) + d = event['d'] + qqbot.ack_interaction(event) # need to ask for permission + # if d['chat_type'] == 0: + # page = 1 + # if d['data']['resolved']['button_data'] == 'nextPage': + # page += 1 + # else: + # page -= 1 + # markdown = msg_to_markdown(page) + # qqbot.update_channel_markdown(event, markdown) \ No newline at end of file