Webhook 指的是这样一种模式:执行开启的不是我们的控制器,而是您自己的系统——Home Assistant、局域网里的继电器、您自己的服务器。Webhook 对象有两种模式: 应用 ——由手机自己向您的地址发起 HTTP 请求,并把取值填进地址模板; 服务器 ——由我们的服务器发送带签名的 POST,也就是本页所讲的内容。现成的接收端: curl, Flask, Home Assistant, Node.js.
请求
开启时,Entrixy 服务器会发送一个 POST 到您的 webhook_url ,正文为 JSON:
POST <your webhook_url>
Content-Type: application/json
{
"action": "open",
"object_id": 42,
"timestamp": 1750000000,
"nonce": "0011223344556677",
"signature": "9d7b58066094fa88..."
}
| 字段 | 取值 |
|---|---|
action | "open" (双稳态对象还会有 "close") |
object_id | 该对象在您账户中的 id |
timestamp | 发送时刻的 unix 时间,单位秒 |
nonce | 16 个十六进制字符(8 个随机字节),一次性 |
signature | HMAC-SHA256,见下文 |
字段 timestamp, nonce 与 signature 只有在该对象设置了 webhook_secret时才会出现。没有密钥时,正文只包含 {action, object_id}.
签名
被签名的是一个 规范化字符串 ,由四个以点号分隔的字段组成,而不是 JSON 正文本身,因此您不必逐字节复刻我们的序列化方式:
base = "<timestamp>.<nonce>.<action>.<object_id>" signature = HMAC-SHA256(webhook_secret, base) // hex
webhook_secret 在应用中创建 Webhook 对象时设定。访客永远拿不到它——服务器会用您的密钥代为签名。
如何校验(在您这一侧)
- 构造同样的字符串
base = timestamp.nonce.action.object_id——用您收到的字段。 - 计算
HMAC-SHA256(webhook_secret, base),再与signature做常数时间比较(hash_equals/hmac.compare_digest). - 防重放: 若
|now − timestamp| > 300秒,则拒绝该请求。也可以保存最近的nonce值,并拒绝重复的。 - 签名一致且请求未过期——执行开启。
Webhook 地址通常是无需认证就能访问的,因此 校验签名是必须的。请使用至少 16 个字符的密钥,最好直接生成一个:
openssl rand -hex 32.测试向量
用这些取值跑一遍您的校验流程,核对签名:
webhook_secret = webhook_secret_example_key timestamp = 1750000000 nonce = 0011223344556677 action = open object_id = 42 base = 1750000000.0011223344556677.open.42 signature = 9d7b58066094fa88acc0afa7aa805fc5f0d008d33cb11b8aa2366102da8e20f1 = HMAC-SHA256(webhook_secret, base)
响应(可选)
请返回 200 OK。若想让应用显示结果,请返回 JSON {"level":"success","message":"..."} (level: success/warning/danger/info)。否则只返回 200 即可。
现成的接收端
curl (测试发送与校验), Flask 与 Node.js (服务骨架), Home Assistant (带 HMAC 的 Webhook 自动化)。不支持 HMAC 的继电器(Shelly、Tasmota)需要经由 代理或 Home Assistant 接入.