Skip to content

Webhooks API

本文档描述了 Trae Webhooks 功能的 API 接口。

概述

Webhooks 允许您在特定事件发生时接收实时通知。当事件触发时,Trae 会向您配置的 URL 发送 HTTP POST 请求,包含事件的详细信息。

支持的事件

事件类型描述
project.created项目创建
project.updated项目更新
project.deleted项目删除
build.started构建开始
build.completed构建完成
build.failed构建失败
deployment.started部署开始
deployment.completed部署完成
deployment.failed部署失败
collaboration.invited协作邀请
collaboration.joined加入协作
collaboration.left离开协作
file.created文件创建
file.updated文件更新
file.deleted文件删除
user.registered用户注册
user.login用户登录
user.logout用户登出
security.alert安全警报

端点

创建 Webhook

http
POST /api/webhooks

请求参数

参数类型必需描述
urlstringWebhook 接收 URL
eventsarray订阅的事件类型列表
namestringWebhook 名称
descriptionstringWebhook 描述
secretstring用于验证的密钥
activeboolean是否激活 (默认: true)
project_idstring项目 ID (项目级别 webhook)
headersobject自定义请求头
timeoutnumber超时时间 (秒, 默认: 30)
retry_policyobject重试策略

请求示例

json
{
  "url": "https://api.example.com/webhooks/trae",
  "events": [
    "build.completed",
    "build.failed",
    "deployment.completed",
    "deployment.failed"
  ],
  "name": "CI/CD Notifications",
  "description": "Receive notifications for build and deployment events",
  "secret": "your-webhook-secret-key",
  "active": true,
  "project_id": "proj_123",
  "headers": {
    "X-Custom-Header": "custom-value",
    "Authorization": "Bearer your-api-token"
  },
  "timeout": 30,
  "retry_policy": {
    "max_attempts": 3,
    "backoff_strategy": "exponential",
    "initial_delay": 1000,
    "max_delay": 60000
  }
}

响应

json
{
  "webhook_id": "webhook_456",
  "url": "https://api.example.com/webhooks/trae",
  "events": [
    "build.completed",
    "build.failed",
    "deployment.completed",
    "deployment.failed"
  ],
  "name": "CI/CD Notifications",
  "description": "Receive notifications for build and deployment events",
  "secret": "your-webhook-secret-key",
  "active": true,
  "project_id": "proj_123",
  "headers": {
    "X-Custom-Header": "custom-value",
    "Authorization": "Bearer your-api-token"
  },
  "timeout": 30,
  "retry_policy": {
    "max_attempts": 3,
    "backoff_strategy": "exponential",
    "initial_delay": 1000,
    "max_delay": 60000
  },
  "created_at": "2024-01-01T12:00:00Z",
  "updated_at": "2024-01-01T12:00:00Z",
  "created_by": "user_123",
  "stats": {
    "total_deliveries": 0,
    "successful_deliveries": 0,
    "failed_deliveries": 0,
    "last_delivery": null
  }
}

获取 Webhook 列表

http
GET /api/webhooks?project_id={project_id}&active={active}&limit={limit}&offset={offset}

查询参数

参数类型必需描述
project_idstring项目 ID 过滤
activeboolean激活状态过滤
limitnumber返回数量限制
offsetnumber偏移量
sortstring排序字段
orderstring排序方向 (asc/desc)

响应

json
{
  "webhooks": [
    {
      "webhook_id": "webhook_456",
      "url": "https://api.example.com/webhooks/trae",
      "events": [
        "build.completed",
        "build.failed"
      ],
      "name": "CI/CD Notifications",
      "description": "Receive notifications for build and deployment events",
      "active": true,
      "project_id": "proj_123",
      "created_at": "2024-01-01T12:00:00Z",
      "updated_at": "2024-01-01T12:00:00Z",
      "created_by": "user_123",
      "stats": {
        "total_deliveries": 150,
        "successful_deliveries": 145,
        "failed_deliveries": 5,
        "last_delivery": "2024-01-01T11:30:00Z",
        "success_rate": 96.67
      }
    }
  ],
  "total": 1,
  "pagination": {
    "limit": 20,
    "offset": 0,
    "has_more": false
  }
}

