Skip to content

Commit

Permalink
Merge pull request #9 from tudou2/master
Browse files Browse the repository at this point in the history
update0418
  • Loading branch information
congxuma committed Apr 18, 2023
2 parents 76a0b8a + 86caf6d commit e13dbc6
Show file tree
Hide file tree
Showing 15 changed files with 165 additions and 14 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ plugins/**/
!plugins/banwords
!plugins/banwords/**/
!plugins/hello
!plugins/role
!plugins/role
!plugins/keyword
2 changes: 1 addition & 1 deletion bot/chatgpt/chat_gpt_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def reply_text(self, session: ChatGPTSession, api_key=None, retry_count=0) -> di
logger.warn("[CHATGPT] RateLimitError: {}".format(e))
result["content"] = "提问太快啦,请休息一下再问我吧"
if need_retry:
time.sleep(5)
time.sleep(20)
elif isinstance(e, openai.error.Timeout):
logger.warn("[CHATGPT] Timeout: {}".format(e))
result["content"] = "我没有收到你的消息"
Expand Down
2 changes: 1 addition & 1 deletion bot/openai/open_ai_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def reply_text(self, session: OpenAISession, retry_count=0):
logger.warn("[OPEN_AI] RateLimitError: {}".format(e))
result["content"] = "提问太快啦,请休息一下再问我吧"
if need_retry:
time.sleep(5)
time.sleep(20)
elif isinstance(e, openai.error.Timeout):
logger.warn("[OPEN_AI] Timeout: {}".format(e))
result["content"] = "我没有收到你的消息"
Expand Down
1 change: 1 addition & 0 deletions bridge/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class ContextType(Enum):
VOICE = 2 # 音频消息
IMAGE = 3 # 图片消息
IMAGE_CREATE = 10 # 创建图片命令
JOIN_GROUP = 20 # 加入群聊

def __str__(self):
return self.name
Expand Down
19 changes: 13 additions & 6 deletions channel/wechat/wechat_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,23 @@

@itchat.msg_register([TEXT, VOICE, PICTURE])
def handler_single_msg(msg):
# logger.debug("handler_single_msg: {}".format(msg))
if msg["Type"] == PICTURE and msg["MsgType"] == 47:
try:
cmsg = WeChatMessage(msg, False)
except NotImplementedError as e:
logger.debug("[WX]single message {} skipped: {}".format(msg["MsgId"], e))
return None
WechatChannel().handle_single(WeChatMessage(msg))
WechatChannel().handle_single(cmsg)
return None


@itchat.msg_register([TEXT, VOICE, PICTURE], isGroupChat=True)
@itchat.msg_register([TEXT, VOICE, PICTURE, NOTE], isGroupChat=True)
def handler_group_msg(msg):
if msg["Type"] == PICTURE and msg["MsgType"] == 47:
try:
cmsg = WeChatMessage(msg, True)
except NotImplementedError as e:
logger.debug("[WX]group message {} skipped: {}".format(msg["MsgId"], e))
return None
WechatChannel().handle_group(WeChatMessage(msg, True))
WechatChannel().handle_group(cmsg)
return None


Expand Down Expand Up @@ -186,6 +191,8 @@ def handle_group(self, cmsg: ChatMessage):
logger.debug("[WX]receive voice for group msg: {}".format(cmsg.content))
elif cmsg.ctype == ContextType.IMAGE:
logger.debug("[WX]receive image for group msg: {}".format(cmsg.content))
elif cmsg.ctype == ContextType.JOIN_GROUP:
logger.debug("[WX]receive join group msg: {}".format(cmsg.content))
else:
# logger.debug("[WX]receive group msg: {}, cmsg={}".format(json.dumps(cmsg._rawmsg, ensure_ascii=False), cmsg))
pass
Expand Down
29 changes: 27 additions & 2 deletions channel/wechat/wechat_message.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import re

