zhayujie / chatgpt-on-wechat

基于大模型搭建的聊天机器人,同时支持 微信公众号、企业微信应用、飞书、钉钉 等接入,可选择GPT3.5/GPT-4o/GPT4.0/ Claude/文心一言/讯飞星火/通义千问/ Gemini/GLM-4/Claude/Kimi/LinkAI,能处理文本、语音和图片,访问操作系统和互联网,支持基于自有知识库进行定制企业智能客服。
https://docs.link-ai.tech/cow
MIT License
28.11k stars 7.49k forks source link

无法发送图片 #1892

Open MuskZhouMQ opened 2 months ago

MuskZhouMQ commented 2 months ago

前置确认

⚠️ 搜索issues中是否已存在类似问题

操作系统类型?

Linux

运行的python版本是?

python 3.10

使用的chatgpt-on-wechat版本是?

Latest Release

运行的channel类型是?

wx(个人微信, itchat)

复现步骤 🕹

在聊天框输入画一个人类,无回复

问题描述 😯

日志显示已生成图片并且发送,但并未收到

终端日志 📒

[INFO][2024-04-14 13:37:31][open_ai_image.py:22] - [OPEN_AI] image_query=一个人类 [INFO][2024-04-14 13:37:32][wechat_channel.py:55] - Wechat message 2610636063098786311 already received, ignore [INFO][2024-04-14 13:37:32][wechat_channel.py:55] - Wechat message 2610636063098786311 already received, ignore [INFO][2024-04-14 13:37:32][wechat_channel.py:55] - Wechat message 2610636063098786311 already received, ignore [INFO][2024-04-14 13:37:32][wechat_channel.py:55] - Wechat message 2610636063098786311 already received, ignore [INFO][2024-04-14 13:37:32][wechat_channel.py:55] - Wechat message 2610636063098786311 already received, ignore [INFO][2024-04-14 13:37:53][open_ai_image.py:31] - [OPEN_AI] image_url=https://filesystem.site/cdn/20240414/J3peFnSvWzqnN6COjijsJ48RAkKBGo.webp [INFO][2024-04-14 13:37:55][wechat_channel.py:230] - [WX] download image success, size=325604, img_url=https://filesystem.site/cdn/20240414/J3peFnSvWzqnN6COjijsJ48RAkKBGo.webp [INFO][2024-04-14 13:37:57][wechat_channel.py:233] - [WX] sendImage url=https://filesystem.site/cdn/20240414/J3peFnSvWzqnN6COjijsJ48RAkKBGo.webp, receiver=@48c7ca2950bf882c8744854398c1e3821e38cf131e85fd555a177c8dca5d84f7

liangxuannb commented 2 months ago

这确实是目前的问题,某些图片是webp格式的,回复不出来

sbcxk commented 2 months ago

大佬有解决办法嘛,遇到同样的问题,图片生成了但无法~Docker部署的

sbcxk commented 2 months ago

希望大佬能更新支持一下,可以用这种方式(发送图片后,同时返回文件链接) image

uluckyXH commented 1 week ago

image 记得在上面加上:import uuid

    # 统一的发送函数,每个Channel自行实现,根据reply的type字段发送不同类型的消息
    def send(self, reply: Reply, context: Context):
        receiver = context["receiver"]
        if reply.type == ReplyType.TEXT:
            itchat.send(reply.content, toUserName=receiver)
            logger.info("[WX] sendMsg={}, receiver={}".format(reply, receiver))
        elif reply.type == ReplyType.ERROR or reply.type == ReplyType.INFO:
            itchat.send(reply.content, toUserName=receiver)
            logger.info("[WX] sendMsg={}, receiver={}".format(reply, receiver))
        elif reply.type == ReplyType.VOICE:
            itchat.send_file(reply.content, toUserName=receiver)
            logger.info("[WX] sendFile={}, receiver={}".format(reply.content, receiver))
        elif reply.type == ReplyType.IMAGE_URL:  # 从网络下载图片
            img_url = reply.content
            logger.debug(f"[WX] start download image, img_url={img_url}")
            pic_res = requests.get(img_url, stream=True)
            image_storage = io.BytesIO()
            size = 0
            for block in pic_res.iter_content(1024):
                size += len(block)
                image_storage.write(block)
            logger.info(f"[WX] download image success, size={size}, img_url={img_url}")
            image_storage.seek(0)

            # 添加对 .webp 图片格式的处理
            if img_url.endswith(".webp"):
                image_storage = self._convert_webp_to_png(image_storage)

            itchat.send_image(image_storage, toUserName=receiver)
            logger.info("[WX] sendImage url={}, receiver={}".format(img_url, receiver))
        elif reply.type == ReplyType.IMAGE:  # 从文件读取图片
            image_storage = reply.content
            image_storage.seek(0)

            # 添加对 .webp 图片格式的处理
            if image_storage.name.endswith(".webp"):
                image_storage = self._convert_webp_to_png(image_storage)

            itchat.send_image(image_storage, toUserName=receiver)
            logger.info("[WX] sendImage, receiver={}".format(receiver))
        elif reply.type == ReplyType.FILE:  # 新增文件回复类型
            file_storage = reply.content
            itchat.send_file(file_storage, toUserName=receiver)
            logger.info("[WX] sendFile, receiver={}".format(receiver))
        elif reply.type == ReplyType.VIDEO:  # 新增视频回复类型
            video_storage = reply.content
            itchat.send_video(video_storage, toUserName=receiver)
            logger.info("[WX] sendFile, receiver={}".format(receiver))
        elif reply.type == ReplyType.VIDEO_URL:  # 新增视频URL回复类型
            video_url = reply.content
            logger.debug(f"[WX] start download video, video_url={video_url}")
            video_res = requests.get(video_url, stream=True)
            video_storage = io.BytesIO()
            size = 0
            for block in video_res.iter_content(1024):
                size += len(block)
                video_storage.write(block)
            logger.info(f"[WX] download video success, size={size}, video_url={video_url}")
            video_storage.seek(0)
            itchat.send_video(video_storage, toUserName=receiver)
            logger.info("[WX] sendVideo url={}, receiver={}".format(video_url, receiver))

    def _convert_webp_to_png(self, webp_image):
        from PIL import Image
        webp_image.seek(0)
        img = Image.open(webp_image).convert("RGBA")
        png_image = io.BytesIO()
        unique_filename = f"{uuid.uuid4()}.png"
        img.save(png_image, format="PNG")
        png_image.name = unique_filename
        png_image.seek(0)
        return png_image
sbcxk commented 1 week ago

感谢大佬 受教啦 👍 ,不过这个文件还需要加一个import uuid

uluckyXH commented 1 week ago

感谢大佬 受教啦 👍 ,不过这个文件还需要加一个import uuid

OK,我重新编辑了一下