mirror of
https://github.com/d0zingcat/alert-message-center.git
synced 2026-05-13 23:16:48 +00:00
feat: polish group binding
Signed-off-by: d0zingcat <iamtangli42@gmail.com>
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
### 修复
|
||||
- **WebSocket 初始化**: 修复了 `@larksuiteoapi/node-sdk` v1.56.0+ 中 WebSocket 初始化不正确的 `TypeError`。现在正确使用了 `WSClient` 类并修复了参数类型错误。
|
||||
- **事件处理**: 修正了 `im.chat.member.bot.added_v1` 事件的 Payload 解析逻辑。
|
||||
- **Hono 兼容性**: 修正了 `feishu-event.ts` 中 `lark.adaptDefault` 的错误用法。改为使用手动 Challenge 处理和 `eventDispatcher.invoke`,解决了与 Hono 请求/响应对象的兼容性问题引发的编译错误。
|
||||
- **Hono 兼容性**: 修正了 `feishu-event.ts` 中 `lark.adaptDefault` 的错误用法。改为使用手动 Challenge 处理和 `eventDispatcher.invoke`,并通过原型链注入 Header 解决了与 Hono 请求/响应对象的兼容性以及签名校验失败的问题。
|
||||
- **群聊解绑**: 增加对 `im.chat.member.bot.deleted_v1` 事件的支持。当机器人被移除群聊时,自动清理 `known_group_chats` 和 `topic_group_chats` 关联,确保订阅关系自动解绑。
|
||||
|
||||
### 新增
|
||||
|
||||
17
README.md
17
README.md
@@ -13,7 +13,16 @@
|
||||
支持通过 **Topic (主题)** 订阅模式分发告警,同时也提供 **Personal Inbox (个人信箱)** 功能,无需创建话题即可快速给自己推送消息。
|
||||

|
||||
|
||||
### 2. 管理员看板 (Live Stats)
|
||||
除了个人订阅外,您可以将 Topic 绑定至多个**飞书群聊**。
|
||||
> [!TIP]
|
||||
> **群聊发现**:请先将机器人邀请进入目标群聊。机器人入群后会触发自动感应,此时刷新管理页面即可在下拉菜单中看到并绑定该群组。
|
||||
|
||||
### 2. 群聊告警分发
|
||||
支持将机器人加入飞书群聊,并将话题绑定到群聊中,实现告警的群组广播。
|
||||

|
||||

|
||||
|
||||
### 3. 管理员看板 (Live Stats)
|
||||
实时追踪全系统的告警负载、分发成功率以及各话题的热度。
|
||||

