支持向gsuid_core/data目录放置template用以发送QQ的按钮/MD模板

This commit is contained in:
KimigaiiWuyi 2023-12-13 04:53:16 +08:00
parent 332c94b37e
commit a0407406db
6 changed files with 211 additions and 28 deletions

View File

@ -8,13 +8,21 @@ from gsuid_core.logger import logger
from gsuid_core.gs_logger import GsLogger
from gsuid_core.message_models import Button
from gsuid_core.models import Event, Message, MessageSend
from gsuid_core.load_template import parse_button, button_templates
from gsuid_core.utils.plugins_config.gs_config import core_plugins_config
from gsuid_core.segment import MessageSegment, to_markdown, convert_message
from gsuid_core.segment import (
MessageSegment,
to_markdown,
convert_message,
check_same_buttons,
markdown_to_template_markdown,
)
sp_msg_id: str = core_plugins_config.get_config('SpecificMsgId').data
is_sp_msg_id: str = core_plugins_config.get_config('EnableSpecificMsgId').data
ism: List = core_plugins_config.get_config('SendMDPlatform').data
isb: List = core_plugins_config.get_config('SendButtonsPlatform').data
istry: List = core_plugins_config.get_config('TryTemplateForQQ').data
enable_buttons_platform = isb
enable_markdown_platform = ism
@ -63,6 +71,7 @@ class _Bot:
msg_id=msg_id,
)
logger.info(f'[发送消息to] {bot_id} - {target_type} - {target_id}')
print(send)
await self.bot.send_bytes(msgjson.encode(send))
async def _process(self):
@ -175,8 +184,9 @@ class Bot:
reply = f'请在{timeout}秒内做出选择...'
_reply = await convert_message(reply, self.bot_id)
success = False
if self.ev.real_bot_id in enable_buttons_platform:
if self.ev.real_bot_id in enable_buttons_platform or istry:
_buttons = []
for option in option_list:
if isinstance(option, List):
@ -191,34 +201,51 @@ class Bot:
_buttons.append(option)
else:
_buttons.append(Button(option, option, option))
md = await to_markdown(_reply, _buttons, self.bot_id)
if self.ev.real_bot_id in enable_markdown_platform:
await self.send(
await to_markdown(_reply, _buttons, self.bot_id)
)
else:
await self.send(md)
success = True
if istry:
md = await markdown_to_template_markdown(md)
fake_buttons = parse_button(_buttons)
for custom_template_id in button_templates:
p = parse_button(button_templates[custom_template_id])
if check_same_buttons(p, fake_buttons):
md.append(
MessageSegment.template_buttons(
custom_template_id
)
)
success = True
await self.send(md)
break
if not success:
_reply.append(MessageSegment.buttons(_buttons))
await self.send(_reply)
else:
if unsuported_platform:
_options: List[str] = []
for option in option_list:
if isinstance(option, List):
for op in option:
if isinstance(op, Button):
_options.append(op.data)
else:
_options.append(op)
elif isinstance(option, Button):
_options.append(option.data)
else:
_options.append(option)
success = True
_reply.append(
MessageSegment.text(
'\n请输入以下命令之一:\n' + sep.join(_options)
)
)
await self.send(_reply)
if not success and unsuported_platform:
_options: List[str] = []
for option in option_list:
if isinstance(option, List):
for op in option:
if isinstance(op, Button):
_options.append(op.data)
else:
_options.append(op)
elif isinstance(option, Button):
_options.append(option.data)
else:
_options.append(option)
_reply.append(
MessageSegment.text('\n请输入以下命令之一:\n' + sep.join(_options))
)
await self.send(_reply)
elif reply:
await self.send(reply)

View File

@ -0,0 +1,63 @@
import re
import json
from typing import Dict, List, Union, TypedDict
from gsuid_core.message_models import Button
from gsuid_core.data_store import get_res_path
buttons_template_path = get_res_path(['template', 'buttons'])
markdown_template_path = get_res_path(['template', 'markdown'])
class MarkdownTemplates(TypedDict):
template_id: str
para: List[str]
button_templates: Dict[
str, Union[List[str], List[Button], List[List[str]], List[List[Button]]]
] = {}
markdown_templates: Dict[str, MarkdownTemplates] = {}
for button_template in buttons_template_path.iterdir():
with open(button_template, 'r', encoding='UTF-8') as f:
button_data = json.load(f)
btl = []
for buttons in button_data['rows']:
btr = []
for button in buttons['buttons']:
bt = Button(
button["render_data"]["label"],
button['action']['data'],
button["render_data"]["visited_label"],
)
btr.append(bt)
btl.append(btr)
btr = []
button_templates[button_template.stem] = btl
for markdown_template in markdown_template_path.iterdir():
with open(markdown_template, 'r') as file:
file_content = file.read()
para_list = re.findall(r'{{([^\n{}]+)}}', file_content)
new_text = re.sub(r'{{([^\n{}]+)}}', '$$', file_content.strip())
rep = (
new_text.replace('(', r'\(')
.replace(')', r'\)')
.replace('$$', r'([\s\S]+)')
)
markdown_templates[rep] = {
'template_id': markdown_template.stem,
'para': [i[1:] for i in para_list],
}
def parse_button(buttons):
fake_buttons = []
for i in buttons:
if isinstance(i, Button):
fake_buttons.append(i)
elif isinstance(i, List):
fake_buttons.extend(i)
return fake_buttons

