Download docs/zh/api-reference/endpoint/webhook.mdx from wuran/mcphub: direct link, hf CLI and curl.
- Browser
- Download file 12.5 kB
-
https://huggingface.co/spaces/wuran/mcphub/resolve/main/docs/zh/api-reference/endpoint/webhook.mdx
- Command line
-
hf download hf://spaces/wuran/mcphub/docs/zh/api-reference/endpoint/webhook.mdx
-
curl -L -o webhook.mdx https://huggingface.co/spaces/wuran/mcphub/resolve/main/docs/zh/api-reference/endpoint/webhook.mdx
12.5 kB
| --- | |
| title: WebHooks API | |
| description: 配置和管理 WebHook 事件通知的完整指南 | |
| --- | |
| # WebHooks API | |
| WebHooks 允许 MCPHub 在特定事件发生时向您的应用程序发送实时通知。 | |
| ## 概述 | |
| MCPHub WebHooks 系统支持以下功能: | |
| - 实时事件通知 | |
| - 自定义过滤器 | |
| - 重试机制 | |
| - 签名验证 | |
| - 批量事件处理 | |
| ## 支持的事件类型 | |
| | 事件类型 | 描述 | | |
| | ----------------------- | -------------- | | |
| | `server.created` | MCP 服务器创建 | | |
| | `server.updated` | MCP 服务器更新 | | |
| | `server.deleted` | MCP 服务器删除 | | |
| | `server.status_changed` | 服务器状态变更 | | |
| | `group.created` | 服务器组创建 | | |
| | `group.updated` | 服务器组更新 | | |
| | `group.deleted` | 服务器组删除 | | |
| | `user.login` | 用户登录 | | |
| | `user.logout` | 用户登出 | | |
| | `config.changed` | 配置变更 | | |
| | `system.error` | 系统错误 | | |
| ## 创建 WebHook | |
| ### 端点 | |
| ```http | |
| POST /api/webhooks | |
| ``` | |
| ### 请求体 | |
| ```json | |
| { | |
| "url": "https://your-app.com/webhook", | |
| "events": ["server.created", "server.status_changed"], | |
| "secret": "your-webhook-secret", | |
| "active": true, | |
| "config": { | |
| "contentType": "application/json", | |
| "insecureSsl": false, | |
| "retryCount": 3, | |
| "timeout": 30 | |
| }, | |
| "filters": { | |
| "serverGroups": ["production", "staging"], | |
| "serverTypes": ["ai-assistant", "data-processor"] | |
| } | |
| } | |
| ``` | |
| ### 响应 | |
| ```json | |
| { | |
| "success": true, | |
| "data": { | |
| "id": "webhook-123", | |
| "url": "https://your-app.com/webhook", | |
| "events": ["server.created", "server.status_changed"], | |
| "active": true, | |
| "secret": "your-webhook-secret", | |
| "config": { | |
| "contentType": "application/json", | |
| "insecureSsl": false, | |
| "retryCount": 3, | |
| "timeout": 30 | |
| }, | |
| "filters": { | |
| "serverGroups": ["production", "staging"], | |
| "serverTypes": ["ai-assistant", "data-processor"] | |
| }, | |
| "createdAt": "2024-01-15T10:30:00Z", | |
| "updatedAt": "2024-01-15T10:30:00Z" | |
| } | |
| } | |
| ``` | |
| ## 获取 WebHook 列表 | |
| ### 端点 | |
| ```http | |
| GET /api/webhooks | |
| ``` | |
| ### 查询参数 | |
| | 参数名 | 类型 | 描述 | | |
| | ------ | ------- | -------------------- | | |
| | page | integer | 页码(默认:1) | | |
| | limit | integer | 每页数量(默认:20) | | |
| | active | boolean | 过滤活跃状态 | | |
| | event | string | 过滤事件类型 | | |
| ### 请求示例 | |
| ```bash | |
| curl -X GET \ | |
| 'https://api.mcphub.io/api/webhooks?active=true&limit=10' \ | |
| -H 'Authorization: Bearer YOUR_API_TOKEN' | |
| ``` | |
| ### 响应 | |
| ```json | |
| { | |
| "success": true, | |
| "data": { | |
| "webhooks": [ | |
| { | |
| "id": "webhook-123", | |
| "url": "https://your-app.com/webhook", | |
| "events": ["server.created", "server.status_changed"], | |
| "active": true, | |
| "lastDelivery": "2024-01-15T09:30:00Z", | |
| "deliveryCount": 145, | |
| "failureCount": 2, | |
| "createdAt": "2024-01-10T10:30:00Z" | |
| } | |
| ], | |
| "pagination": { | |
| "page": 1, | |
| "limit": 10, | |
| "total": 25, | |
| "pages": 3 | |
| } | |
| } | |
| } | |
| ``` | |
| ## 获取单个 WebHook | |
| ### 端点 | |
| ```http | |
| GET /api/webhooks/{id} | |
| ``` | |
| ### 响应 | |
| ```json | |
| { | |
| "success": true, | |
| "data": { | |
| "id": "webhook-123", | |
| "url": "https://your-app.com/webhook", | |
| "events": ["server.created", "server.status_changed"], | |
| "active": true, | |
| "secret": "your-webhook-secret", | |
| "config": { | |
| "contentType": "application/json", | |
| "insecureSsl": false, | |
| "retryCount": 3, | |
| "timeout": 30 | |
| }, | |
| "filters": { | |
| "serverGroups": ["production", "staging"], | |
| "serverTypes": ["ai-assistant", "data-processor"] | |
| }, | |
| "stats": { | |
| "totalDeliveries": 145, | |
| "successfulDeliveries": 143, | |
| "failedDeliveries": 2, | |
| "lastDelivery": "2024-01-15T09:30:00Z", | |
| "lastSuccess": "2024-01-15T09:30:00Z", | |
| "lastFailure": "2024-01-14T15:20:00Z" | |
| }, | |
| "createdAt": "2024-01-10T10:30:00Z", | |
| "updatedAt": "2024-01-15T10:30:00Z" | |
| } | |
| } | |
| ``` | |
| ## 更新 WebHook | |
| ### 端点 | |
| ```http | |
| PUT /api/webhooks/{id} | |
| ``` | |
| ### 请求体 | |
| ```json | |
| { | |
| "url": "https://your-app.com/new-webhook", | |
| "events": ["server.created", "server.updated", "server.deleted"], | |
| "active": true, | |
| "config": { | |
| "retryCount": 5, | |
| "timeout": 45 | |
| } | |
| } | |
| ``` | |
| ## 删除 WebHook | |
| ### 端点 | |
| ```http | |
| DELETE /api/webhooks/{id} | |
| ``` | |
| ### 响应 | |
| ```json | |
| { | |
| "success": true, | |
| "message": "WebHook 已成功删除" | |
| } | |
| ``` | |
| ## WebHook 事件格式 | |
| ### 基本结构 | |
| 所有 WebHook 事件都遵循以下基本结构: | |
| ```json | |
| { | |
| "id": "event-123", | |
| "type": "server.created", | |
| "timestamp": "2024-01-15T10:30:00Z", | |
| "version": "1.0", | |
| "data": { | |
| // 事件特定数据 | |
| }, | |
| "metadata": { | |
| "source": "mcphub", | |
| "environment": "production", | |
| "triggeredBy": "user-456" | |
| } | |
| } | |
| ``` | |
| ### 服务器事件示例 | |
| #### server.created | |
| ```json | |
| { | |
| "id": "event-123", | |
| "type": "server.created", | |
| "timestamp": "2024-01-15T10:30:00Z", | |
| "version": "1.0", | |
| "data": { | |
| "server": { | |
| "id": "mcp-server-123", | |
| "name": "AI Assistant Server", | |
| "type": "ai-assistant", | |
| "endpoint": "https://ai-assistant.example.com", | |
| "group": "production", | |
| "status": "active", | |
| "capabilities": ["chat", "completion"], | |
| "createdAt": "2024-01-15T10:30:00Z" | |
| } | |
| }, | |
| "metadata": { | |
| "source": "mcphub", | |
| "environment": "production", | |
| "triggeredBy": "user-456" | |
| } | |
| } | |
| ``` | |
| #### server.status_changed | |
| ```json | |
| { | |
| "id": "event-124", | |
| "type": "server.status_changed", | |
| "timestamp": "2024-01-15T11:30:00Z", | |
| "version": "1.0", | |
| "data": { | |
| "server": { | |
| "id": "mcp-server-123", | |
| "name": "AI Assistant Server", | |
| "previousStatus": "active", | |
| "currentStatus": "inactive", | |
| "reason": "Health check failed", | |
| "lastHealthCheck": "2024-01-15T11:25:00Z" | |
| } | |
| }, | |
| "metadata": { | |
| "source": "mcphub", | |
| "environment": "production", | |
| "triggeredBy": "system" | |
| } | |
| } | |
| ``` | |
| ## 签名验证 | |
| MCPHub 使用 HMAC-SHA256 签名来验证 WebHook 的真实性。 | |
| ### 签名生成 | |
| 签名在 `X-MCPHub-Signature-256` 头中发送: | |
| ``` | |
| X-MCPHub-Signature-256: sha256=5757107ea39eca8e35d1e8... | |
| ``` | |
| ### 验证示例 | |
| #### Node.js | |
| ```javascript | |
| const crypto = require('crypto'); | |
| function verifySignature(payload, signature, secret) { | |
| const expectedSignature = crypto | |
| .createHmac('sha256', secret) | |
| .update(payload, 'utf8') | |
| .digest('hex'); | |
| const actualSignature = signature.replace('sha256=', ''); | |
| return crypto.timingSafeEqual( | |
| Buffer.from(expectedSignature, 'hex'), | |
| Buffer.from(actualSignature, 'hex'), | |
| ); | |
| } | |
| // Express.js 中间件示例 | |
| app.use('/webhook', express.raw({ type: 'application/json' }), (req, res) => { | |
| const signature = req.headers['x-mcphub-signature-256']; | |
| const payload = req.body; | |
| if (!verifySignature(payload, signature, process.env.WEBHOOK_SECRET)) { | |
| return res.status(401).send('Unauthorized'); | |
| } | |
| // 处理 WebHook 事件 | |
| const event = JSON.parse(payload); | |
| console.log('收到事件:', event.type); | |
| res.status(200).send('OK'); | |
| }); | |
| ``` | |
| #### Python | |
| ```python | |
| import hmac | |
| import hashlib | |
| def verify_signature(payload, signature, secret): | |
| expected_signature = hmac.new( | |
| secret.encode('utf-8'), | |
| payload, | |
| hashlib.sha256 | |
| ).hexdigest() | |
| actual_signature = signature.replace('sha256=', '') | |
| return hmac.compare_digest(expected_signature, actual_signature) | |
| # Flask 示例 | |
| from flask import Flask, request, jsonify | |
| import json | |
| app = Flask(__name__) | |
| methods=['POST']) | |
| def webhook(): | |
| signature = request.headers.get('X-MCPHub-Signature-256') | |
| payload = request.get_data() | |
| if not verify_signature(payload, signature, 'your-webhook-secret'): | |
| return jsonify({'error': 'Unauthorized'}), 401 | |
| event = json.loads(payload) | |
| print(f'收到事件: {event["type"]}') | |
| return jsonify({'status': 'success'}), 200 | |
| ``` | |
| ## 重试机制 | |
| MCPHub 对失败的 WebHook 交付实施指数退避重试: | |
| - **重试次数**: 可配置(默认 3 次) | |
| - **重试间隔**: 2^n 秒(n 为重试次数) | |
| - **最大间隔**: 300 秒(5 分钟) | |
| - **超时设置**: 可配置(默认 30 秒) | |
| ### 重试时间表 | |
| | 尝试次数 | 延迟时间 | | |
| | -------- | -------- | | |
| | 1 | 立即 | | |
| | 2 | 2 秒 | | |
| | 3 | 4 秒 | | |
| | 4 | 8 秒 | | |
| | 5 | 16 秒 | | |
| ## 获取交付历史 | |
| ### 端点 | |
| ```http | |
| GET /api/webhooks/{id}/deliveries | |
| ``` | |
| ### 查询参数 | |
| | 参数名 | 类型 | 描述 | | |
| | ---------- | ------- | ------------------------------------ | | |
| | page | integer | 页码 | | |
| | limit | integer | 每页数量 | | |
| | status | string | 过滤状态(success, failed, pending) | | |
| | event_type | string | 过滤事件类型 | | |
| ### 响应 | |
| ```json | |
| { | |
| "success": true, | |
| "data": { | |
| "deliveries": [ | |
| { | |
| "id": "delivery-123", | |
| "eventId": "event-123", | |
| "eventType": "server.created", | |
| "url": "https://your-app.com/webhook", | |
| "status": "success", | |
| "responseCode": 200, | |
| "responseTime": 145, | |
| "attempts": 1, | |
| "deliveredAt": "2024-01-15T10:30:15Z", | |
| "nextRetry": null | |
| }, | |
| { | |
| "id": "delivery-124", | |
| "eventId": "event-124", | |
| "eventType": "server.status_changed", | |
| "url": "https://your-app.com/webhook", | |
| "status": "failed", | |
| "responseCode": 500, | |
| "responseTime": 30000, | |
| "attempts": 3, | |
| "error": "Connection timeout", | |
| "deliveredAt": null, | |
| "nextRetry": "2024-01-15T11:45:00Z" | |
| } | |
| ], | |
| "pagination": { | |
| "page": 1, | |
| "limit": 20, | |
| "total": 145, | |
| "pages": 8 | |
| } | |
| } | |
| } | |
| ``` | |
| ## 测试 WebHook | |
| ### 端点 | |
| ```http | |
| POST /api/webhooks/{id}/test | |
| ``` | |
| ### 请求体 | |
| ```json | |
| { | |
| "eventType": "server.created", | |
| "customData": { | |
| "test": true, | |
| "message": "这是一个测试事件" | |
| } | |
| } | |
| ``` | |
| ### 响应 | |
| ```json | |
| { | |
| "success": true, | |
| "data": { | |
| "deliveryId": "delivery-test-123", | |
| "status": "delivered", | |
| "responseCode": 200, | |
| "responseTime": 124, | |
| "sentAt": "2024-01-15T10:30:00Z" | |
| } | |
| } | |
| ``` | |
| ## 最佳实践 | |
| ### 1. 幂等性处理 | |
| 确保您的 WebHook 端点能够处理重复事件: | |
| ```javascript | |
| const processedEvents = new Set(); | |
| app.post('/webhook', (req, res) => { | |
| const event = req.body; | |
| // 检查事件是否已处理 | |
| if (processedEvents.has(event.id)) { | |
| return res.status(200).send('Already processed'); | |
| } | |
| // 处理事件 | |
| processEvent(event); | |
| // 记录已处理的事件 | |
| processedEvents.add(event.id); | |
| res.status(200).send('OK'); | |
| }); | |
| ``` | |
| ### 2. 异步处理 | |
| 对于复杂的处理逻辑,使用异步处理避免阻塞: | |
| ```javascript | |
| app.post('/webhook', async (req, res) => { | |
| const event = req.body; | |
| // 立即响应 | |
| res.status(200).send('OK'); | |
| // 异步处理事件 | |
| setImmediate(() => { | |
| processEventAsync(event); | |
| }); | |
| }); | |
| ``` | |
| ### 3. 错误处理 | |
| 实施适当的错误处理和日志记录: | |
| ```javascript | |
| app.post('/webhook', (req, res) => { | |
| try { | |
| const event = req.body; | |
| processEvent(event); | |
| res.status(200).send('OK'); | |
| } catch (error) { | |
| console.error('WebHook 处理错误:', error); | |
| res.status(500).send('Internal Server Error'); | |
| } | |
| }); | |
| ``` | |
| ### 4. 监控和告警 | |
| 监控 WebHook 的交付状态: | |
| ```bash | |
| # 检查失败的交付 | |
| curl -X GET \ | |
| 'https://api.mcphub.io/api/webhooks/webhook-123/deliveries?status=failed' \ | |
| -H 'Authorization: Bearer YOUR_API_TOKEN' | |
| ``` | |
| ## 故障排除 | |
| ### 常见问题 | |
| 1. **签名验证失败** | |
| - 检查密钥是否正确 | |
| - 确保使用原始请求体进行验证 | |
| - 验证 HMAC 计算实现 | |
| 2. **超时错误** | |
| - 增加 WebHook 超时设置 | |
| - 优化端点响应时间 | |
| - 使用异步处理 | |
| 3. **重复事件** | |
| - 实施幂等性检查 | |
| - 使用事件 ID 去重 | |
| - 记录处理状态 | |
| ### 调试工具 | |
| 使用 MCPHub 提供的调试工具: | |
| ```bash | |
| # 查看最近的交付日志 | |
| curl -X GET \ | |
| 'https://api.mcphub.io/api/webhooks/webhook-123/deliveries?limit=5' \ | |
| -H 'Authorization: Bearer YOUR_API_TOKEN' | |
| # 重新发送失败的事件 | |
| curl -X POST \ | |
| 'https://api.mcphub.io/api/webhooks/delivery-124/redeliver' \ | |
| -H 'Authorization: Bearer YOUR_API_TOKEN' | |
| ``` | |