refactor(wechatmp): use wechatpy to handle wechatmp messages

feat(wechatmp): add support for image and voice replies
This commit is contained in:
lanvent
2023-04-21 02:47:33 +08:00
parent c60f0517fb
commit 89dd8a1db6
7 changed files with 267 additions and 337 deletions

View File

@@ -3,15 +3,14 @@ import asyncio
import web
from channel.wechatmp.wechatmp_message import parse_xml
from channel.wechatmp.passive_reply_message import TextMsg, VoiceMsg, ImageMsg
from channel.wechatmp.wechatmp_message import WeChatMPMessage
from bridge.context import *
from bridge.reply import ReplyType
from channel.wechatmp.common import *
from channel.wechatmp.wechatmp_channel import WechatMPChannel
from common.log import logger
from config import conf
from wechatpy import parse_message
from wechatpy.replies import create_reply, ImageReply, VoiceReply
# This class is instantiated once per query
class Query:
@@ -22,36 +21,49 @@ class Query:
try:
request_time = time.time()
channel = WechatMPChannel()
webData = web.data()
logger.debug("[wechatmp] Receive post data:\n" + webData.decode("utf-8"))
wechatmp_msg = parse_xml(webData)
if wechatmp_msg.msg_type == "text" or wechatmp_msg.msg_type == "voice":
message = web.data() # todo crypto
msg = parse_message(message)
logger.debug("[wechatmp] Receive post data:\n" + message.decode("utf-8"))
if msg.type == "event":
logger.info(
"[wechatmp] Event {} from {}".format(
msg.event, msg.source
)
)
reply_text = subscribe_msg()
replyPost = create_reply(reply_text, msg)
return replyPost.render()
wechatmp_msg = WeChatMPMessage(msg, client=channel.client)
if wechatmp_msg.ctype in [ContextType.TEXT, ContextType.IMAGE, ContextType.VOICE]:
from_user = wechatmp_msg.from_user_id
to_user = wechatmp_msg.to_user_id
message = wechatmp_msg.content
content = wechatmp_msg.content
message_id = wechatmp_msg.msg_id
supported = True
if "【收到不支持的消息类型,暂无法显示】" in message:
if "【收到不支持的消息类型,暂无法显示】" in content:
supported = False # not supported, used to refresh
# New request
if (
from_user not in channel.cache_dict
and from_user not in channel.running
or message.startswith("#")
or content.startswith("#")
and message_id not in channel.request_cnt # insert the godcmd
):
# The first query begin
if (wechatmp_msg.msg_type == "voice" and conf().get("voice_reply_voice") == True):
rtype = ReplyType.VOICE
if (msg.type == "voice" and wechatmp_msg.ctype == ContextType.TEXT):
origin_ctype = ContextType.VOICE
context = channel._compose_context(
wechatmp_msg.ctype, content, isgroup=False, origin_ctype=origin_ctype, msg=wechatmp_msg
)
else:
rtype = None
context = channel._compose_context(
ContextType.TEXT, message, isgroup=False, desire_rtype=rtype, msg=wechatmp_msg
)
context = channel._compose_context(
wechatmp_msg.ctype, content, isgroup=False, msg=wechatmp_msg
)
logger.debug(
"[wechatmp] context: {} {}".format(context, wechatmp_msg)
"[wechatmp] context: {} {} {}".format(context, wechatmp_msg, supported)
)
if supported and context:
@@ -65,26 +77,27 @@ class Query:
trigger_prefix = conf().get("single_chat_prefix", [""])
if trigger_prefix or not supported:
if trigger_prefix:
content = textwrap.dedent(
reply_text = textwrap.dedent(
f"""\
请输入'{trigger_prefix}'接你想说的话跟我说话。
例如:
{trigger_prefix}你好,很高兴见到你。"""
)
else:
content = textwrap.dedent(
reply_text = textwrap.dedent(
"""\
你好,很高兴见到你。
请跟我说话吧。"""
)
else:
logger.error(f"[wechatmp] unknown error")
content = textwrap.dedent(
reply_text = textwrap.dedent(
"""\
未知错误,请稍后再试"""
)
replyPost = TextMsg(wechatmp_msg.from_user_id, wechatmp_msg.to_user_id, content).send()
return replyPost
replyPost = create_reply(reply_text, msg)
return replyPost.render()
# Wechat official server will request 3 times (5 seconds each), with the same message_id.
@@ -96,7 +109,7 @@ class Query:
request_cnt,
from_user,
message_id,
message,
content,
web.ctx.env.get("REMOTE_ADDR"),
web.ctx.env.get("REMOTE_PORT"),
)
@@ -121,8 +134,8 @@ class Query:
else: # request_cnt == 3:
# return timeout message
reply_text = "【正在思考中,回复任意文字尝试获取回复】"
replyPost = TextMsg(from_user, to_user, reply_text).send()
return replyPost
replyPost = create_reply(reply_text, msg)
return replyPost.render()
# reply is ready
channel.request_cnt.pop(message_id)
@@ -158,36 +171,27 @@ class Query:
request_cnt,
from_user,
message_id,
message,
content,
reply_text,
)
)
replyPost = TextMsg(from_user, to_user, reply_text).send()
return replyPost
replyPost = create_reply(reply_text, msg)
return replyPost.render()
elif (reply_type == "voice"):
media_id = content
asyncio.run_coroutine_threadsafe(channel.delete_media(media_id), channel.delete_media_loop)
replyPost = VoiceMsg(from_user, to_user, media_id).send()
return replyPost
replyPost = VoiceReply(message=msg)
replyPost.media_id = media_id
return replyPost.render()
elif (reply_type == "image"):
media_id = content
asyncio.run_coroutine_threadsafe(channel.delete_media(media_id), channel.delete_media_loop)
replyPost = ImageMsg(from_user, to_user, media_id).send()
return replyPost
elif wechatmp_msg.msg_type == "event":
logger.info(
"[wechatmp] Event {} from {}".format(
wechatmp_msg.content, wechatmp_msg.from_user_id
)
)
content = subscribe_msg()
replyMsg = TextMsg(
wechatmp_msg.from_user_id, wechatmp_msg.to_user_id, content
)
return replyMsg.send()
replyPost = ImageReply(message=msg)
replyPost.media_id = media_id
return replyPost.render()
else:
logger.info("暂且不处理")
return "success"