From c3a92b12b4c15089ecc38c0eab1ab30d60db8029 Mon Sep 17 00:00:00 2001 From: gateray Date: Mon, 9 Oct 2017 23:34:58 +0800 Subject: [PATCH] fixed --- README.md | 164 ++++++++++++-------------------------- local_settings.py.example | 2 + models.py | 6 +- 3 files changed, 56 insertions(+), 116 deletions(-) diff --git a/README.md b/README.md index 5607791..f754a34 100644 --- a/README.md +++ b/README.md @@ -1,226 +1,162 @@ -#概述 +# 概述 ->msg-sender是一个基于tornado框架的异步消息发送接口,当前支持消息发送微信企业号、玄武短信接口和Email; 接口调用支持http和websocket。遵循MIT开源许可。 +> msg-sender是一个基于tornado框架的异步消息发送接口,当前支持消息发送微信企业号、玄武短信接口和Email; 接口调用支持http和websocket。遵循MIT开源许可。 -#接口调用方式 +# 接口调用方式 -##微信企业号消息发送接口 +## 微信企业号消息发送接口 关闭签名: -字段名|字段类型|是否必须|描述 - ----------|------------|------------|------ - -title|String|是|消息的标题 - -content|String|是|消息的内容 +字段名 | 字段类型 | 是否必须 | 描述 +-----------|-----------|-----------|----------- +title | String | 是 | 消息的标题 +content | String | 是 | 消息的内容 ``` - POST http://host:8000/qywx?content=abc&title=接口测试 - ``` 开启签名: -字段名|字段类型|是否必须|描述 - ----------|------------|------------|------ - -title|String|是|消息的标题 - -content|String|是|消息的内容 +字段名 | 字段类型 | 是否必须 | 描述 -timestamp|Integer|是|unix时间戳(当前时间,10位数字) - -signature|String|是|16进制格式的签名值,支持md5、sha1、sha128、sha224、 sha256、 sha384、 sha512签名方法,默认为sha256。 +-----------|-----------|-----------|----------- +title | String | 是 | 消息的标题 +content | String | 是 | 消息的内容 +timestamp | Integer | 是 | unix时间戳(当前时间,10位数字) +signature | String | 是 | 16进制格式的签名值,支持md5、sha1、sha128、sha224、 sha256、 sha384、 sha512签名方法,默认为sha256。 签名说明: -1)将所有字段按key自然排序后,拼接key-value得到字符串A +* 将所有字段按key自然排序后,拼接key-value得到字符串A -2)字符串A后拼接上apiKey,得到字符串B +* 字符串A后拼接上apiKey,得到字符串B -3)字符串B进行签名,输出的16进制字符串为signature字段的值 +* 字符串B进行签名,输出的16进制字符串为signature字段的值 示例: -> 1)假设title=test&content=test消息内容×tamp=1507545674, apiKey=mysecret +* 假设title=test&content=test消息内容×tamp=1507545674, apiKey=mysecret -> 2)按key自然排序的结果为:content=test消息内容×tamp=1507545674&title=test +* 按key自然排序的结果为:content=test消息内容×tamp=1507545674&title=test -> 3)拼接后得到字符串:contenttest消息内容timestamp1507545674titletest +* 拼接后得到字符串:contenttest消息内容timestamp1507545674titletest -> 4)拼接上apiKey得到的字符串:contenttest消息内容timestamp1507545674titletestmysecret +* 拼接上apiKey得到的字符串:contenttest消息内容timestamp1507545674titletestmysecret -> 5)上一步得到的字符串进行sha256签名,得到签名:28924486d2aaf886565736a50e61bb9fb0d3baf613e2333b0e497934699ec15b +* 上一步得到的字符串进行sha256签名,得到签名:28924486d2aaf886565736a50e61bb9fb0d3baf613e2333b0e497934699ec15b ``` - POST http://host:8000/qywx?title=test&content=test消息内容×tamp=1507545674&signature=28924486d2aaf886565736a50e61bb9fb0d3baf613e2333b0e497934699ec15b - ``` > 签名有效期为1分钟 - - -##玄武短信消息发送接口 +## 玄武短信消息发送接口 关闭签名: -字段名|字段类型|是否必须|描述 - ----------|------------|------------|------ - -title|String|是|消息的标题 - -content|String|是|消息的内容 +字段名 | 字段类型 | 是否必须 | 描述 +----------|--------------|--------------|------- +title | String | 是 | 消息的标题 +content | String | 是 | 消息的内容 ``` - POST http://host:8000/sms?content=这是一条测试短信&title=标题会忽略 - ``` 开启签名: 规则与上面微信企业号方式相同 - - -##Email消息发送接口 +## Email消息发送接口 关闭签名: -字段名|字段类型|是否必须|描述 - ----------|------------|------------|------ - -title|String|是|消息的标题 - -content|String|是|消息的内容 +字段名 | 字段类型 | 是否必须 | 描述 +----------|-------------|--------------|------- +title | String | 是 | 消息的标题 +content | String | 是 | 消息的内容 ``` - POST http://host:8000/mail?content=这是一封测试邮件,请勿回复!&title=接口测试 - ``` 开启签名: 规则与上面微信企业号方式相同 +# 部署 +## 环境要求 -#部署 - -##环境要求 - -1. python 3.5以上 - -2. redis 2.8以上(可选,使用微信企业号发送消息时需要使用) +* python 3.5以上 -3.推荐linux环境下运行 +* redis 2.8以上(可选,使用微信企业号发送消息时需要使用) +* 推荐linux环境下运行 - -##依赖安装 +## 依赖安装 ``` - -git clone https://gitee.com/gateray/msg-sender.git - +git clone https://github.com/gateray/msg-sender.git cd msg-sender - pip install -r requirements.txt - ``` +## 运行 - -##运行 - -###测试环境 +### 测试环境 ``` - -cd msg-sender - cp local_settings.py.example local_settings.py - python app.py --port=8000 - ``` - - -###生产环境部署建议 +### 生产环境部署建议 建议使用nginx作为反向代理,后端开启多个python进程(建议与cpu核数相等)做负载均衡。 -####打开最多文件数限制: +#### 打开最多文件数限制: 方式一: ``` - ulimit -n 1048576 - ``` 方式二: ``` - vim /etc/security/limits.conf - -#加上下面配置: - +# 加上下面配置: * - nofile 1048576 - ``` 方式三(systemd): ``` - 在对应服务的service文件中添加,例如: - vim /lib/systemd/system/nginx.service - - [Service] - User=gateray - Group=gateray - LimitNOFILE= 1048576 - -#实际上对于nginx,可以通过配置文件中 worker_connections 1048576;指定 - +# 实际上对于nginx,可以通过配置文件中 worker_connections 1048576;指定 ``` - - -####开启多个python进程: +#### 开启多个python进程: ``` - for i in {8001..8008}; do - nohup python app.py --port=800$i &> /tmp/msg-sender-800$i.log & - done - ``` 强烈推荐使用supervisor去管理进程,以下是一个示例: ``` - ➜ msg-sender git:(master) ✗ cat /etc/supervisord.conf.d/msg-sender.conf [program:msg-sender-8001] @@ -287,7 +223,7 @@ stdout_logfile=/tmp/%(program_name)s.log ; stdout log path, NONE for none; ``` -####nginx配置: +#### nginx配置: ``` @@ -365,7 +301,7 @@ http { ``` -#本地压测结果: +# 本地压测结果: ``` @@ -487,8 +423,8 @@ Percentage of the requests served within a certain time (ms) -#联系方式 +# 联系方式 QQ:437925289 -Email:437925289@qq.com \ No newline at end of file +Email:437925289@qq.com diff --git a/local_settings.py.example b/local_settings.py.example index 550b138..5f31132 100644 --- a/local_settings.py.example +++ b/local_settings.py.example @@ -25,6 +25,8 @@ qywx = { "corpid": "wx17000000000000", #根据自己的企业号修改 "corpsecret": "xxxxxxxxxxxxxxxxxxxx", #根据自己的企业号修改 "agentid": "00000000", #根据自己的企业号修改 + "toUser": "@all", #设置接收消息的userid,@all表示所有用户,多个用户使用‘|’分隔 + "toParty": "@all", #设置接收消息的部门id,@all表示所有部门,多个部门使用‘|’分隔 "timeout": 5, #设置调用超时时间 } #使用邮件发送消息时启用 diff --git a/models.py b/models.py index e90d24b..d179f45 100644 --- a/models.py +++ b/models.py @@ -41,6 +41,8 @@ def __init__(self, redisConn, title="", content="", **qywxSettings): self.corpid = qywxSettings.get("corpid") self.corpsecret = qywxSettings.get("corpsecret") self.agentid = qywxSettings.get("agentid") + self.toUser = qywxSettings.get("toUser") + self.toParty = qywxSettings.get("toParty") self.timeout = qywxSettings.get("timeout") self.__redis = redisConn @@ -85,8 +87,8 @@ def send(self): accessToken = yield self.getAccessToken() if len(accessToken) == 0: return None body = { - "touser": "gateray", - "toparty": "", + "touser": self.toUser, + "toparty": self.toParty, "totag": "", "msgtype": "text", "agentid": self.agentid,