# message-bridge
**Repository Path**: xiaobowen-hz/message-bridge
## Basic Information
- **Project Name**: message-bridge
- **Description**: 轻量级的消息封装服务,旨在简化钉钉、微信和短信等多平台消息的接入与发送;适用于需要快速接入钉钉、微信或短信通知的应用或者多平台消息推送的集成需求
- **Primary Language**: Python
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-04-23
- **Last Updated**: 2025-04-29
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Redis, minio, dysmsapi, dingTalk
## README
# message-bridge
#### 介绍
通知扩展服务,目前接入了钉钉消息和阿里短信等消息通知;为了支持展示消息图片,本服务还接入了 _Minio_ 作为文件服务器,_Minio_ 的文件服务默认未启用
#### 环境搭建
1. 安装 _Python_ 解释器,本程序基于 v3.9.8 构建(略...)
2. 安装包管理工具`pip`,新版的 _Python_ 版本已经预装了`pip`,可通过以下指令查看是否已经安装
```
pip --version
```
3. 安装并配置 _Minio_ 服务,*如果启用*
4. 安装并配置 _Redis_ 服务,*如果启用缓存数据*;可缓解钉钉等第三方API的频率限制。
5. 钉钉消息环境准备,你需要先了解钉钉怎样通过机器人去发送群消息
详情流程请查看[官网](https://open.dingtalk.com/document/orgapp/robot-overview)
- 创建企业内部应用
- 创建企业内部应用机器人并发布
- 在企业内部应用中给机器人相关的授权
- 在企业内部的通知群聊中添加以上发布的机器人
6. 阿里短信通知环境准备,你需要先了解阿里的短信服务
- 开通阿里短信服务
- 添加资质
- 申请短信签名
- 申请短信模板
7. 下载项目中用到的所有依赖库,在项目的根目录执行以下指令:
```
pip install -r ./requirements.txt --ignore-installed
```
#### 使用说明
1. 修改配置文件 *static/conf/application.yaml* 中的参数为你的真实信息
- 核心配置,以下配置为空则使用默认值
```
server.host = "0.0.0.0"
server.port = 4000
```
- 候补配置,可以从调用方通过 `context` 传递核心配置;如果调用方不传递,并且本服务已经启用配置填充则使用以下配置
```
server.enable_fill = on
sms.endpoint = "dysmsapi.aliyuncs.com"
sms.sign_name = "阿里云短信测试"
sms.phone_numbers = ["13578965423","16896357486"]
ding.open_conversation_id = "***"
ding.app_key = "***"
ding.app_secret = "***"
ding.robot_code = "***"
```
从如下位置获取钉钉应用信息 `app_key` 和 `app_secret`:

获取企业 `CorpId` 请登录[钉钉开发者后台](https://open-dev.dingtalk.com/?spm=dd_developers.header.unLogin.openDevBtn&hash=%23%2F)
已获取 `CorpId` 后,有关群会话 `DING_OPEN_CONVERSATION_ID` 你可以通过钉钉官方提供的途径来获取:
- [调试路径1](https://open.dingtalk.com/tools/explorer/jsapi?id=10303)
- [调试路径2](https://open-dev.dingtalk.com/apiExplorer?spm=ding_open_doc.document.0.0.87ca4a979GVvgo#/jsapi?api=biz.chat.chooseConversationByCorpId)
除以上配置外,你还需要额外配置系统变量 `ALIBABA_CLOUD_ACCESS_KEY_ID` 和 `ALIBABA_CLOUD_ACCESS_KEY_SECRET`,这两个是你
阿里账号的访问密钥。另外,接收短信的手机号码也可以在系统中配置变量 `ALIBABA_CLOUD_PHONE_NUMBERS`,多个号码用逗号连接,但是系统中配置的优先级低于配置文件
- 可选配置,如果启用 _Minio_ 文件服务,必须配置以下配置项
```
server.enable_minio = on
minio.endpoint = "***"
minio.access_key = "***"
minio.secret_key = "***"
```
- 可选配置,本程序已经实现 _Redis_ 作为缓存服务器,如果启用缓存,必须配置以下配置项;如果未配置参数,默认走本地服务的默认用户连接
```
server.enable_cache = on
redis.host = "localhost"
redis.port = 6379
redis.user_name = "default"
redis.pass_word = ""
```
2. 运行main.py文件中的主函数
#### 开发指南
1. 开发人员如果更新了项目,请及时在项目的根目录使用以下指令导出当前项目的最新环境依赖!*注意,要清空build目录下的所有资源再执行*,否则会导致导出的依赖为空。
```cmd
pipreqs ./ --encoding=utf-8 --force
```
如果无法使用,请先安装`pipreqs`工具:
```cmd
pip install pipreqs
```
#### 打包成系统可执行程序
1. 清理环境依赖。如果你对环境中的依赖有信心,可以直接从第二步开始执行;但如果在最后打包时出现迭代深度超出限制,请回到这里重新开始
- 卸载所有已安装的包,执行以下指令:
```
pip freeze > overall.txt
pip uninstall -r overall.txt -y
```
- 查看卸载结果,如果内容为空表示已经卸载干净,未卸载干净请重新卸载
```
pip freeze > overall.txt
```
- 卸载干净以后重新安装项目依赖
```
pip install -r ./requirements.txt --ignore-installed
```
2. 安装 `cx_Freeze`
```
pip install cx_Freeze
```
3. 修改打包文件 *setup.py* 中的选项为你的期望信息,主要关注以下选项
- 依赖环境(includes):更新 *requirements.txt*,尽量确保依赖的名称正确;其中,以下依赖的名称需要稍加调整
```
Flask -> flask
Requests -> requests
PyYAML -> yaml
json_rpc -> jsonrpc
```
- 资源文件(include_files):确保 *include_files* 包含了所有你要复制的文件
4. 打包,根目录执行以下指令
```
python setup.py build
```
5. 注意:打包后生成的可执行文件由操作系统决定。win系统下执行打包,打包后获得的可执行文件就是 main.exe
#### 打包到 _Docker_ 镜像
1. 安装 _Docker_(略...)
```
docker --version
```
2. 更新 *.dockerignore*;以便在构建时跳过不必要的文件,从而减小构建后的镜像大小。**可跳过**
3. 编辑 *Dockerfile*;定义属于你自己构建 _Docker_ 镜像的步骤。**可跳过**
4. 如果你的消息服务和心跳服务都部署在 _Docker_ 容器,为了使得相同网络中的容器可以互相通讯,必须创建自定义网络使用容器名称或者别名进行通信
```
docker network create smartlinks
```
- 附加指令 | 查看网络
```
docker network ls
```
- 附加指令 | 删除网络,确保在删除网络之前,网络中没有正在运行的容器或者其他依赖于该网络的服务
```
docker network rm smartlinks
```
5. 构建 _Docker_ 镜像,构建过程中如果出现 `load metadata for docker.io/library/python:3.9.8-slim`,请开启代理重试
```
docker build -t msg-notice-sv:1.3.0 .
```
- 附加指令 | 如果始终无法加载 *python:3.9.8-slim* 的镜像源,请尝试手动拉取镜像,再执行以上构建指令
```
docker pull python:3.9.8-slim
```
6. 运行 _Docker_ 镜像,连接到名为 `smartlinks` 的自定义网络,并指定容器的网络别名为 `msg-sv`
- 通过默认配置文件启动
```
docker run -d --name msg-sv --network smartlinks --network-alias msg-sv -p 4000:4000 msg-notice-sv:1.3.0
```
- 指定环境启动
```
docker run -d --name msg-sv --network smartlinks --network-alias msg-sv -p 4000:4000 -e ACTIVE=test msg-notice-sv:1.3.0
```
- 指定启动参数,更多环境参数请参看环境常量
```
docker run -d --name msg-sv --network smartlinks --network-alias msg-sv -p 4000:4000 -e REDIS_HOST=122.9.106.209 -e REDIS_PORT=6360 -e REDIS_PASSWORD=smartlinks@987#$% msg-notice-sv:1.3.0
```
7. 列出所有正在运行的容器
```
docker ps
```
8. 保存容器镜像为本地文件,文件将会保存在执行指令的目录下
```
docker save -o msg-v1.tar msg-notice-sv:1.3.0
```
9. 从本地系统拷贝镜像文件到 _Linux_ 或其它系统,在 _Linux_ 系统的 _Docker_ 中加载镜像文件
```
docker load -i /path/msg-v1.tar
```
#### 问题与方案
1. 程序出现 `***Unable to connect to proxy***` 错误!
```
Max retries exceeded with url: /media/upload?access_token=8f2d1a2b3bbc3403a292a7d1d77f815f (Caused by ProxyError('Unable to connect to proxy', FileNotFoundError(2, 'No such file or directory')))
```
方案:请检查是否开启了VPN代理,关闭代理后恢复正常
#### 目录结构
```
├── common - 通用模块
│ ├── AsciiCode.py - ASCII 码表,通过 ASCII 码编译配置键
│ ├── constants.py - 通用常量
│ ├── env.py - 环境常量,可通过环境变量读取配置信息
│ ├── LoggerFactory.py - 日志配置
│ ├── util.py - 通用工具
│ ├── exception.py - 异常类
│ ├── DingtalkUrl.py - 钉钉 SDK 地址
│ ├── RpcResponse.py - RPC 响应
│ └── RpcStatus.py - RPC 响应状态码
├── config - 环境配置
│ └── configuration.py - 配置工厂
├── client_rpc - RPC 测试客户端
│ ├── file_client.py - 文件服务测试客户端
│ └── msg_client.py - 消息服务测试客户端
├── service_rpc - RPC 接口模块
│ ├── api - RPC 接口注册
│ │ ├── rpc_file_api.py - 文件服务的 RPC 接口
│ │ └── rpc_sms_api.py - 消息服务的 RPC 接口
│ └── route_entrance.py - 服务路由端点注册
├── service_file - 文件服务模块
│ ├── MinioService.py - Minio 文件服务
│ └── RedisUtils.py - Redis 缓存服务
├── service_sms - 消息服务模块
│ ├── sdk - 第三方 SDK
│ │ ├── dingtalk.py - 钉钉消息
│ │ └── dysmsapi.py - 阿里短信
│ ├── AlibabaSmsService.py - 阿里短信服务
│ └── DingtalkService.py - 钉钉消息服务
├── static - 静态文件目录
│ ├── conf - 配置文件
│ ├── bfp - 二进制文件的临时保存目录
│ ├── log - 日志的输出目录
│ └── files - 文件目录
├── build - 打包目录,包含可执行文件、项目依赖、静态资源等(打包后生成)
├── setup.py - 打包选项配置
└── main.py - 主程序
```