View File

@ -5,6 +5,7 @@ from async_timeout import timeout
from gsuid_core.bot import Bot
from gsuid_core.sv import SL, SV
from gsuid_core.models import Event
from gsuid_core.message_models import Button
sv_switch = SV('测试开关')
@ -91,3 +92,30 @@ async def get_regex_msg(bot: Bot, ev: Event):
await bot.send(
f'[正则测试]校验成功!{ev.regex_dict["name"]}你输入的是{ev.regex_dict["int"]}'
)
@sv_switch.on_fullmatch('按钮模板')
async def send_temp_button_msg(bot: Bot, ev: Event):
a = '🏝️野外探索'
b = '🗺️查看地图'
c = '📖精灵状态'
d = '🕹️城镇打工'
e = '💎道具帮助'
f = '🚶更换地点'
g = '✨更新队伍'
h = '🥚精灵孵化'
i = '📋我的名片'
j = '🎀个体重置'
ab = Button(a, '野外探索')
bb = Button(b, '查看地图')
cb = Button(c, '精灵状态')
db = Button(d, '城镇打工')
eb = Button(e, '道具帮助')
fb = Button(f, '更换地点')
gb = Button(g, '更新队伍')
hb = Button(h, '精灵孵化')
ib = Button(i, '精灵状态')
jb = Button(j, '我的名片')
await bot.send_option('测试', [ab, bb, cb, db, eb, fb, gb, hb, ib, jb])

View File

@ -1,9 +1,10 @@
import re
import uuid
import random
from io import BytesIO
from pathlib import Path
from base64 import b64decode, b64encode
from typing import List, Tuple, Union, Literal, Optional
from typing import Dict, List, Tuple, Union, Literal, Optional
import msgspec
from PIL import Image
@ -13,6 +14,7 @@ from gsuid_core.data_store import image_res
from gsuid_core.message_models import Button
from gsuid_core.utils.image.convert import text2pic
from gsuid_core.utils.image.image_tools import sget
from gsuid_core.load_template import markdown_templates
from gsuid_core.utils.plugins_config.gs_config import (
send_pic_config,
pic_upload_config,
@ -93,6 +95,12 @@ class MessageSegment:
) -> Message:
return Message(type='buttons', data=msgspec.to_builtins(buttons))
@staticmethod
def template_buttons(
template_id: str,
) -> Message:
return Message(type='template_buttons', data=template_id)
@staticmethod
def markdown(
content: str,
@ -104,6 +112,23 @@ class MessageSegment:
return data
@staticmethod
def template_markdown(
template_id: str,
para: Dict[str, str],
buttons: Optional[Union[List[Button], List[List[Button]]]] = None,
) -> List[Message]:
data = [
Message(
type='template_markdown',
data={'template_id': template_id, 'para': para},
)
]
if buttons:
data.append(MessageSegment.buttons(buttons))
return data
@staticmethod
def image_size(size: Tuple[int, int]) -> Message:
return Message(type='image_size', data=size)
@ -349,6 +374,33 @@ async def convert_message(
return _message
async def markdown_to_template_markdown(
message: List[Message],
) -> List[Message]:
_message = []
for m in message:
if m.type == 'markdown':
for mdt in markdown_templates:
match = re.fullmatch(mdt, str(m.data).strip())
if match:
match_para = match.groups()
para = markdown_templates[mdt]['para']
_message.extend(
MessageSegment.template_markdown(
markdown_templates[mdt]['template_id'],
{
i: match_para[index]
for index, i in enumerate(para)
},
)
)
break
else:
_message.append(m)
return _message
async def to_markdown(
message: List[Message],
buttons: Optional[Union[List[Button], List[List[Button]]]] = None,
@ -384,3 +436,15 @@ async def to_markdown(
_markdown = '\n'.join(_markdown_list)
_message.extend(MessageSegment.markdown(_markdown, buttons))
return _message
async def check_same_buttons(a: List[Button], b: List[Button]) -> bool:
if len(a) != len(b):
return False
count = 0
for button in a:
if button in b:
count += 1
if count == len(b):
return True
return False

View File

@ -129,7 +129,7 @@ class SV:
if name == '测试开关':
self.pm = 6
self.enabled = False
self.enabled = True
def set(self, **kwargs):
for var in kwargs:

View File

@ -70,5 +70,6 @@ CONIFG_DEFAULT: Dict[str, GSC] = {
'发送按钮的平台列表',
["villa", "kaiheila", "dodo", "discord", "telegram"],
),
'TryTemplateForQQ': GsBoolConfig('启用后尝试读取模板文件并发送', '发送MD和按钮模板', True),
'ForceSendMD': GsBoolConfig('强制使用MD发送图文', '强制使用MD发送图文', False),
}