From 3ea87813810e59922b654f8ebb4070ea878e7c29 Mon Sep 17 00:00:00 2001 From: lanvent Date: Thu, 20 Apr 2023 02:14:52 +0800 Subject: [PATCH] feat(wechatcom): add support for sending image --- channel/wechatcom/wechatcom_channel.py | 54 +++++++++++++++++++++++--- channel/wechatcom/wechatcom_message.py | 17 ++++++-- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/channel/wechatcom/wechatcom_channel.py b/channel/wechatcom/wechatcom_channel.py index 6bb4f1f..90c7b22 100644 --- a/channel/wechatcom/wechatcom_channel.py +++ b/channel/wechatcom/wechatcom_channel.py @@ -1,7 +1,10 @@ #!/usr/bin/env python # -*- coding=utf-8 -*- +import io import os +import textwrap +import requests import web from wechatpy.enterprise import WeChatClient, create_reply, parse_message from wechatpy.enterprise.crypto import WeChatCrypto @@ -20,7 +23,7 @@ from voice.audio_convert import any_to_amr @singleton class WechatComChannel(ChatChannel): - NOT_SUPPORT_REPLYTYPE = [ReplyType.IMAGE] + NOT_SUPPORT_REPLYTYPE = [] def __init__(self): super().__init__() @@ -72,6 +75,38 @@ class WechatComChannel(ChatChannel): logger.info( "[wechatcom] sendVoice={}, receiver={}".format(reply.content, receiver) ) + elif reply.type == ReplyType.IMAGE_URL: # 从网络下载图片 + img_url = reply.content + pic_res = requests.get(img_url, stream=True) + image_storage = io.BytesIO() + for block in pic_res.iter_content(1024): + image_storage.write(block) + image_storage.seek(0) + try: + response = self.client.media.upload("image", image_storage) + logger.debug("[wechatcom] upload image response: {}".format(response)) + except WeChatClientException as e: + logger.error("[wechatcom] upload image failed: {}".format(e)) + return + self.client.message.send_image( + self.agent_id, receiver, response["media_id"] + ) + logger.info( + "[wechatcom] sendImage url={}, receiver={}".format(img_url, receiver) + ) + elif reply.type == ReplyType.IMAGE: # 从文件读取图片 + image_storage = reply.content + image_storage.seek(0) + try: + response = self.client.media.upload("image", image_storage) + logger.debug("[wechatcom] upload image response: {}".format(response)) + except WeChatClientException as e: + logger.error("[wechatcom] upload image failed: {}".format(e)) + return + self.client.message.send_image( + self.agent_id, receiver, response["media_id"] + ) + logger.info("[wechatcom] sendImage, receiver={}".format(receiver)) class Query: @@ -103,13 +138,22 @@ class Query: ) except (InvalidSignatureException, InvalidCorpIdException): raise web.Forbidden() - print(message) msg = parse_message(message) - - print(msg) + logger.debug("[wechatcom] receive message: {}, msg= {}".format(message, msg)) if msg.type == "event": if msg.event == "subscribe": - reply = create_reply("感谢关注", msg).render() + trigger_prefix = conf().get("single_chat_prefix", [""])[0] + reply_content = textwrap.dedent( + f"""\ + 感谢您的关注! + 这里是ChatGPT,可以自由对话。 + 支持语音对话。 + 支持通用表情输入。 + 支持图片输入输出。 + 支持角色扮演和文字冒险两种定制模式对话。 + 输入'{trigger_prefix}#help' 查看详细指令。""" + ) + reply = create_reply(reply_content, msg).render() res = channel.crypto.encrypt_message(reply, nonce, timestamp) return res else: diff --git a/channel/wechatcom/wechatcom_message.py b/channel/wechatcom/wechatcom_message.py index 42de66e..9b34f11 100644 --- a/channel/wechatcom/wechatcom_message.py +++ b/channel/wechatcom/wechatcom_message.py @@ -41,9 +41,20 @@ class WechatComMessage(ChatMessage): self._prepare_fn = download_voice elif msg.type == "image": self.ctype = ContextType.IMAGE - self.content = msg.image # content直接存临时目录路径 - print(self.content) - # self._prepare_fn = lambda: itchat_msg.download(self.content) # TODO: download image + self.content = TmpDir().path() + msg.media_id + ".png" # content直接存临时目录路径 + + def download_image(): + # 如果响应状态码是200,则将响应内容写入本地文件 + response = client.media.download(msg.media_id) + if response.status_code == 200: + with open(self.content, "wb") as f: + f.write(response.content) + else: + logger.info( + f"[wechatcom] Failed to download image file, {response.content}" + ) + + self._prepare_fn = download_image else: raise NotImplementedError( "Unsupported message type: Type:{} ".format(msg.type)