获取特定 Webhook

http
GET /api/webhooks/{webhook_id}

响应

json
{
  "webhook_id": "webhook_456",
  "url": "https://api.example.com/webhooks/trae",
  "events": [
    "build.completed",
    "build.failed",
    "deployment.completed",
    "deployment.failed"
  ],
  "name": "CI/CD Notifications",
  "description": "Receive notifications for build and deployment events",
  "secret": "your-webhook-secret-key",
  "active": true,
  "project_id": "proj_123",
  "headers": {
    "X-Custom-Header": "custom-value",
    "Authorization": "Bearer your-api-token"
  },
  "timeout": 30,
  "retry_policy": {
    "max_attempts": 3,
    "backoff_strategy": "exponential",
    "initial_delay": 1000,
    "max_delay": 60000
  },
  "created_at": "2024-01-01T12:00:00Z",
  "updated_at": "2024-01-01T12:00:00Z",
  "created_by": "user_123",
  "stats": {
    "total_deliveries": 150,
    "successful_deliveries": 145,
    "failed_deliveries": 5,
    "last_delivery": "2024-01-01T11:30:00Z",
    "success_rate": 96.67,
    "average_response_time": 250
  },
  "recent_deliveries": [
    {
      "delivery_id": "del_789",
      "event_type": "build.completed",
      "status": "success",
      "response_code": 200,
      "response_time": 245,
      "delivered_at": "2024-01-01T11:30:00Z",
      "attempts": 1
    },
    {
      "delivery_id": "del_788",
      "event_type": "build.failed",
      "status": "failed",
      "response_code": 500,
      "response_time": 5000,
      "delivered_at": "2024-01-01T11:00:00Z",
      "attempts": 3,
      "error": "Internal Server Error"
    }
  ]
}

更新 Webhook

http
PUT /api/webhooks/{webhook_id}

请求参数

参数类型必需描述
urlstringWebhook 接收 URL
eventsarray订阅的事件类型列表
namestringWebhook 名称
descriptionstringWebhook 描述
secretstring用于验证的密钥
activeboolean是否激活
headersobject自定义请求头
timeoutnumber超时时间 (秒)
retry_policyobject重试策略

请求示例

json
{
  "events": [
    "build.completed",
    "build.failed",
    "deployment.completed",
    "deployment.failed",
    "security.alert"
  ],
  "active": true,
  "timeout": 45,
  "retry_policy": {
    "max_attempts": 5,
    "backoff_strategy": "exponential",
    "initial_delay": 2000,
    "max_delay": 120000
  }
}

响应

json
{
  "webhook_id": "webhook_456",
  "url": "https://api.example.com/webhooks/trae",
  "events": [
    "build.completed",
    "build.failed",
    "deployment.completed",
    "deployment.failed",
    "security.alert"
  ],
  "name": "CI/CD Notifications",
  "description": "Receive notifications for build and deployment events",
  "active": true,
  "timeout": 45,
  "retry_policy": {
    "max_attempts": 5,
    "backoff_strategy": "exponential",
    "initial_delay": 2000,
    "max_delay": 120000
  },
  "updated_at": "2024-01-01T12:30:00Z"
}

删除 Webhook

http
DELETE /api/webhooks/{webhook_id}

响应

json
{
  "message": "Webhook deleted successfully",
  "webhook_id": "webhook_456",
  "deleted_at": "2024-01-01T12:00:00Z"
}

测试 Webhook

http
POST /api/webhooks/{webhook_id}/test

请求参数

参数类型必需描述
event_typestring测试事件类型 (默认: test.ping)
payloadobject自定义测试载荷

请求示例

json
{
  "event_type": "build.completed",
  "payload": {
    "build_id": "build_test_123",
    "project_id": "proj_123",
    "status": "success",
    "duration": 120
  }
}

响应

json
{
  "delivery_id": "del_test_999",
  "event_type": "build.completed",
  "status": "success",
  "response_code": 200,
  "response_time": 245,
  "response_body": "OK",
  "delivered_at": "2024-01-01T12:00:00Z",
  "attempts": 1,
  "webhook_url": "https://api.example.com/webhooks/trae"
}