from bridge.context import ContextType
from channel.chat_message import ChatMessage
from common.log import logger
Expand All @@ -24,9 +26,31 @@ def __init__(self, itchat_msg, is_group=False):
self.ctype = ContextType.IMAGE
self.content = TmpDir().path() + itchat_msg["FileName"] # content直接存临时目录路径
self._prepare_fn = lambda: itchat_msg.download(self.content)
elif itchat_msg["Type"] == NOTE and itchat_msg["MsgType"] == 10000:
if is_group and (
"加入群聊" in itchat_msg["Content"] or "加入了群聊" in itchat_msg["Content"]
):
self.ctype = ContextType.JOIN_GROUP
logger.debug("[WX]join group message: " + itchat_msg["Content"])
self.content = itchat_msg["Content"]
# 这里只能得到nickname, actual_user_id还是机器人的id
if "加入了群聊" in itchat_msg["Content"]:
self.actual_user_nickname = re.findall(
r"\"(.*?)\"", itchat_msg["Content"]
)[-1]
elif "加入群聊" in itchat_msg["Content"]:
self.actual_user_nickname = re.findall(
r"\"(.*?)\"", itchat_msg["Content"]
)[0]
else:
raise NotImplementedError(
"Unsupported note message: " + itchat_msg["Content"]
)
else:
raise NotImplementedError(
"Unsupported message type: {}".format(itchat_msg["Type"])
"Unsupported message type: Type:{} MsgType:{}".format(
itchat_msg["Type"], itchat_msg["MsgType"]
)
)

self.from_user_id = itchat_msg["FromUserName"]
Expand Down Expand Up @@ -58,4 +82,5 @@ def __init__(self, itchat_msg, is_group=False):
if self.is_group:
self.is_at = itchat_msg["IsAt"]
self.actual_user_id = itchat_msg["ActualUserName"]
self.actual_user_nickname = itchat_msg["ActualNickName"]
if self.ctype != ContextType.JOIN_GROUP:
self.actual_user_nickname = itchat_msg["ActualNickName"]
2 changes: 1 addition & 1 deletion plugins/banwords/banwords.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,4 @@ def on_decorate_reply(self, e_context: EventContext):
return

def get_help_text(self, **kwargs):
return Banwords.desc
return "过滤消息中的敏感词。"
11 changes: 10 additions & 1 deletion plugins/hello/hello.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,16 @@ def __init__(self):
logger.info("[Hello] inited")

def on_handle_context(self, e_context: EventContext):
if e_context["context"].type != ContextType.TEXT:
if e_context["context"].type not in [ContextType.TEXT, ContextType.JOIN_GROUP]:
return

if e_context["context"].type == ContextType.JOIN_GROUP:
e_context["context"].type = ContextType.TEXT
msg: ChatMessage = e_context["context"]["msg"]
e_context[
"context"
].content = f'请你随机使用一种风格说一句问候语来欢迎新用户"{msg.actual_user_nickname}"加入群聊。'
e_context.action = EventAction.CONTINUE # 事件继续,交付给下个插件或默认逻辑
return

content = e_context["context"].content
Expand Down
13 changes: 13 additions & 0 deletions plugins/keyword/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# 目的
关键字匹配并回复

# 试用场景
目前是在微信公众号下面使用过。

# 使用步骤
1. 复制 `config.json.template``config.json`
2. 在关键字 `keyword` 新增需要关键字匹配的内容
3. 重启程序做验证

# 验证结果
![结果](test-keyword.png)
1 change: 1 addition & 0 deletions plugins/keyword/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .keyword import *
5 changes: 5 additions & 0 deletions plugins/keyword/config.json.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"keyword": {
"关键字匹配": "测试成功"
}
}
67 changes: 67 additions & 0 deletions plugins/keyword/keyword.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# encoding:utf-8

import json
import os

import plugins
from bridge.context import ContextType
from bridge.reply import Reply, ReplyType
from common.log import logger
from plugins import *


