☰
Webhook:把一次 HTTP POST 变成一条 shell 命令,5 分钟跑通
2026/11/4 7:04:04 网站建设 项目流程

Webhook:把一次 HTTP POST 变成一条 shell 命令,5 分钟跑通

【免费下载链接】webhookwebhook is a lightweight incoming webhook server to run shell commands项目地址: https://gitcode.com/gh_mirrors/we/webhook

webhook 是一个用 Go 写的轻量级入站 Webhook 服务器:在配置里声明 HTTP 端点,触发后执行本地命令。下面跑通最小链路,再接 GitHub 和 Slack 两个场景,覆盖 Webhook 配置、签名验证与传参给脚本;反向代理、systemd 部署不展开。

先跑通:一条 curl 触发本地脚本

先把最短的 hooks.json 存下来,内容只有一个 hook 对象:

[{ "id": "redeploy-webhook", "execute-command": "redeploy.sh", "command-working-directory": "/var/webhook" }]

启动服务并发送一次 POST,redeploy.sh会被立即执行:

webhook -hooks hooks.json -verbose # 启动,默认监听 9000 端口 # 下面这条请求命中 /hooks/redeploy-webhook,脚本随之执行 curl -X POST http://localhost:9000/hooks/redeploy-webhook

✅ 此刻你已有「请求进、命令出」的完整链路。接下来给它加上规则和参数。

Webhook 配置骨架:6 个字段速览

字段作用一句话说明内联示例
id端点路径决定 URL 是/hooks/<id>"id": "redeploy-webhook"
execute-command执行的命令只放可执行文件路径,参数必须另配"execute-command": "redeploy.sh"
command-working-directory脚本工作目录同时决定相对命令的查找位置"command-working-directory": "/var/webhook"
response-message回给调用方命令完成后才返回的输出不走这里"response-message": "OK"
pass-arguments-to-command传参给脚本把请求值变成命令行参数{"source": "payload", "name": "ref"}
trigger-rule触发条件签名、token、IP 校验全在这"and": [ ... ]

完整字段(含http-methods、include-command-output-in-response等)以 Hook 定义页为准,这里不逐字段展开。

GitHub Webhook 触发命令:怎么配、签名怎么验

场景:代码推到 master 时,自动在服务器跑部署脚本。

触发条件用and组合两条规则:先验签名,再限定分支。

"trigger-rule": { "and": [ { "match": { "type": "payload-hmac-sha1", "secret": "mysecret", "parameter": { "source": "header", "name": "X-Hub-Signature" } } }, { "match": { "type": "value", "value": "refs/heads/master", "parameter": { "source": "payload", "name": "ref" } } } ] }

签名验证:GitHub 侧的 Secret token 必须与配置里的secret完全一致;请求头X-Hub-Signature的值带sha1=前缀,若用逗号传了多个签名,webhook 会逐个尝试直到匹配。

一个踩坑点:2.8 及以上版本签名类型写payload-hmac-sha1,老版本写payload-hash-sha1。写错类型不会报错,而是签名永远不匹配,表现为请求全部被拒。

Slack 斜杠命令:触发怎么配、token 怎么验

场景:在 Slack 频道里敲一条斜杠命令,后台跑你的脚本并立刻回执。

{ "id": "slack-command", "execute-command": "/scripts/slack-command.sh", "response-message": "已收到,后台执行中", "trigger-rule": { "match": { "type": "value", "value": "YOUR-TOKEN", "parameter": { "source": "payload", "name": "token" } } } }

token 验证:Slack 配置斜杠命令时生成的 Token 本身就是凭证,直接做value匹配,不需要 HMAC。

一个踩坑点:Slack 要求 3 秒内收到响应。默认情况下 webhook 在后台执行命令并立即返回response-message,长任务因此不会超时;但回执文本只会在频道显示这一次,建议保持短句。

让数据流进来:Webhook 传参给脚本

取值语法:规则与pass-arguments-to-command共用同一套点号路径,数组按下标、XML 属性用-前缀、节点文本用#text。

想取的值name写法备注
第一个提交的 idcommits.0.commit.id数组用数字下标
数组 payload 的第二项事件root.1.event数组体被包进root对象
XML 的 user 属性app.users.user.0.-name属性加-,文本加#text
整个请求体source用entire-payload原样交给脚本

文件传递:二进制放在 payload 里是 base64 字符串,直接当参数会撑爆 argv 长度,写成临时文件更稳;base64decode负责解码,脚本通过envname指定的环境变量拿到文件路径。

"pass-file-to-command": [ { "source": "payload", "name": "binary", "envname": "FILE_DATA", "base64decode": true } ]

非 JSON 体:有些平台把 JSON 当字符串塞在普通字段里(如 Travis 的payload、multipart 的某个 part),点号取值会拿到整个字符串,必须先解析成对象。

"parse-parameters-as-json": [ { "source": "payload", "name": "payload" } ]

⚠️必须配 trigger-rule:没有规则的 hook 等于「知道 URL 就能执行你的命令」。

  • secret 不要硬编码:用-template参数把密钥经模板注入,配置文件只留占位符
  • 建议限定http-methods:只放行POST,拦截 GET 探测
  • 可选 IP 白名单:藏在反向代理后面时,ip-whitelist验到的是代理 IP,必须改在代理层限制来源
  • 命令用最小权限:靠command-working-directory圈定活动范围,脚本以非 root 账号运行

调不通时先看这里

现象最可能原因一条验证命令
404Hook not found.URL 的 id 与配置里的id不一致curl -i http://localhost:9000/hooks/<id>
Hook rules were not satisfied.secret/token 与平台侧不一致echo -n "$BODY" \| openssl dgst -sha1 -hmac "$SECRET"与请求头比对
命令没执行,返回 500execute-command路径不存在或无执行权限ls -l /var/webhook/redeploy.sh
命令跑了但 payload 取值全空请求没带Content-Type: application/jsoncurl -H "Content-Type: application/json" -X POST -d @body.json http://localhost:9000/hooks/<id>

不想把密钥硬编码进配置文件,就上-template参数用 Go 模板注入,用法见 docs/Templates.md。再深的兼容问题,直接去项目 issue 区按trigger-rule搜,多数场景已有答案。

【免费下载链接】webhookwebhook is a lightweight incoming webhook server to run shell commands项目地址: https://gitcode.com/gh_mirrors/we/webhook

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询