|
||||
|
||||
@@ -22,11 +31,13 @@
|
||||
## 🔥 核心特性
|
||||
|
||||
- **🚀 极简推送 (Personal Inbox)**: 每个用户拥有专属的 Webhook Token,直接向 `/dm` 接口发送即可在飞书收到私聊,零配置成本。
|
||||
- **📢 主题订阅 (Topic Model)**: 灵活的“发布-订阅”机制。告警发送至 Topic,系统自动分发给所有订阅成员,避免群聊骚扰。
|
||||
- **📢 主题订阅 (Topic Model)**: 灵活的“发布-订阅”机制。告警发送至 Topic,系统自动分发给所有订阅成员。
|
||||
- **👥 群聊分发 (Group Support)**: 告警可同步分发至绑定的飞书群聊,支持机器人自动发现与解绑。
|
||||
- **🛡️ 权限与审计**:
|
||||
- 话题创建需经过管理员审批。
|
||||
- 记录完整的 `Alert Task` 日志,包含发送者、时间、审批人及分发成功率。
|
||||
- 记录完整的 `Alert Task` 日志,实现发送链路可追溯。
|
||||
- **📊 实时看板**: Grafana 风格的监控界面,直观展示系统运行健壮性。
|
||||
- **🔌 长连接模式 (WebSocket)**: 支持飞书开放平台长连接,无需公网 IP 或域名即可在内网环境接收事件回调。
|
||||
- **⚡ 高性能架构**: 基于 Bun + Hono 的全异步架构,毫秒级分发延迟。
|
||||
|
||||
---
|
||||
|
||||
@@ -31,11 +31,11 @@ feishuEvent.post('/', async (c) => {
|
||||
}
|
||||
|
||||
// 2. Dispatch event
|
||||
// The dispatcher expects an object containing headers and body
|
||||
const result = await eventDispatcher.invoke({
|
||||
...req.body,
|
||||
headers: req.headers
|
||||
});
|
||||
// The dispatcher expects an object containing headers and body.
|
||||
// We use Object.create to put headers on the prototype so they are accessible
|
||||
// but not included in JSON.stringify, which preserves signature verification.
|
||||
const payload = Object.assign(Object.create({ headers: headerRecord }), body);
|
||||
const result = await eventDispatcher.invoke(payload);
|
||||
|
||||
return c.json(result || {});
|
||||
} catch (e) {
|
||||
|
||||
@@ -4,7 +4,10 @@ import { eq } from 'drizzle-orm';
|
||||
import * as lark from '@larksuiteoapi/node-sdk';
|
||||
import { logger } from './lib/logger';
|
||||
|
||||
export const eventDispatcher = new lark.EventDispatcher({}).register({
|
||||
export const eventDispatcher = new lark.EventDispatcher({
|
||||
encryptKey: process.env.FEISHU_ENCRYPT_KEY,
|
||||
verificationToken: process.env.FEISHU_VERIFICATION_TOKEN,
|
||||
}).register({
|
||||
'im.chat.member.bot.added_v1': async (data) => {
|
||||
const { chat_id, name } = data as any;
|
||||
logger.info({ chat_id, name }, '[Feishu Event] Bot added to group');
|
||||
|
||||
@@ -175,6 +175,7 @@ The database schema is defined in `apps/server/src/db/schema.ts`.
|
||||
### Feishu Event
|
||||
- `POST /api/feishu/event`: Endpoint for receiving Feishu events (Webhook mode).
|
||||
- **Note**: This endpoint uses **manual challenge handling** (`lark.generateChallenge`) and `eventDispatcher.invoke` instead of the SDK's `adaptDefault` to maintain compatibility with Hono's non-standard Node.js response object.
|
||||
- **Signature Verification Hack**: To preserve Feishu's signature verification, the internal `invoke` call uses `Object.create({ headers })` to inject HTTP headers on the prototype of the payload object. This ensures headers are accessible to the SDK's internal verification logic but are **excluded** from `JSON.stringify`, which is critical for matching the SHA256 content checksum.
|
||||
|
||||
### Webhook
|
||||
- `POST /api/webhook/:token/topic/:slug`: Trigger an alert for a topic.
|
||||
@@ -183,9 +184,9 @@ The database schema is defined in `apps/server/src/db/schema.ts`.
|
||||
## 6. Future Roadmap (Planned)
|
||||
|
||||
- [ ] **Message Preview**: Preview Feishu card JSON in the UI.
|
||||
- [ ] **History/Logs**: Keep a log of sent alerts for auditing.
|
||||
- [x] **History/Logs**: Tracking for sent alerts (Alert Tasks/Logs).
|
||||
- [ ] **Retry Mechanism**: Handle Feishu API failures.
|
||||
- [x] **Deployment**: Dockerfile and deployment scripts.
|
||||
- [x] **Deployment**: Dockerfile and CI/CD.
|
||||
|
||||
## 7. Development Conventions
|
||||
|
||||
@@ -201,6 +202,11 @@ The database schema is defined in `apps/server/src/db/schema.ts`.
|
||||
- **Environment Isolation**:
|
||||
- Each workspace (`apps/server`, `apps/web`) uses its own `.env` file via Bun's `--env-file .env` flag.
|
||||
- Development proxy target for the frontend is configurable via `VITE_API_URL` (default: `http://localhost:3000`).
|
||||
- **Critical Environment Variables**:
|
||||
- `FEISHU_ENCRYPT_KEY`: Essential for the `lark.generateChallenge` and event signature verification.
|
||||
- `FEISHU_VERIFICATION_TOKEN`: Used by `EventDispatcher` for event authentication.
|
||||
- `FEISHU_USE_WS`: Set to `true` to enable WebSocket mode (bypasses `feishu-event.ts`).
|
||||
- `ADMIN_EMAILS`: Comma-separated list of emails that automatically receive `isAdmin=true` upon first login.
|
||||
- **CI/CD**:
|
||||
- GitHub Actions automates building a multi-stage Docker image and pushing it to GitHub Container Registry (GHCR).
|
||||
- Image path: `ghcr.io/${USER}/alert-message-center`.
|
||||
|
||||
BIN
docs/images/group_alert.png
Normal file
BIN
docs/images/group_alert.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
BIN
docs/images/group_binding.png
Normal file
BIN
docs/images/group_binding.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 416 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 291 KiB After Width: | Height: | Size: 409 KiB |
Reference in New Issue
Block a user