获取 Webhook 投递历史

http
GET /api/webhooks/{webhook_id}/deliveries?limit={limit}&offset={offset}&status={status}&event_type={event_type}

查询参数

参数类型必需描述
limitnumber返回数量限制
offsetnumber偏移量
statusstring投递状态过滤 (success/failed/pending)
event_typestring事件类型过滤
start_datestring开始日期 (ISO 8601)
end_datestring结束日期 (ISO 8601)

响应

json
{
  "deliveries": [
    {
      "delivery_id": "del_789",
      "webhook_id": "webhook_456",
      "event_type": "build.completed",
      "event_id": "event_123",
      "status": "success",
      "response_code": 200,
      "response_time": 245,
      "response_body": "OK",
      "delivered_at": "2024-01-01T11:30:00Z",
      "attempts": 1,
      "payload": {
        "event": "build.completed",
        "timestamp": "2024-01-01T11:30:00Z",
        "data": {
          "build_id": "build_123",
          "project_id": "proj_123",
          "status": "success",
          "duration": 120,
          "commit_sha": "abc123def456",
          "branch": "main"
        }
      }
    },
    {
      "delivery_id": "del_788",
      "webhook_id": "webhook_456",
      "event_type": "build.failed",
      "event_id": "event_122",
      "status": "failed",
      "response_code": 500,
      "response_time": 5000,
      "response_body": "Internal Server Error",
      "delivered_at": "2024-01-01T11:00:00Z",
      "attempts": 3,
      "error": "HTTP 500: Internal Server Error",
      "next_retry": null,
      "payload": {
        "event": "build.failed",
        "timestamp": "2024-01-01T11:00:00Z",
        "data": {
          "build_id": "build_122",
          "project_id": "proj_123",
          "status": "failed",
          "error": "Compilation error in main.js",
          "commit_sha": "def456ghi789",
          "branch": "feature/new-ui"
        }
      }
    }
  ],
  "total": 2,
  "pagination": {
    "limit": 20,
    "offset": 0,
    "has_more": false
  },
  "stats": {
    "total_deliveries": 150,
    "successful_deliveries": 145,
    "failed_deliveries": 5,
    "pending_deliveries": 0,
    "success_rate": 96.67
  }
}

重新投递 Webhook

http
POST /api/webhooks/{webhook_id}/deliveries/{delivery_id}/redeliver

响应

json
{
  "delivery_id": "del_new_999",
  "original_delivery_id": "del_788",
  "event_type": "build.failed",
  "status": "pending",
  "scheduled_at": "2024-01-01T12:00:00Z",
  "webhook_url": "https://api.example.com/webhooks/trae"
}

获取 Webhook 统计

http
GET /api/webhooks/{webhook_id}/stats?period={period}&start_date={start_date}&end_date={end_date}

查询参数

参数类型必需描述
periodstring统计周期 (hour/day/week/month)
start_datestring开始日期 (ISO 8601)
end_datestring结束日期 (ISO 8601)

响应

json
{
  "webhook_id": "webhook_456",
  "period": "day",
  "start_date": "2024-01-01T00:00:00Z",
  "end_date": "2024-01-07T23:59:59Z",
  "overall_stats": {
    "total_deliveries": 150,
    "successful_deliveries": 145,
    "failed_deliveries": 5,
    "pending_deliveries": 0,
    "success_rate": 96.67,
    "average_response_time": 250,
    "median_response_time": 200,
    "p95_response_time": 500
  },
  "daily_stats": [
    {
      "date": "2024-01-01",
      "total_deliveries": 25,
      "successful_deliveries": 24,
      "failed_deliveries": 1,
      "success_rate": 96.0,
      "average_response_time": 245
    },
    {
      "date": "2024-01-02",
      "total_deliveries": 30,
      "successful_deliveries": 29,
      "failed_deliveries": 1,
      "success_rate": 96.67,
      "average_response_time": 230
    }
  ],
  "event_type_stats": [
    {
      "event_type": "build.completed",
      "total_deliveries": 80,
      "successful_deliveries": 78,
      "failed_deliveries": 2,
      "success_rate": 97.5
    },
    {
      "event_type": "build.failed",
      "total_deliveries": 20,
      "successful_deliveries": 19,
      "failed_deliveries": 1,
      "success_rate": 95.0
    },
    {
      "event_type": "deployment.completed",
      "total_deliveries": 30,
      "successful_deliveries": 29,
      "failed_deliveries": 1,
      "success_rate": 96.67
    },
    {
      "event_type": "deployment.failed",
      "total_deliveries": 20,
      "successful_deliveries": 19,
      "failed_deliveries": 1,
      "success_rate": 95.0
    }
  ]
}

