mirror of
https://github.com/zhayujie/bot-on-anything.git
synced 2026-03-03 00:24:53 +08:00
25
README.md
25
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`: 对话内指令,主动清空前文记忆,字符串数组可自定义指令别名。
|
||||
|
||||
@@ -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()
|
||||
|
||||
93
channel/wechat/wechat_com_channel.py
Normal file
93
channel/wechat/wechat_com_channel.py
Normal 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'
|
||||
@@ -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"
|
||||
|
||||
@@ -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"],
|
||||
|
||||
Reference in New Issue
Block a user