sync: 同步飞书机器人 v1.0.4 并脱敏
This commit is contained in:
@@ -1,127 +1,90 @@
|
||||
# iotlcm-bot
|
||||
|
||||
独立飞书应用机器人:读取 Worker 终态 Run JSON,渲染并发送全量同步结果卡片。
|
||||
|
||||
本服务是 [iotlcm](https://git.5iot.com/iotlcm-public) 物联网卡全生命周期管理平台的配套组件,用于把异步全量同步(卡状态、流量、IMEI 等)的执行结果推送到飞书群。
|
||||
|
||||
## 特性
|
||||
|
||||
- **零外部依赖**:只依赖 `gopkg.in/yaml.v3`,不需要 Redis、数据库或 Worker HTTP 接口
|
||||
- **只读归档**:只读挂载 Worker 的归档目录,按 `runId` 去重后发送
|
||||
- **多类卡片**:全量同步汇总卡、告警卡、供料提醒卡
|
||||
- **健康自检**:检测归档目录被宿主删除(inode 丢失)这类静默故障并告警
|
||||
- **单镜像**:`scratch` 基础镜像,非 root 运行
|
||||
V1 独立飞书应用机器人:读取 Worker 终态 Run JSON,渲染并发送全量同步结果卡片。
|
||||
|
||||
## V1 范围
|
||||
|
||||
- 只接受 `version=1` 且包含 `run` 和非空 `rounds` 的归档 JSON
|
||||
- 不兼容旧版 `rounds=[]` 文件
|
||||
- 不读取 Redis、Worker HTTP 接口或日志
|
||||
- 不实现 Replay、事件回调、卡片按钮和错误聚合
|
||||
- 只接受当前版本 `version=1` 且包含 `run` 和非空 `rounds` 的归档 JSON。
|
||||
- 不兼容旧版 `rounds=[]` 文件。
|
||||
- 不读取 Redis、Worker HTTP 接口或日志。
|
||||
- 不实现 Replay、事件回调、卡片按钮和错误聚合。
|
||||
- 按 `runId` 去重,避免重复发送。
|
||||
|
||||
## 快速开始
|
||||
## 本地验证
|
||||
|
||||
```bash
|
||||
go mod tidy
|
||||
go test ./...
|
||||
```
|
||||
|
||||
本地渲染一张卡片(不调用飞书 API):
|
||||
|
||||
```bash
|
||||
go run ./cmd/iotlcm-bot render --file testdata/current-run.json
|
||||
go run ./cmd/iotlcm-bot render --file testdata/current-run.json --json
|
||||
```
|
||||
|
||||
## 配置
|
||||
`render` 只渲染通知内容,不调用飞书 API。
|
||||
|
||||
配置文件为 `config.yaml`。**公开版里的飞书凭据是占位符**,真实值请用环境变量或本地覆盖文件注入:
|
||||
## 本地单次发送
|
||||
|
||||
```yaml
|
||||
environment: preview
|
||||
archiveDir: /data/full-sync
|
||||
stateDir: ./state
|
||||
pollInterval: 10s
|
||||
feishu:
|
||||
appId: "${FEISHU_APP_ID}"
|
||||
appSecret: "${FEISHU_APP_SECRET}"
|
||||
chatId: "${FEISHU_CHAT_ID}"
|
||||
```
|
||||
|
||||
| 配置项 | 说明 |
|
||||
| --- | --- |
|
||||
| `archiveDir` | Worker 归档目录(只读挂载) |
|
||||
| `stateDir` | 已发送 Run 的标记目录(可写) |
|
||||
| `pollInterval` | 扫描间隔,默认 `10s` |
|
||||
| `feishu.appId` / `appSecret` | 飞书应用凭据 |
|
||||
| `feishu.chatId` | 目标群 ID |
|
||||
|
||||
## 命令
|
||||
|
||||
| 命令 | 作用 |
|
||||
| --- | --- |
|
||||
| `watch` | 常驻扫描归档目录,自动发送新 Run(默认模式) |
|
||||
| `send` | 发送指定 Run JSON |
|
||||
| `send-text` | 向配置里的群发一条纯文本(用于连通性验证) |
|
||||
| `render` | 只渲染卡片内容,不调用飞书 API |
|
||||
机器人加入测试群,且 YAML 配置已填写 `feishu.appSecret` 和 `feishu.chatId` 后,可以发送指定 Run:
|
||||
|
||||
```bash
|
||||
go run ./cmd/iotlcm-bot watch --config /path/to/iotlcm-bot.yaml
|
||||
go run ./cmd/iotlcm-bot send --config /path/to/iotlcm-bot.yaml --file /path/to/run.json
|
||||
```
|
||||
|
||||
发送成功后会写入 `state/sent/<runId>.json`;同一 Run 再次执行会跳过。确需重发时使用:
|
||||
|
||||
```bash
|
||||
go run ./cmd/iotlcm-bot send --config /path/to/iotlcm-bot.yaml --file /path/to/run.json --force
|
||||
```
|
||||
|
||||
`--force` 用于确需重发时;正常运行不要使用。发送成功会写入 `state/sent/<runId>.json`,同一 Run 再次执行会跳过。
|
||||
正常运行时不要使用 `--force`。
|
||||
|
||||
## 容器化部署
|
||||
## 已部署容器的发送测试
|
||||
|
||||
只验证飞书连接时,无需提供 Run JSON。Bot 容器运行后,发送一条自定义文本:
|
||||
|
||||
```bash
|
||||
docker build -t iotlcm-bot:latest .
|
||||
docker run -d \
|
||||
-v /host/worker/full-sync:/data/full-sync:ro \
|
||||
-v /host/bot/state:/data/state \
|
||||
-v /host/bot/config.yaml:/app/config/config.yaml:ro \
|
||||
iotlcm-bot:latest
|
||||
docker exec iotlcm-bot /usr/local/bin/iotlcm-bot send-text --config /app/config/config.yaml --text "iotlcm-bot 飞书连接测试"
|
||||
```
|
||||
|
||||
容器内路径约定:
|
||||
`send-text` 不扫描归档、不写 Run 发送标记,可以重复执行。它直接通过飞书消息 API 向配置文件中的群发送文本,不是 HTTP 测试接口。
|
||||
|
||||
| 容器内路径 | 用途 | 挂载方式 |
|
||||
| --- | --- | --- |
|
||||
| `/data/full-sync` | Worker 归档目录 | **只读** |
|
||||
| `/data/state` | 已发送标记 | 可写 |
|
||||
| `/app/config/config.yaml` | 配置文件 | 只读 |
|
||||
需要测试完整的 Run 卡片链路时,才使用下面的单次发送命令:
|
||||
|
||||
## 目录结构
|
||||
```bash
|
||||
docker exec iotlcm-bot /usr/local/bin/iotlcm-bot send --config /app/config/config.yaml --file /data/full-sync/run-<runId>.json
|
||||
```
|
||||
|
||||
如该 Run 已发送,明确需要再次发送时加 `--force`:
|
||||
|
||||
```bash
|
||||
docker exec iotlcm-bot /usr/local/bin/iotlcm-bot send --config /app/config/config.yaml --file /data/full-sync/run-<runId>.json --force
|
||||
```
|
||||
|
||||
发送成功会写入 `/data/state/sent/<runId>.json`。检查容器和日志:
|
||||
|
||||
```bash
|
||||
docker ps --filter name=iotlcm-bot
|
||||
docker logs --tail 100 iotlcm-bot
|
||||
```
|
||||
|
||||
## 配置文件
|
||||
|
||||
复制 `config.example.yaml` 为未跟踪的 `config.yaml`,填入实际飞书应用凭据和群 ID。
|
||||
配置加载器直接读取 YAML,不展开环境变量;请勿把真实凭据提交到仓库。
|
||||
部署时通过只读挂载将配置注入容器,容器内路径可为 `/app/config/config.yaml`。
|
||||
|
||||
## 自动通知
|
||||
|
||||
Compose 默认以 `watch` 模式启动 Bot。Bot 每 10 秒扫描挂载的终态 Run JSON,校验通过且未发送过的 Run 会自动发到配置的飞书群。
|
||||
|
||||
本地启动方式:
|
||||
|
||||
```bash
|
||||
go run ./cmd/iotlcm-bot watch --config /path/to/iotlcm-bot.yaml
|
||||
```
|
||||
|
||||
## 目录挂载
|
||||
|
||||
```text
|
||||
iotlcm-bot/
|
||||
├── cmd/iotlcm-bot/main.go # CLI 入口
|
||||
├── internal/
|
||||
│ ├── archive/ # 归档 JSON 解析
|
||||
│ ├── config/ # 配置加载
|
||||
│ ├── feishu/ # 飞书 API 客户端
|
||||
│ ├── notify/ # 通知服务与健康自检
|
||||
│ ├── render/ # 卡片渲染
|
||||
│ └── state/ # 已发送标记
|
||||
├── config.yaml # 配置(公开版为占位值)
|
||||
├── testdata/ # 测试用归档样例
|
||||
└── Dockerfile
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
**卡片不发送?** 检查归档目录是否可读、`runId` 是否已发送过(`state/sent/` 下有标记则跳过)、群机器人是否被移出。
|
||||
|
||||
**日志刷满?** `watch` 模式对同一文件只记一次错误,文件被重写后会重新记录。
|
||||
|
||||
**归档目录被宿主删了?** Bot 会检测到(inode 丢失)并降级告警——此时应检查宿主的日志清理脚本是否误删了挂载源目录。
|
||||
|
||||
## 相关项目
|
||||
|
||||
- [iotlcm-worker-svr](https://git.5iot.com/iotlcm-public/iotlcm-worker-svr) —— 异步执行中枢,产出归档 JSON
|
||||
- [iotlcm-openapi](https://git.5iot.com/iotlcm-public/iotlcm-openapi) —— 对外 API 网关
|
||||
|
||||
## License
|
||||
|
||||
[Apache License 2.0](./LICENSE)
|
||||
Worker 宿主归档目录:<host-worker-full-sync-dir>
|
||||
Bot 只读挂载目录:/data/full-sync
|
||||
Bot 可写状态目录:<host-bot-state-dir> -> /data/state
|
||||
```
|
||||
Reference in New Issue
Block a user