Webhook 载荷格式

所有 Webhook 载荷都遵循以下基本格式:

json
{
  "event": "event.type",
  "timestamp": "2024-01-01T12:00:00Z",
  "webhook_id": "webhook_456",
  "delivery_id": "del_789",
  "data": {
    // 事件特定数据
  }
}

构建事件载荷

build.started

json
{
  "event": "build.started",
  "timestamp": "2024-01-01T12:00:00Z",
  "webhook_id": "webhook_456",
  "delivery_id": "del_789",
  "data": {
    "build_id": "build_123",
    "project_id": "proj_123",
    "project_name": "My Project",
    "commit_sha": "abc123def456",
    "commit_message": "Fix bug in authentication",
    "branch": "main",
    "author": {
      "name": "Alice Johnson",
      "email": "alice@example.com",
      "username": "alice_dev"
    },
    "trigger": "push",
    "started_at": "2024-01-01T12:00:00Z",
    "environment": "production",
    "build_config": {
      "node_version": "18.x",
      "build_command": "npm run build",
      "output_directory": "dist"
    }
  }
}

build.completed

json
{
  "event": "build.completed",
  "timestamp": "2024-01-01T12:02:00Z",
  "webhook_id": "webhook_456",
  "delivery_id": "del_790",
  "data": {
    "build_id": "build_123",
    "project_id": "proj_123",
    "project_name": "My Project",
    "commit_sha": "abc123def456",
    "commit_message": "Fix bug in authentication",
    "branch": "main",
    "author": {
      "name": "Alice Johnson",
      "email": "alice@example.com",
      "username": "alice_dev"
    },
    "status": "success",
    "started_at": "2024-01-01T12:00:00Z",
    "completed_at": "2024-01-01T12:02:00Z",
    "duration": 120,
    "environment": "production",
    "artifacts": [
      {
        "name": "build-output.zip",
        "size": 1024576,
        "url": "https://cdn.trae.ai/builds/build_123/artifacts/build-output.zip"
      }
    ],
    "logs_url": "https://app.trae.ai/projects/proj_123/builds/build_123/logs",
    "deploy_preview_url": "https://build-123--my-project.trae.app"
  }
}

build.failed

json
{
  "event": "build.failed",
  "timestamp": "2024-01-01T12:01:30Z",
  "webhook_id": "webhook_456",
  "delivery_id": "del_791",
  "data": {
    "build_id": "build_124",
    "project_id": "proj_123",
    "project_name": "My Project",
    "commit_sha": "def456ghi789",
    "commit_message": "Add new feature",
    "branch": "feature/new-ui",
    "author": {
      "name": "Bob Smith",
      "email": "bob@example.com",
      "username": "bob_dev"
    },
    "status": "failed",
    "started_at": "2024-01-01T12:00:00Z",
    "failed_at": "2024-01-01T12:01:30Z",
    "duration": 90,
    "environment": "production",
    "error": {
      "type": "compilation_error",
      "message": "Compilation failed: Unexpected token in main.js:45",
      "details": {
        "file": "src/main.js",
        "line": 45,
        "column": 12,
        "code": "SyntaxError"
      }
    },
    "logs_url": "https://app.trae.ai/projects/proj_123/builds/build_124/logs"
  }
}

部署事件载荷

deployment.completed

