webhook订阅设备上下线,有的参数为空

emqx:5.3.2,开源版本,使用了webhook设备上线后,访问webhook的url,直接输出(直接全部输出),s设备下线也是

收到Webhook请求: {
headers: {
‘content-length’: ‘346’,
host: ‘127.0.0.1:3000’,
‘content-type’: ‘application/json’
},
body: {
username: ‘IotApp/nFN8_yX9bP’,
ts: ‘undefined’,
clientid: ‘IotApp/nFN8_yX9bP’,
topic: ‘$SYS/brokers/+/clients/#’,
action: ‘undefined’,
ip: ‘undefined’,
protocol: { name: ‘MQTT’, version: ‘4’ },
connected_at: ‘1747062348147’,
disconnected_at: ‘undefined’,
reason: ‘undefined’
}
}
POST /emqx_web_hook 200 19.560 ms - 2
收到Webhook请求: {
headers: {
‘content-length’: ‘342’,
host: ‘127.0.0.1:3000’,
‘content-type’: ‘application/json’
},
body: {
username: ‘IotApp/nFN8_yX9bP’,
ts: ‘undefined’,
clientid: ‘IotApp/nFN8_yX9bP’,
topic: ‘$SYS/brokers/+/clients/#’,
action: ‘undefined’,
ip: ‘undefined’,
protocol: { name: ‘MQTT’, version: ‘4’ },
connected_at: ‘undefined’,
disconnected_at: ‘undefined’,
reason: ‘undefined’
}
}
POST /emqx_web_hook 200 3.013 ms - 2
收到Webhook请求: {
headers: {
‘content-length’: ‘346’,
host: ‘127.0.0.1:3000’,
‘content-type’: ‘application/json’
},
body: {
username: ‘IotApp/nFN8_yX9bP’,
ts: ‘undefined’,
clientid: ‘IotApp/nFN8_yX9bP’,
topic: ‘$SYS/brokers/+/clients/#’,
action: ‘undefined’,
ip: ‘undefined’,
protocol: { name: ‘MQTT’, version: ‘4’ },
connected_at: ‘undefined’,
disconnected_at: ‘1747062348147’,
reason: ‘takenover’
}
}
POST /emqx_web_hook 200 4.420 ms - 2
收到Webhook请求: {
headers: {
‘content-length’: ‘353’,
host: ‘127.0.0.1:3000’,
‘content-type’: ‘application/json’
},
body: {
username: ‘IotApp/nFN8_yX9bP’,
ts: ‘undefined’,
clientid: ‘IotApp/nFN8_yX9bP’,
topic: ‘$SYS/brokers/+/clients/#’,
action: ‘publish’,
ip: ‘undefined’,
protocol: { name: ‘undefined’, version: ‘undefined’ },
connected_at: ‘undefined’,
disconnected_at: ‘undefined’,
reason: ‘undefined’
}
}
POST /emqx_web_hook 200 6.185 ms - 2
收到Webhook请求: {
headers: {
‘content-length’: ‘355’,
host: ‘127.0.0.1:3000’,
‘content-type’: ‘application/json’
},
body: {
username: ‘IotApp/nFN8_yX9bP’,
ts: ‘undefined’,
clientid: ‘IotApp/nFN8_yX9bP’,
topic: ‘$SYS/brokers/+/clients/#’,
action: ‘undefined’,
ip: ‘undefined’,
protocol: { name: ‘undefined’, version: ‘undefined’ },
connected_at: ‘undefined’,
disconnected_at: ‘undefined’,
reason: ‘undefined’
}
}
POST /emqx_web_hook 200 4.410 ms - 2
收到Webhook请求: {
headers: {
‘content-length’: ‘360’,
host: ‘127.0.0.1:3000’,
‘content-type’: ‘application/json’
},
body: {
username: ‘IotApp/nFN8_yX9bP’,
ts: ‘undefined’,
clientid: ‘IotApp/nFN8_yX9bP’,
topic: ‘$SYS/brokers/+/clients/#’,
action: ‘undefined’,
ip: ‘undefined’,
protocol: { name: ‘undefined’, version: ‘undefined’ },
connected_at: ‘undefined’,
disconnected_at: ‘undefined’,
reason: ‘no_subscribers’
}
}
POST /emqx_web_hook 200 4.316 ms - 2
收到Webhook请求: {
headers: {
‘content-length’: ‘353’,
host: ‘127.0.0.1:3000’,
‘content-type’: ‘application/json’
},
body: {
username: ‘IotApp/nFN8_yX9bP’,
ts: ‘undefined’,
clientid: ‘IotApp/nFN8_yX9bP’,
topic: ‘$SYS/brokers/+/clients/#’,
action: ‘publish’,
ip: ‘undefined’,
protocol: { name: ‘undefined’, version: ‘undefined’ },
connected_at: ‘undefined’,
disconnected_at: ‘undefined’,
reason: ‘undefined’
}
}
POST /emqx_web_hook 200 4.487 ms - 2
收到Webhook请求: {
headers: {
‘content-length’: ‘355’,
host: ‘127.0.0.1:3000’,
‘content-type’: ‘application/json’
},
body: {
username: ‘IotApp/nFN8_yX9bP’,
ts: ‘undefined’,
clientid: ‘IotApp/nFN8_yX9bP’,
topic: ‘$SYS/brokers/+/clients/#’,
action: ‘undefined’,
ip: ‘undefined’,
protocol: { name: ‘undefined’, version: ‘undefined’ },
connected_at: ‘undefined’,
disconnected_at: ‘undefined’,
reason: ‘undefined’
}
}
POST /emqx_web_hook 200 5.060 ms - 2
收到Webhook请求: {
headers: {
‘content-length’: ‘360’,
host: ‘127.0.0.1:3000’,
‘content-type’: ‘application/json’
},
body: {
username: ‘IotApp/nFN8_yX9bP’,
ts: ‘undefined’,
clientid: ‘IotApp/nFN8_yX9bP’,
topic: ‘$SYS/brokers/+/clients/#’,
action: ‘undefined’,
ip: ‘undefined’,
protocol: { name: ‘undefined’, version: ‘undefined’ },
connected_at: ‘undefined’,
disconnected_at: ‘undefined’,
reason: ‘no_subscribers’
}
}
POST /emqx_web_hook 200 4.060 ms - 2
收到Webhook请求: {
headers: {
‘content-length’: ‘343’,
host: ‘127.0.0.1:3000’,
‘content-type’: ‘application/json’
},
body: {
username: ‘IotApp/nFN8_yX9bP’,
ts: ‘undefined’,
clientid: ‘IotApp/nFN8_yX9bP’,
topic: ‘$SYS/brokers/+/clients/#’,
action: ‘undefined’,
ip: ‘undefined’,
protocol: { name: ‘MQTT’, version: ‘4’ },
connected_at: ‘undefined’,
disconnected_at: ‘1747062353156’,
reason: ‘normal’
}
},
这是 Payload
{
“username”: “${username}”,
“ts”: “${ts}”,
“clientid”: “${clientid}”,
“topic”: “$SYS/brokers/+/clients/#”,
“action”: “${action}”,
“ip”: “${ipaddress}”,
“protocol”: {
“name”: “${proto_name}”,
“version”: “${proto_ver}”
},
“connected_at”: “${connected_at}”,
“disconnected_at”: “${disconnected_at}”,
“reason”: “${reason}”
}

