本文目录导读:

- 最常见的方案:Python + Flask/FastAPI
- 更轻量的选择:Node.js (Express)
- 面向配置的脚本:Shell + 第三方工具 (如
webhook) - 无服务器方案:云函数(如 AWS Lambda、阿里云函数计算)
- 关键考量与最佳实践
- 实用场景举例
是的,实用脚本完全可以自动处理Webhook。Webhook 的本质就是 HTTP 回调,任何能监听 HTTP 请求的脚本都能处理它。
最常见的方案是通过轻量级 HTTP 服务器或云函数来实现,以下是几种实用的脚本处理方式:
最常见的方案:Python + Flask/FastAPI
这是最灵活且易于上手的方案,适合处理 GitHub、Stripe、Slack 等各类 Webhook。
示例:自动接收 GitHub Webhook 并执行部署脚本
from flask import Flask, request, jsonify
import subprocess
import hmac
import hashlib
app = Flask(__name__)
# 从环境变量读取你的 Secret Token
SECRET_TOKEN = "your_webhook_secret"
@app.route('/webhook', methods=['POST'])
def handle_webhook():
# 1. 验证签名(确保来源可信)
signature = request.headers.get('X-Hub-Signature-256', '')
body = request.get_data()
expected_signature = 'sha256=' + hmac.new(SECRET_TOKEN.encode(), body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(signature, expected_signature):
return jsonify({"error": "Invalid signature"}), 401
# 2. 解析事件
event = request.headers.get('X-GitHub-Event', '')
payload = request.json
# 3. 触发具体操作(例如只处理推送事件)
if event == 'push' and payload.get('ref') == 'refs/heads/main':
# 执行部署脚本
result = subprocess.run(['/path/to/deploy.sh'], capture_output=True, text=True)
print(f"Deploy stdout: {result.stdout}")
return jsonify({"status": "deployed", "message": result.stdout})
return jsonify({"status": "ignored", "event": event})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, ssl_context='adhoc') # 建议使用 HTTPS
运行方式:
pip install flask python webhook_listener.py
更轻量的选择:Node.js (Express)
适合前端或 Node.js 开发者,代码量更少。
const express = require('express');
const crypto = require('crypto');
const { exec } = require('child_process');
const app = express();
// 必须使用 raw body 来验证签名
app.use(express.json({
verify: (req, res, buf) => { req.rawBody = buf; }
}));
const SECRET = process.env.WEBHOOK_SECRET;
app.post('/webhook', (req, res) => {
// 签名验证
const sig = req.headers['x-hub-signature-256'];
const computed = 'sha256=' + crypto.createHmac('sha256', SECRET).update(req.rawBody).digest('hex');
if (sig !== computed) return res.status(401).send('Unauthorized');
const event = req.headers['x-github-event'];
const payload = req.body;
if (event === 'push' && payload.ref === 'refs/heads/main') {
exec('/path/to/deploy.sh', (err, stdout, stderr) => {
console.log(stdout);
res.json({ status: 'deployed' });
});
} else {
res.json({ status: 'skipped' });
}
});
app.listen(3000, () => console.log('Webhook server on port 3000'));
面向配置的脚本:Shell + 第三方工具 (如 webhook)
如果你不想写代码,可以使用现成的 Webhook 工具。webhook 是一个 Go 语言编写的工具,只需一个 YAML 配置文件。
安装:
# Linux/Mac sudo apt install webhook # 或 brew install webhook
配置文件 hooks.yaml:
- id: deploy
execute-command: /path/to/deploy.sh
command-working-directory: /var/www/myapp
trigger-rule:
match:
type: value
value: refs/heads/main
parameter:
source: payload
name: ref
response-message: "Deployment started"
http-methods: [POST]
运行:
webhook -hooks hooks.yaml -port 9000 -verbose -ip 0.0.0.0
无服务器方案:云函数(如 AWS Lambda、阿里云函数计算)
适合不想维护服务器的场景,脚本会被自动触发。
Python 示例(AWS Lambda):
import json
def lambda_handler(event, context):
# 从 API Gateway 传入的事件中提取
body = json.loads(event['body'])
print(f"Received webhook: {body}")
# 处理逻辑,比如发送邮件、更新数据库等
# ...
return {
'statusCode': 200,
'body': json.dumps('Webhook processed')
}
关键考量与最佳实践
-
安全性第一!
- 验证签名:几乎所有 Webhook 都支持 Secret Token,必须验证签名才能执行后续操作。
- 使用 HTTPS:如果脚本暴露在公网,务必使用 HTTPS。
- IP 白名单:只允许已知的 Webhook 提供商 IP 访问。
-
处理幂等性
- Webhook 可能会重试,确保你的脚本结果幂等(多次执行与一次执行结果相同)。
-
异步与超时
- Webhook 通常要求 5-10 秒内响应,如果任务耗时较长(如拉取代码、构建项目),先返回
200响应,然后后台异步处理。
- Webhook 通常要求 5-10 秒内响应,如果任务耗时较长(如拉取代码、构建项目),先返回
-
日志与调试
记录所有收到的 Webhook 请求体和头部信息,方便排查问题。
实用场景举例
- Git Push → 自动部署:接收到
push事件后,运行部署脚本。 - Stripe 支付成功 → 更新订单状态:收到
checkout.session.completed后,更新数据库。 - Telegram Bot → 自动回复:用脚本监听 Telegram 的 Webhook 并回复。
- CI/CD 通知 → 更新 Slack 状态:从 GitHub Actions 收到 Webhook 后在 Slack 发消息。
实用脚本完全能胜任 Webhook 处理工作。 推荐使用 Python (Flask) 或 Go (webhook 工具),根据你的技术栈选择,难点通常不在脚本本身,而在于安全验证、可靠部署和响应超时管理。