json
{
  "event": "deployment.completed",
  "timestamp": "2024-01-01T12:05:00Z",
  "webhook_id": "webhook_456",
  "delivery_id": "del_792",
  "data": {
    "deployment_id": "deploy_123",
    "build_id": "build_123",
    "project_id": "proj_123",
    "project_name": "My Project",
    "environment": "production",
    "status": "success",
    "started_at": "2024-01-01T12:03:00Z",
    "completed_at": "2024-01-01T12:05:00Z",
    "duration": 120,
    "url": "https://my-project.trae.app",
    "commit_sha": "abc123def456",
    "commit_message": "Fix bug in authentication",
    "branch": "main",
    "author": {
      "name": "Alice Johnson",
      "email": "alice@example.com",
      "username": "alice_dev"
    },
    "deployed_by": {
      "name": "Alice Johnson",
      "email": "alice@example.com",
      "username": "alice_dev"
    },
    "deployment_config": {
      "strategy": "rolling",
      "instances": 3,
      "health_check_url": "/health"
    }
  }
}

协作事件载荷

collaboration.invited

json
{
  "event": "collaboration.invited",
  "timestamp": "2024-01-01T12:00:00Z",
  "webhook_id": "webhook_456",
  "delivery_id": "del_793",
  "data": {
    "invitation_id": "invite_123",
    "project_id": "proj_123",
    "project_name": "My Project",
    "inviter": {
      "name": "Alice Johnson",
      "email": "alice@example.com",
      "username": "alice_dev"
    },
    "invitee": {
      "email": "bob@example.com",
      "name": "Bob Smith"
    },
    "role": "developer",
    "permissions": [
      "read",
      "write",
      "build"
    ],
    "message": "Welcome to the team! Looking forward to working with you.",
    "expires_at": "2024-01-08T12:00:00Z",
    "invitation_url": "https://app.trae.ai/invitations/invite_123"
  }
}

文件事件载荷

file.updated

json
{
  "event": "file.updated",
  "timestamp": "2024-01-01T12:00:00Z",
  "webhook_id": "webhook_456",
  "delivery_id": "del_794",
  "data": {
    "file_id": "file_123",
    "project_id": "proj_123",
    "project_name": "My Project",
    "file_path": "src/components/Button.jsx",
    "file_name": "Button.jsx",
    "file_type": "javascript",
    "size": 2048,
    "updated_by": {
      "name": "Alice Johnson",
      "email": "alice@example.com",
      "username": "alice_dev"
    },
    "changes": {
      "lines_added": 15,
      "lines_removed": 8,
      "lines_modified": 3
    },
    "commit_sha": "abc123def456",
    "branch": "feature/button-improvements",
    "diff_url": "https://app.trae.ai/projects/proj_123/files/file_123/diff"
  }
}

安全事件载荷

security.alert

json
{
  "event": "security.alert",
  "timestamp": "2024-01-01T12:00:00Z",
  "webhook_id": "webhook_456",
  "delivery_id": "del_795",
  "data": {
    "alert_id": "alert_123",
    "alert_type": "suspicious_login",
    "severity": "high",
    "title": "Suspicious login attempt detected",
    "description": "Multiple failed login attempts from unusual location",
    "user": {
      "user_id": "user_123",
      "username": "alice_dev",
      "email": "alice@example.com"
    },
    "details": {
      "ip_address": "203.0.113.1",
      "location": "Unknown Location",
      "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
      "failed_attempts": 5,
      "time_window": "5 minutes"
    },
    "actions_taken": [
      "account_locked",
      "notification_sent"
    ],
    "recommended_actions": [
      "change_password",
      "enable_2fa",
      "review_account_activity"
    ]
  }
}

安全性

签名验证

Trae 使用 HMAC-SHA256 对 Webhook 载荷进行签名。签名包含在 X-Trae-Signature-256 请求头中。

验证签名 (Node.js)

javascript
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');
  
  const receivedSignature = signature.replace('sha256=', '');
  
  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature, 'hex'),
    Buffer.from(receivedSignature, 'hex')
  );
}

// Express.js 中间件示例
app.use('/webhooks/trae', express.raw({ type: 'application/json' }));