@plugins.register(
name="Keyword",
desire_priority=900,
hidden=True,
desc="关键词匹配过滤",
version="0.1",
author="fengyege.top",
)
class Keyword(Plugin):
def __init__(self):
super().__init__()
try:
curdir = os.path.dirname(__file__)
config_path = os.path.join(curdir, "config.json")
conf = None
if not os.path.exists(config_path):
logger.debug(f"[keyword]不存在配置文件{config_path}")
conf = {"keyword": {}}
with open(config_path, "w", encoding="utf-8") as f:
json.dump(conf, f, indent=4)
else:
logger.debug(f"[keyword]加载配置文件{config_path}")
with open(config_path, "r", encoding="utf-8") as f:
conf = json.load(f)
# 加载关键词
self.keyword = conf["keyword"]

logger.info("[keyword] {}".format(self.keyword))
self.handlers[Event.ON_HANDLE_CONTEXT] = self.on_handle_context
logger.info("[keyword] inited.")
except Exception as e:
logger.warn(
"[keyword] init failed, ignore or see https://github.com/zhayujie/chatgpt-on-wechat/tree/master/plugins/keyword ."
)
raise e

def on_handle_context(self, e_context: EventContext):
if e_context["context"].type != ContextType.TEXT:
return

content = e_context["context"].content.strip()
logger.debug("[keyword] on_handle_context. content: %s" % content)
if content in self.keyword:
logger.debug(f"[keyword] 匹配到关键字【{content}】")
reply_text = self.keyword[content]

reply = Reply()
reply.type = ReplyType.TEXT
reply.content = reply_text
e_context["reply"] = reply
e_context.action = EventAction.BREAK_PASS # 事件结束,并跳过处理context的默认逻辑

def get_help_text(self, **kwargs):
help_text = "关键词过滤"
return help_text
Binary file added plugins/keyword/test-keyword.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 22 additions & 1 deletion plugins/plugin_getnews/getnews.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ def on_handle_context(self, e_context: EventContext):
getnews_api_token = "UDuxUGXTKAlCJ3qt"
content = e_context['context'].content
logger.debug("[getnews] on_handle_context. content: %s" % content)

help_info = "\n【请注意尽量不要询问涉及个人隐私和敏感问题哦!】 \
\n\n使用技巧 \
\n\n0、直接输入可进行对话,支持1000字上下文联系,输入#help 获取帮助 \
\n\n1、输入内容中含‘每日新闻’可获取当日新闻;含‘每日摄影’可获取每日的一张摄影作品 \
\n\n2、关键字画开头将触发画图,目前需要以特殊的格式输入【画 <模型>:prompt】如:画journey:1cat,big eyes,garden \
\n\n3、输入‘画修复’可触发修复人像功能,会提示上传一张照片"

if re.search(r"每日新闻|getnews|今日新闻|今天有什么新闻", content):
reply = Reply()
Expand All @@ -47,7 +54,21 @@ def on_handle_context(self, e_context: EventContext):

e_context['reply'] = reply
e_context.action = EventAction.BREAK_PASS # 事件结束,并跳过处理context的默认逻辑


if re.match(r"我是.*", content):
reply = Reply()
reply.type = ReplyType.TEXT

msg: ChatMessage = e_context["context"]["msg"]
if e_context["context"]["isgroup"]:
reply.content = (
f"Hello, {msg.actual_user_nickname} from {msg.from_user_nickname} \n" + help_info
)
else:
reply.content = f"Hello, {msg.from_user_nickname} \n" + help_info
e_context["reply"] = reply
e_context.action = EventAction.BREAK_PASS # 事件结束,并跳过处理context的默认逻辑

if re.search(r"每日图片|getimg|今日摄影|每日摄影", content):
reply = Reply()
reply.type = ReplyType.IMAGE_URL
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ replicate>=0.7.0
lxml==4.9.2
pre-commit
webdriver_manager
selenium==2.48.0

0 comments on commit e13dbc6

Please sign in to comment.