不要from #

还是一样的输出

告诉你一个调试小技巧:

用 MQTTX 订阅一下 $SYS/brokers/+/clients/# 然后看他的结果是什么,


你设置的的 action是没有的
disconnected_at 和 connected_at 也不是所有事件都有的。
要是你需要在 emqx 侧区分不同的事件,就用多个 webhook 来做,不过,我还是建议直接不改 payload,所有的事件都通过一个 webhook 传给你的 http server ,在你的 http server 做区分事件。

使用$SYS/brokers/+/clients/#:
输出

{“username”:“jwt_user”,“ts”:1747121362098,“topic”:“$SYS/brokers/+/clients/#”,“subopts”:{“sub_props”:{},“rh”:0,“rap”:0,“qos”:0,“nl”:0,“is_new”:true},“protocol”:“mqtt”,“clientid”:“mqttjs_2b845a4a”}
{“username”:“IotApp/nFN8_yX9bP”,“ts”:1747121366956,“sockport”:1883,“reason”:“takenover”,“protocol”:“mqtt”,“proto_ver”:4,“proto_name”:“MQTT”,“ipaddress”:“127.0.0.1”,“disconnected_at”:1747121366956,“connected_at”:1747121029035,“clientid”:“IotApp/nFN8_yX9bP”}
{“username”:“IotApp/nFN8_yX9bP”,“ts”:1747121366956,“sockport”:1883,“protocol”:“mqtt”,“proto_ver”:4,“proto_name”:“MQTT”,“keepalive”:60,“ipaddress”:“127.0.0.1”,“expiry_interval”:7200000,“connected_at”:1747121366956,“clientid”:“IotApp/nFN8_yX9bP”,“clean_start”:false}没有undefined,也没有重复发送

这里面是没有 undefined 的。
你自己写的 playload 模块里面啊

这个${} 就是要取上面你输出有的字段。如果没有的话他就会返回 undefined 的

不过我已经忘记了以前的 webhook 是什么样子的了(在哪里设置 payload)

新版本的(v5.8.6)是直接不需要(不能)设置这些模版的。

你可以看下我的问题的输出,他是有值的,比如version,有的时候是4,有的时候是undefined

事件不一样就是不会有的。
可以试试上面的方法:用 MQTTX 同时订阅。然后看完整的消息结构去匹配你写的模板看是不是应该为 undefined

我的也是这样的界面,但是如果不设置模板的话,

POST /emqx_web_hook 400 2.227 ms - 33
收到Webhook请求: {
headers: {
‘content-length’: ‘488’,
host: ‘127.0.0.1:3000’,
‘content-type’: ‘application/json’
},
body: {
username: ‘IotApp/nFN8_yX9bP’,
topic: ‘get/IotApp/nFN8_yX9bP/$tags/6822f86daff4c93582fda3d1’,
timestamp: 1747122285331,
reason: ‘no_subscribers’,
qos: 1,
publish_received_at: 1747122285331,
pub_props: { ‘User-Property’: {} },
peerhost: ‘127.0.0.1’,
payload: ‘{“tags”:,“tags_version”:0}’,
node: ‘emqx@127.0.0.1’,
metadata: { rule_id: ‘webhook_WH_D’ },
id: ‘000634FF9B324358F445000031E00002’,
flags: { retain: false, dup: false },
event: ‘message.dropped’,
clientid: ‘IotApp/nFN8_yX9bP’
}
}
非法请求: 缺少action字段

我的mqttx订阅有点问题,我是用用代码测试

client.on(‘connect’, function () {
console.log(“Connected to MQTT broker”);
client.subscribe(“$SYS/brokers/+/clients/#”); // 监听所有客户端连接/断开事件
console.log(“Subscribed to system topics”);
});
可以输出正确的值:
Subscribed to system topics
{“username”:“jwt_user”,“ts”:1747121362098,“topic”:“$SYS/brokers/+/clients/#”,“subopts”:{“sub_props”:{},“rh”:0,“rap”:0,“qos”:0,“nl”:0,“is_new”:true},“protocol”:“mqtt”,“clientid”:“mqttjs_2b845a4a”}
{“username”:“IotApp/nFN8_yX9bP”,“ts”:1747121366956,“sockport”:1883,“reason”:“takenover”,“protocol”:“mqtt”,“proto_ver”:4,“proto_name”:“MQTT”,“ipaddress”:“127.0.0.1”,“disconnected_at”:1747121366956,“connected_at”:1747121029035,“clientid”:“IotApp/nFN8_yX9bP”}
{“username”:“IotApp/nFN8_yX9bP”,“ts”:1747121366956,“sockport”:1883,“protocol”:“mqtt”,“proto_ver”:4,“proto_name”:“MQTT”,“keepalive”:60,“ipaddress”:“127.0.0.1”,“expiry_interval”:7200000,“connected_at”:1747121366956,“clientid”:“IotApp/nFN8_yX9bP”,“clean_start”:false}

这个无法订阅是默认的 acl 不让127.0.0.1 外的客户订阅 sys 主题,你可以临时把他关掉。

登录


连接设备后

断开设备:

SQL:SELECT
*,
CASE
WHEN topic = ‘$events/client_connected’ THEN ‘connect’
WHEN topic = ‘$events/client_disconnected’ THEN ‘disconnect’
END AS action,
clientid,
username,
timestamp
FROM
“$events/client_connected”, “$events/client_disconnected”