app.post('/webhooks/trae', (req, res) => {
  const signature = req.headers['x-trae-signature-256'];
  const payload = req.body;
  const secret = process.env.WEBHOOK_SECRET;
  
  if (!verifyWebhookSignature(payload, signature, secret)) {
    return res.status(401).send('Unauthorized');
  }
  
  // 处理 Webhook 事件
  const event = JSON.parse(payload);
  console.log('Received event:', event.event);
  
  res.status(200).send('OK');
});

验证签名 (Python)

python
import hmac
import hashlib
import json
from flask import Flask, request, abort

app = Flask(__name__)

def verify_webhook_signature(payload, signature, secret):
    expected_signature = hmac.new(
        secret.encode('utf-8'),
        payload,
        hashlib.sha256
    ).hexdigest()
    
    received_signature = signature.replace('sha256=', '')
    
    return hmac.compare_digest(expected_signature, received_signature)

@app.route('/webhooks/trae', methods=['POST'])
def handle_webhook():
    signature = request.headers.get('X-Trae-Signature-256')
    payload = request.get_data()
    secret = os.environ.get('WEBHOOK_SECRET')
    
    if not verify_webhook_signature(payload, signature, secret):
        abort(401)
    
    # 处理 Webhook 事件
    event = json.loads(payload)
    print(f'Received event: {event["event"]}')
    
    return 'OK', 200

其他安全头

请求头描述
X-Trae-Event事件类型
X-Trae-Delivery投递 ID
X-Trae-Webhook-IDWebhook ID
X-Trae-Timestamp时间戳
User-AgentTrae-Webhooks/1.0

重试策略

默认重试策略

  • 最大重试次数: 3
  • 退避策略: 指数退避
  • 初始延迟: 1 秒
  • 最大延迟: 60 秒
  • 重试条件: HTTP 状态码 >= 500 或网络错误

自定义重试策略

json
{
  "retry_policy": {
    "max_attempts": 5,
    "backoff_strategy": "exponential",
    "initial_delay": 2000,
    "max_delay": 300000,
    "retry_on_status": [500, 502, 503, 504],
    "retry_on_timeout": true
  }
}

退避策略

  • linear: 线性增长 (delay = initial_delay * attempt)
  • exponential: 指数增长 (delay = initial_delay * 2^(attempt-1))
  • fixed: 固定延迟 (delay = initial_delay)

示例

创建和管理 Webhook

javascript
// 创建 Webhook
const createWebhook = async (webhookData) => {
  const response = await fetch('/api/webhooks', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(webhookData)
  });
  
  const webhook = await response.json();
  
  if (response.ok) {
    console.log('Webhook 创建成功:', webhook.webhook_id);
    return webhook;
  } else {
    throw new Error(webhook.message);
  }
};

// 使用示例
try {
  const webhook = await createWebhook({
    url: 'https://api.myapp.com/webhooks/trae',
    events: [
      'build.completed',
      'build.failed',
      'deployment.completed',
      'deployment.failed'
    ],
    name: 'CI/CD Notifications',
    description: 'Receive build and deployment notifications',
    secret: 'my-webhook-secret-key',
    active: true,
    project_id: 'proj_123',
    headers: {
      'X-API-Key': 'my-api-key'
    },
    timeout: 30,
    retry_policy: {
      max_attempts: 3,
      backoff_strategy: 'exponential',
      initial_delay: 1000,
      max_delay: 60000
    }
  });
  
  console.log('Webhook URL:', webhook.url);
  console.log('订阅事件:', webhook.events);
} catch (error) {
  console.error('创建 Webhook 失败:', error.message);
}

处理 Webhook 事件

javascript
// Express.js Webhook 处理器
const express = require('express');
const crypto = require('crypto');
const app = express();

// 中间件:原始载荷解析
app.use('/webhooks/trae', express.raw({ type: 'application/json' }));

