zhayujie / chatgpt-on-wechat

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

让BOT发送表情包 #1278

Open Namarimizu opened 1 year ago

Namarimizu commented 1 year ago

⚠️ 搜索是否存在类似issue

总结

如题,受 #1078 启发,效果如下: botemojieff

实现方式其实很粗暴…… 而且我刚学 Python 没多久,很多都是跟着 GPT 做的,可以改进的地方肯定不少:

    def send(self, reply: Reply, context: Context):
        receiver = context["receiver"]
        if reply.type == ReplyType.TEXT:
            random.seed(time.time())  #不写这句的话后边随机数总是生成出0,不懂

"""
角色描述和roleplay插件的猫娘大同小异,但是多了以下部分:「%情感%就是你对话时的情感,放在两个%之间,
有以下七种情况:%无语%、%惊讶%、%难过%、%愉快%、%疑惑%、%安慰%、%害羞%」,配合猫娘自带的格式使用
"""

            mood_mapping = {
                "%愉快%": "joy",
                "%难过%": "sad",
                "%无语%": "speechless",
                "%惊讶%": "surprised",
                "%疑惑%": "doubt",
                "%安慰%": "comfort",
                "%害羞%": "shy",
            }

            # 处理文本,解决 GPT3.5 猫娘对话中「怎么了?喵~」之类文本被切成['怎么了?', '喵~']这两段而过于细碎的问题

            meow_dict = {
                '?喵~': '喵?',
                '!喵~': '喵!',
                '。喵~': '喵~'
            }
            for key, value in meow_dict.items():
                reply.content = reply.content.replace(key, value)

            reply.content = reply.content.replace("\n", "").replace("\r", "").strip()   # 清除大段文字中 GPT 式的换行和空行

            # 分割標點符號
            split_punc = ['。', '~', '?', '!', '!', '?', ')', '~']
            rm_punc = ['。']
            pattern = "(?<=[" + re.escape(''.join(split_punctuation)) + "])(?![?!(])"  # 在?!(之前不切分
            split_messages = re.split(pattern, reply.content)

            sticker_sent, i = 0, 0  # sticker_sent 变量限定单次回复内最多发送一次表情包,i 处理发送概率
            for msg in split_messages:
                for punc in rm_punc:
                    msg = msg.replace(punc, '')
                for keyword, emotion in mood_mapping.items():
                    if keyword in msg:
                        mood = emotion
                        msg = msg.replace(keyword, "")
                        i = random.randint(0, 1)
                        print(i)
"""
当一段对话有%情感%时,设置变量mood为对应的情感,清除文本中的情感信息,进行是否发送表情包的判定(因为较长的回复可能含有多种情感,
比如先 %安慰% 再 %愉快% ,据此可以随机决定是在 %安慰% 还是 %愉快% 文本之后发送对应表情包,或者干脆就不发送)print是debug用……
"""
                        break
                itchat.send(msg, toUserName=receiver)
                logger.info("[WX] sendMsg={}, receiver={}".format(msg, receiver))

                if mood and i == 1 and sticker_sent == 0:  # 有情感,判定为发送,且未发送过
                 image_directory = os.path.join('resources', 'stickers', mood)
                    image_files = [file for file in os.listdir(image_directory) if
                                   os.path.isfile(os.path.join(image_directory, file))]
                    image_file = random.choice(image_files)
                    image_path = os.path.join(image_directory, image_file)
                    print(image_path)
                    image_reply = Reply(ReplyType.IMAGE, image_path)
"""
随机选择一张图片发送。图片最好统一成 gif,这样微信会当成表情处理;另外文件大小似乎有限制
"""
                    self.send(image_reply, context)
                    sticker_sent = 1  # 限定一次回复中最多发送一张表情包
                    time.sleep(2)  #如果发送表情就多停顿1秒
                else:
                    time.sleep(1)

