Merge pull request #292 from ffwen123/master

add wechat_com_channel
This commit is contained in:
zhayujie
2023-04-11 00:27:09 +08:00
committed by GitHub
5 changed files with 130 additions and 1 deletions

View File

@@ -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`默认接收消息服务器URLhttp://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`: 对话内指令,主动清空前文记忆,字符串数组可自定义指令别名。

View File

@@ -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()

View File

@@ -0,0 +1,93 @@
#!/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("channel").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=_conf.get('port'))
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':
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'

View File

@@ -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"

View File

@@ -45,6 +45,14 @@
"token": "YOUR TOKEN",
"port": "80"
},
"wechat_com": {
"wechat_token": "",
"wechat_encoding_aes_key":"",
"wechat_corp_id":"",
"appid":"",
"secret":"",
"port": "8888"
},
"gmail": {
"subject_keyword": ["bot", "@bot"],