// Webhook 处理器
app.post('/webhooks/trae', (req, res) => {
  try {
    // 验证签名
    const signature = req.headers['x-trae-signature-256'];
    const payload = req.body;
    const secret = process.env.WEBHOOK_SECRET;
    
    if (!verifyWebhookSignature(payload, signature, secret)) {
      console.error('Webhook 签名验证失败');
      return res.status(401).send('Unauthorized');
    }
    
    // 解析事件
    const event = JSON.parse(payload);
    const eventType = event.event;
    const eventData = event.data;
    
    console.log(`收到 Webhook 事件: ${eventType}`);
    
    // 根据事件类型处理
    switch (eventType) {
      case 'build.completed':
        handleBuildCompleted(eventData);
        break;
        
      case 'build.failed':
        handleBuildFailed(eventData);
        break;
        
      case 'deployment.completed':
        handleDeploymentCompleted(eventData);
        break;
        
      case 'deployment.failed':
        handleDeploymentFailed(eventData);
        break;
        
      case 'collaboration.invited':
        handleCollaborationInvited(eventData);
        break;
        
      case 'security.alert':
        handleSecurityAlert(eventData);
        break;
        
      default:
        console.log(`未处理的事件类型: ${eventType}`);
    }
    
    // 返回成功响应
    res.status(200).send('OK');
    
  } catch (error) {
    console.error('处理 Webhook 事件时出错:', error);
    res.status(500).send('Internal Server Error');
  }
});

// 事件处理函数
function handleBuildCompleted(data) {
  console.log(`构建完成: ${data.build_id}`);
  console.log(`项目: ${data.project_name}`);
  console.log(`分支: ${data.branch}`);
  console.log(`持续时间: ${data.duration}秒`);
  
  // 发送通知到 Slack
  sendSlackNotification({
    text: `✅ 构建成功`,
    attachments: [{
      color: 'good',
      fields: [
        { title: '项目', value: data.project_name, short: true },
        { title: '分支', value: data.branch, short: true },
        { title: '提交', value: data.commit_sha.substring(0, 7), short: true },
        { title: '持续时间', value: `${data.duration}秒`, short: true }
      ],
      actions: [{
        type: 'button',
        text: '查看构建',
        url: data.logs_url
      }, {
        type: 'button',
        text: '预览部署',
        url: data.deploy_preview_url
      }]
    }]
  });
}

function handleBuildFailed(data) {
  console.log(`构建失败: ${data.build_id}`);
  console.log(`项目: ${data.project_name}`);
  console.log(`错误: ${data.error.message}`);
  
  // 发送通知到 Slack
  sendSlackNotification({
    text: `❌ 构建失败`,
    attachments: [{
      color: 'danger',
      fields: [
        { title: '项目', value: data.project_name, short: true },
        { title: '分支', value: data.branch, short: true },
        { title: '提交', value: data.commit_sha.substring(0, 7), short: true },
        { title: '错误', value: data.error.message, short: false }
      ],
      actions: [{
        type: 'button',
        text: '查看日志',
        url: data.logs_url
      }]
    }]
  });
}

function handleDeploymentCompleted(data) {
  console.log(`部署完成: ${data.deployment_id}`);
  console.log(`环境: ${data.environment}`);
  console.log(`URL: ${data.url}`);
  
  // 发送邮件通知
  sendEmailNotification({
    to: data.author.email,
    subject: `部署成功 - ${data.project_name}`,
    template: 'deployment-success',
    data: {
      project_name: data.project_name,
      environment: data.environment,
      url: data.url,
      commit_message: data.commit_message,
      author_name: data.author.name
    }
  });
}

function handleSecurityAlert(data) {
  console.log(`安全警报: ${data.alert_type}`);
  console.log(`严重程度: ${data.severity}`);
  console.log(`用户: ${data.user.username}`);
  
  // 立即通知安全团队
  sendSecurityAlert({
    alert_id: data.alert_id,
    alert_type: data.alert_type,
    severity: data.severity,
    user: data.user,
    details: data.details,
    actions_taken: data.actions_taken
  });
}

// 辅助函数
function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');
  
  const receivedSignature = signature.replace('sha256=', '');
  
  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature, 'hex'),
    Buffer.from(receivedSignature, 'hex')
  );
}

function sendSlackNotification(message) {
  // 实现 Slack 通知逻辑
  console.log('发送 Slack 通知:', message.text);
}

function sendEmailNotification(email) {
  // 实现邮件通知逻辑
  console.log('发送邮件通知:', email.subject);
}

function sendSecurityAlert(alert) {
  // 实现安全警报逻辑
  console.log('发送安全警报:', alert.alert_type);
}

