From 0d1b7aa1d44d750d5f900c831dccfa8a40b61d44 Mon Sep 17 00:00:00 2001 From: ffwen123 Date: Mon, 10 Apr 2023 22:38:56 +0800 Subject: [PATCH 1/3] ceshi --- channel/channel_factory.py | 4 ++ channel/wechat/wechat_com_channel.py | 94 ++++++++++++++++++++++++++++ common/const.py | 1 + config-template.json | 7 +++ 4 files changed, 106 insertions(+) create mode 100644 channel/wechat/wechat_com_channel.py diff --git a/channel/channel_factory.py b/channel/channel_factory.py index 1346499..320fa3a 100644 --- a/channel/channel_factory.py +++ b/channel/channel_factory.py @@ -25,6 +25,10 @@ def create_channel(channel_type): from channel.wechat.wechat_mp_service_channel import WechatServiceAccount return WechatServiceAccount() + elif channel_type == const.WECHAT_COM: + from channel.wechat.wechat_com_channel import WechatEnterpriseChannel + return WechatEnterpriseChannel() + elif channel_type == const.QQ: from channel.qq.qq_channel import QQChannel return QQChannel() diff --git a/channel/wechat/wechat_com_channel.py b/channel/wechat/wechat_com_channel.py new file mode 100644 index 0000000..a37ae25 --- /dev/null +++ b/channel/wechat/wechat_com_channel.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding=utf-8 -*- +""" +@time: 2023/4/10 22:24 +@Project :bot-on-anything +@file: wechat_com_channel.py + +""" +from channel.channel import Channel +from concurrent.futures import ThreadPoolExecutor +from common.log import logger +from config import conf + +from wechatpy.enterprise.crypto import WeChatCrypto +from wechatpy.enterprise import WeChatClient +from wechatpy.exceptions import InvalidSignatureException +from wechatpy.enterprise.exceptions import InvalidCorpIdException +from wechatpy.enterprise import parse_message +from flask import Flask, request, abort + +thread_pool = ThreadPoolExecutor(max_workers=8) +app = Flask(__name__) + + +@app.route('/wechat', methods=['GET', 'POST']) +def handler_msg(): + return WechatEnterpriseChannel().handle() + + +_conf = conf().get("wechat_com") + + +class WechatEnterpriseChannel(Channel): + def __init__(self): + self.CorpId = _conf.get('wechat_corp_id') + self.Secret = _conf.get('secret') + self.AppId = _conf.get('appid') + self.TOKEN = _conf.get('wechat_token') + self.EncodingAESKey = _conf.get('wechat_encoding_aes_key') + self.crypto = WeChatCrypto(self.TOKEN, self.EncodingAESKey, self.CorpId) + self.client = WeChatClient(self.CorpId, self.Secret, self.AppId) + + def startup(self): + # start message listener + app.run(host='0.0.0.0', port=8888) + + def send(self, msg, receiver): + logger.info('[WXCOM] sendMsg={}, receiver={}'.format(msg, receiver)) + self.client.message.send_text(self.AppId, receiver, msg) + + def _do_send(self, query, reply_user_id): + try: + if not query: + return + context = dict() + context['from_user_id'] = reply_user_id + reply_text = super().build_reply_content(query, context) + if reply_text: + self.send(reply_text, reply_user_id) + except Exception as e: + logger.exception(e) + + def handle(self): + query_params = request.args + signature = query_params.get('msg_signature', '') + timestamp = query_params.get('timestamp', '') + nonce = query_params.get('nonce', '') + if request.method == 'GET': + # 处理验证请求 + echostr = query_params.get('echostr', '') + try: + echostr = self.crypto.check_signature(signature, timestamp, nonce, echostr) + except InvalidSignatureException: + abort(403) + print(echostr) + return echostr + elif request.method == 'POST': + try: + message = self.crypto.decrypt_message( + request.data, + signature, + timestamp, + nonce + ) + except (InvalidSignatureException, InvalidCorpIdException): + abort(403) + msg = parse_message(message) + if msg.type == 'text': + reply = '收到,思考中...' + thread_pool.submit(self._do_send, msg.content, msg.source) + else: + reply = 'Can not handle this for now' + self.client.message.send_text(self.AppId, msg.source, reply) + return 'success' diff --git a/common/const.py b/common/const.py index bd28a5c..e0fa6e8 100644 --- a/common/const.py +++ b/common/const.py @@ -3,6 +3,7 @@ TERMINAL = "terminal" WECHAT = "wechat" WECHAT_MP = "wechat_mp" WECHAT_MP_SERVICE = "wechat_mp_service" +WECHAT_COM = "wechat_com" QQ = "qq" GMAIL = "gmail" TELEGRAM = "telegram" diff --git a/config-template.json b/config-template.json index 8b61dc2..d02addd 100644 --- a/config-template.json +++ b/config-template.json @@ -45,6 +45,13 @@ "token": "YOUR TOKEN", "port": "80" }, + "wechat_com": { + "wechat_token": "6a7948ff36d8", + "wechat_encoding_aes_key":"jMQA7bDP4u52dILb1W6IGib5c1FooFrHJpEuTczQQeT", + "wechat_corp_id":"ww288c216b922e23a1", + "appid":"1000002", + "secret":"UMPISp6qiaKheLdv1src9nNaKsCWSKE_-5ujU_l2QdY" + }, "gmail": { "subject_keyword": ["bot", "@bot"], From 184744df9ba39b9a76522a4aee7b01b431383380 Mon Sep 17 00:00:00 2001 From: ffwen123 Date: Mon, 10 Apr 2023 22:40:57 +0800 Subject: [PATCH 2/3] ceshi --- config-template.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config-template.json b/config-template.json index d02addd..28cc068 100644 --- a/config-template.json +++ b/config-template.json @@ -46,11 +46,11 @@ "port": "80" }, "wechat_com": { - "wechat_token": "6a7948ff36d8", - "wechat_encoding_aes_key":"jMQA7bDP4u52dILb1W6IGib5c1FooFrHJpEuTczQQeT", - "wechat_corp_id":"ww288c216b922e23a1", - "appid":"1000002", - "secret":"UMPISp6qiaKheLdv1src9nNaKsCWSKE_-5ujU_l2QdY" + "wechat_token": "", + "wechat_encoding_aes_key":"", + "wechat_corp_id":"", + "appid":"", + "secret":"" }, "gmail": { From f0de76b190a3948e5d05683a4e0b9bd11ac206f6 Mon Sep 17 00:00:00 2001 From: ffwen123 Date: Mon, 10 Apr 2023 23:41:41 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1wechatc?= =?UTF-8?q?om?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 25 ++++++++++++++++++++++++- channel/wechat/wechat_com_channel.py | 7 +++---- config-template.json | 11 ++++++----- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 696c84a..70f696d 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ - [x] [个人微信](https://github.com/zhayujie/bot-on-anything#2%E4%B8%AA%E4%BA%BA%E5%BE%AE%E4%BF%A1) - [x] [订阅号](https://github.com/zhayujie/bot-on-anything#3%E4%B8%AA%E4%BA%BA%E8%AE%A2%E9%98%85%E5%8F%B7) - [x] [服务号](https://github.com/zhayujie/bot-on-anything#4%E4%BC%81%E4%B8%9A%E6%9C%8D%E5%8A%A1%E5%8F%B7) - - [ ] 企业微信 + - [x] 企业微信 - [x] [Telegram](https://github.com/zhayujie/bot-on-anything#6telegram) - [x] [QQ](https://github.com/zhayujie/bot-on-anything#5qq) - [x] [钉钉](https://github.com/zhayujie/bot-on-anything#10%E9%92%89%E9%92%89) @@ -590,6 +590,29 @@ pip3 install requests flask 3. 订阅菜单添加事件(接收消息v2.0) 配置请求地址(配置中的对外地址如 https://xx.xx.com:8081) 4. 版本管理与发布中上架应用,app中会收到审核信息,通过审核后在群里添加自建应用 +### 12.企业微信 + +**需要:** 一个服务器、一个已认证的企业微信。 + +企业微信的 `config.json` 配置只需修改type为`wechat_com`,默认接收消息服务器URL:http://ip:8888/wechat + +```bash +"channel": { + "type": "wechat_com", + + "wechat_mp": { + "wechat_token": "YOUR TOKEN", # token值 + "port": "8888", # 程序启动监听的端口 + "app_id": "YOUR APP ID", # app ID + "app_secret": "YOUR APP SECRET" # app secret + "wechat_corp_id": "YOUR CORP ID" + "wechat_encoding_aes_key": "YOUR AES KEY" + } +} +``` + +注意:需将服务器ip地址配置在 "企业可信IP" 内,否则用户将收不到主动推送的消息。 + ### 通用配置 + `clear_memory_commands`: 对话内指令,主动清空前文记忆,字符串数组可自定义指令别名。 diff --git a/channel/wechat/wechat_com_channel.py b/channel/wechat/wechat_com_channel.py index a37ae25..17e5e4a 100644 --- a/channel/wechat/wechat_com_channel.py +++ b/channel/wechat/wechat_com_channel.py @@ -27,7 +27,7 @@ def handler_msg(): return WechatEnterpriseChannel().handle() -_conf = conf().get("wechat_com") +_conf = conf().get("channel").get("wechat_com") class WechatEnterpriseChannel(Channel): @@ -42,7 +42,7 @@ class WechatEnterpriseChannel(Channel): def startup(self): # start message listener - app.run(host='0.0.0.0', port=8888) + app.run(host='0.0.0.0', port=_conf.get('port')) def send(self, msg, receiver): logger.info('[WXCOM] sendMsg={}, receiver={}'.format(msg, receiver)) @@ -86,9 +86,8 @@ class WechatEnterpriseChannel(Channel): abort(403) msg = parse_message(message) if msg.type == 'text': - reply = '收到,思考中...' thread_pool.submit(self._do_send, msg.content, msg.source) else: reply = 'Can not handle this for now' - self.client.message.send_text(self.AppId, msg.source, reply) + self.client.message.send_text(self.AppId, msg.source, reply) return 'success' diff --git a/config-template.json b/config-template.json index 28cc068..099d9e2 100644 --- a/config-template.json +++ b/config-template.json @@ -46,11 +46,12 @@ "port": "80" }, "wechat_com": { - "wechat_token": "", - "wechat_encoding_aes_key":"", - "wechat_corp_id":"", - "appid":"", - "secret":"" + "wechat_token": "", + "wechat_encoding_aes_key":"", + "wechat_corp_id":"", + "appid":"", + "secret":"", + "port": "8888" }, "gmail": {