之后准备一个文件夹分类存放需要的表情 image 就OK了(

Namarimizu commented 1 year ago

对了,对于传到gpt那边的文本,自动把微信备注名作为前缀不知道效果怎么样

isanwenyu commented 1 year ago

请问有仓库吗?

Namarimizu commented 1 year ago

請問有倉庫嗎?

备份之后改一下.\channel\wechat_channel.py里边send函数的if reply.type == ReplyType.TEXT:这个分支下的内容,然后把表情包放在.\resources\stickers\对应表情目录里(表情包选用透明底gif效果最好,可以是动图),配置文件里的character_desc也加上%情感%相关的描述就可以了

mouxangithub commented 1 year ago

可以考虑整个插件

Namarimizu commented 1 year ago

可以考慮整個插件

确实那样更好,最近在忙别的下次试试😵

Xiaoheizi2023 commented 1 year ago

可以考慮整個插件

确实那样更好,最近在忙别的下次试试😵 大佬有空更新了踢我😋

JuliabenjaminOrange commented 1 year ago

想问一下,这个gif表情包是动态的吗

Namarimizu commented 1 year ago

想問一下,這個 gif 表情包是動態的嗎

可以是动画,也可以有透明度

qjsir commented 1 year ago

好有趣的样子,请问是直接替换if reply.type == ReplyType.TEXT:分枝下的全部内容就可以了吗

Namarimizu commented 1 year ago

好有趣的樣子,請問是直接替換 if reply.type == ReplyType.TEXT: 分枝下的全部內容就可以了嗎

角色描述那边也要补充对应内容(比如注释里的「%情感%就是……%害羞%」那段),根据需求再调整,还要把表情放到对应目录下;记得备份

qjsir commented 1 year ago

请问可以参考下你的角色描述怎么写的吗

Namarimizu commented 1 year ago

請問可以參考下你的角色描述怎麼寫的嗎

你看看自带 roleplay 插件里的猫娘,我想到会话格式其实也是顺着那个角色描述的思路,相关内容大概这样:

你的回话格式是「语言」+「动作」+ %情感%,比如「两凤(超开心)%愉快%」。动作包含你的动作或表情,用全角括号括起来,例如(摇尾巴)或(超开心);语言就是你要说的话,不用处理。%情感%就是你对话时的情感,放在%之间,只有以下七种:「%无语%、%惊讶%、%难过%、%愉快%、%疑惑%、%安慰%、%害羞%」,若都不符合则不说出%情感%。

那个「两凤」是乱打的不会在任何情况出现的无意义文本,我之前举例用「你好(超开心)」,结果GPT 3.5打招呼经常直接就复用「你好(超开心)」,所以这么处理……

qjsir commented 1 year ago

請問可以參考下你的角色描述怎麼寫的嗎

你看看自带 roleplay 插件里的猫娘,我想到会话格式其实也是顺着那个角色描述的思路,相关内容大概这样:

你的回话格式是「语言」+「动作」+ %情感%,比如「两凤(超开心)%愉快%」。动作包含你的动作或表情,用全角括号括起来,例如(摇尾巴)或(超开心);语言就是你要说的话,不用处理。%情感%就是你对话时的情感,放在%之间,只有以下七种:「%无语%、%惊讶%、%难过%、%愉快%、%疑惑%、%安慰%、%害羞%」,若都不符合则不说出%情感%。

那个「两凤」是乱打的不会在任何情况出现的无意义文本,我之前举例用「你好(超开心)」,结果GPT 3.5打招呼经常直接就复用「你好(超开心)」,所以这么处理……

好的,感谢分享

qjsir commented 12 months ago

請問可以參考下你的角色描述怎麼寫的嗎

你看看自带 roleplay 插件里的猫娘,我想到会话格式其实也是顺着那个角色描述的思路,相关内容大概这样:

你的回话格式是「语言」+「动作」+ %情感%,比如「两凤(超开心)%愉快%」。动作包含你的动作或表情,用全角括号括起来,例如(摇尾巴)或(超开心);语言就是你要说的话,不用处理。%情感%就是你对话时的情感,放在%之间,只有以下七种:「%无语%、%惊讶%、%难过%、%愉快%、%疑惑%、%安慰%、%害羞%」,若都不符合则不说出%情感%。

那个「两凤」是乱打的不会在任何情况出现的无意义文本,我之前举例用「你好(超开心)」,结果GPT 3.5打招呼经常直接就复用「你好(超开心)」,所以这么处理……

好的,感谢分享

请问在复制代码到文件后抱错了怎么回事呢 ![Uploading Screenshot_20231128_114418_com.tencent.mm.jpg…]()

qjsir commented 12 months ago

Screenshot_20231128_114418_com tencent mm

Namarimizu commented 12 months ago

if keyword in msg: mood = emotion msg = msg.replace(keyword, "") i = random.randint(0, 1) print(i)

您把

               if keyword in msg:
                   mood = emotion
                   msg = msg.replace(keyword, "")
                   i = random.randint(0, 1)
                   print(i)

的最后两行去掉,以及 random.seed(time.time())

去掉,再把

  if mood and i == 1 and sticker_sent == 0:

改成 if mood == 1 and sticker_sent == 0: 试试?

Namarimizu commented 10 months ago

突然想到可以用用斗图api来选表情,缺点是那些表情画风不是很统一,会出戏……

huihuihenqiang commented 6 months ago

大佬,根据你的代码整理了一下。并且修复了一下。做成了仓库https://github.com/huihuihenqiang/wechat-simulate-human