---
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__)

@app.route('/webhook', 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'
```