app.listen(3000, () => {
  console.log('Webhook 服务器运行在端口 3000');
});

监控和统计

javascript
// 获取 Webhook 统计
const getWebhookStats = async (webhookId, period = 'day') => {
  const response = await fetch(`/api/webhooks/${webhookId}/stats?period=${period}`, {
    headers: {
      'Authorization': `Bearer ${accessToken}`
    }
  });
  
  const stats = await response.json();
  
  if (response.ok) {
    return stats;
  } else {
    throw new Error(stats.message);
  }
};

// 监控 Webhook 健康状态
const monitorWebhookHealth = async (webhookId) => {
  try {
    const stats = await getWebhookStats(webhookId);
    const successRate = stats.overall_stats.success_rate;
    const avgResponseTime = stats.overall_stats.average_response_time;
    
    console.log(`Webhook ${webhookId} 健康状态:`);
    console.log(`- 成功率: ${successRate}%`);
    console.log(`- 平均响应时间: ${avgResponseTime}ms`);
    
    // 健康状态检查
    if (successRate < 95) {
      console.warn('⚠️ 成功率低于 95%,需要检查');
      
      // 获取最近的失败投递
      const deliveries = await getWebhookDeliveries(webhookId, {
        status: 'failed',
        limit: 10
      });
      
      console.log('最近的失败投递:');
      deliveries.deliveries.forEach(delivery => {
        console.log(`- ${delivery.event_type}: ${delivery.error}`);
      });
    }
    
    if (avgResponseTime > 5000) {
      console.warn('⚠️ 平均响应时间超过 5 秒,可能存在性能问题');
    }
    
    return {
      healthy: successRate >= 95 && avgResponseTime <= 5000,
      successRate,
      avgResponseTime
    };
    
  } catch (error) {
    console.error('获取 Webhook 统计失败:', error.message);
    return { healthy: false, error: error.message };
  }
};

// 定期健康检查
setInterval(async () => {
  const webhooks = await getWebhooks();
  
  for (const webhook of webhooks.webhooks) {
    if (webhook.active) {
      const health = await monitorWebhookHealth(webhook.webhook_id);
      
      if (!health.healthy) {
        console.error(`Webhook ${webhook.name} 不健康:`, health);
        
        // 发送警报
        await sendAlert({
          type: 'webhook_unhealthy',
          webhook_id: webhook.webhook_id,
          webhook_name: webhook.name,
          details: health
        });
      }
    }
  }
}, 5 * 60 * 1000); // 每 5 分钟检查一次

测试 Webhook

javascript
// 测试 Webhook
const testWebhook = async (webhookId, eventType = 'test.ping') => {
  const response = await fetch(`/api/webhooks/${webhookId}/test`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      event_type: eventType,
      payload: {
        test: true,
        timestamp: new Date().toISOString(),
        message: 'This is a test webhook delivery'
      }
    })
  });
  
  const result = await response.json();
  
  if (response.ok) {
    console.log('Webhook 测试成功:');
    console.log(`- 投递 ID: ${result.delivery_id}`);
    console.log(`- 状态: ${result.status}`);
    console.log(`- 响应码: ${result.response_code}`);
    console.log(`- 响应时间: ${result.response_time}ms`);
    
    return result;
  } else {
    throw new Error(result.message);
  }
};

// 批量测试所有 Webhook
const testAllWebhooks = async () => {
  try {
    const webhooks = await getWebhooks({ active: true });
    
    console.log(`测试 ${webhooks.webhooks.length} 个活跃的 Webhook...`);
    
    for (const webhook of webhooks.webhooks) {
      console.log(`\n测试 Webhook: ${webhook.name}`);
      
      try {
        const result = await testWebhook(webhook.webhook_id);
        
        if (result.status === 'success') {
          console.log('✅ 测试通过');
        } else {
          console.log('❌ 测试失败:', result.error);
        }
      } catch (error) {
        console.log('❌ 测试出错:', error.message);
      }
    }
  } catch (error) {
    console.error('批量测试失败:', error.message);
  }
};

// 使用示例
testAllWebhooks();

您的终极 AI 驱动 IDE 学习指南