# WebHook

WebHook is a plugin provided by the emqx_web_hook (opens new window) plugin with the function of notifying a web service of hook events in EMQ X Broker.

The internal implementation of WebHook is based on hooks, but it is closer to the top level. It obtains various events in EMQ X Broker through the callback function mounted on the hook, and forwards them to the web server configured in emqx_web_hook.

Taking the client.connected event as an example, the event delivery process is as follows:

    Client      |    EMQ X     |  emqx_web_hook |   HTTP       +------------+
  =============>| - - - - - - -> - - - - - - - ->===========>  | Web Server |
                |    Broker    |                |  Request     +------------+

TIP

WebHook processes events in one-way pattern. It only supports pushing events in EMQ X Broker to Web services, and does not care about the return of Web services. With the help of Webhooks, many services such as device going online, online and offline recording, subscription and message storage, and message delivery confirmation can be completed.

# Configuration item

The webhook configuration file is located in: etc/plugins/emqx_web_hook.conf

Configuration itemTypeOptional valueDefault valueDescription
api.urlstring-http://127.0.0.1:8080Address of the destination server to which the event needs to be forwarded
encode_payloadenumbase64, base62undefinedEncode the Payload field in the message event

TIP

When the message content is invisible characters (such as binary data), encode_payload is very useful for transmission in the HTTP protocol.

# Trigger rule

Trigger rules can be configured in etc/plugins/emqx_web_hooks.conf. The configuration format is as follows:

## Format example
web.hook.rule.<Event>.<Number> = <Rule>

## Example
web.hook.rule.message.publish.1 = {"action": "on_message_publish", "topic": "a/b/c"}
web.hook.rule.message.publish.2 = {"action": "on_message_publish", "topic": "foo/#"}

# Trigger event

The following events are currently supported:

NameDescriptionExecution timing
client.connectProcessing connection packetsWhen the server receives the client's connection packet
client.connackIssue connection acknowledgeWhen the server is ready to send connack packet
client.connectedconnectedAfter the client authentication is completed and successfully connected to the system
client.disconnecteddisconnectedWhen the client connection layer is about to close
client.subscribesubscribeAfter receiving the subscription message,and before executing client.check_acl authentication
client.unsubscribeunsubscribeAfter receiving the unsubscription message
session.subscribedSession subscribedAfter completing the subscription operation
session.unsubscribedsession unsubscribedAfter completing the unsubscription operation
message.publishmessage publishedBefore the server rpublishes (routes) the message
message.deliveredmessage deliveriedBefore the message is ready to be delivered to the client
message.ackedmessage acknowledgedAfter the server received the message ACK from the client
message.droppedmessage droppedAfter the published message is dropped

# Number

Multiple trigger rules can be configured for the same event, and events with the same configuration should be incremented in sequence.

# Rule

The trigger rule's 'value is a JSON string, and the available Keys are:

  • action: string, taking a fixed value
  • topic: a string, indicating a topic filter, the operation topic can only trigger the forwarding of the event if it matches the topic

For example, we only forward messages matching the topics of a/b/c and foo/# to the web server, and the configuration should be:

web.hook.rule.message.publish.1 = {"action": "on_message_publish", "topic": "a/b/c"}
web.hook.rule.message.publish.2 = {"action": "on_message_publish", "topic": "foo/#"}

In this way, Webhook will only forward messages matching the topics of a/b/c and foo/#, such as foo/bar, etc., instead of forwarding a/b/d or fo/bar.

# Webhook event parameters

When the event is triggered, Webhook will group each event into an HTTP request and sent it to the web server configured by api.url according to the configuration. The request format is:

URL: <api.url>      # From the api.url field in the configuration
Method: POST        # Fixed as POST method

Body: <JSON>        # Body is a JSON format string

For different events, the content of the request body is different. The following table lists the parameters of the body in each event:

client.connect

KeyTypeDescription
actionstringevent name
fixed at:"client_connect"
clientidstringclient ClientId
usernamestringclient Username, When not existed, the value is "undefined"
ipaddressstringclient source IP address
keepaliveintegerHeartbeat keepalive time applied by client
proto_verintegerProtocol version number

client.connack

KeyTypeDescription
actionstringevent name
fixed at: "client_connack"
clientidstringclient ClientId
usernamestringclient Username, When not existed, the value is "undefined"
ipaddressstringclient source IP address
keepaliveintegerHeartbeat keepalive time applied by client
proto_verintegerProtocol version number
conn_ackstring"success" means success, other means failure

client.connected

KeyTypeDescription
actionstringevent name
fixed at:"client_connected"
clientidstringclient ClientId
usernamestringclient Username, When not existed, the value is "undefined"
ipaddressstringclient source IP address
keepaliveintegerHeartbeat keepalive time applied by client
proto_verintegerProtocol version number
connected_atintegerTimestamp (second)

client.disconnected

KeyTypeDescription
actionstringevent name
fixed at: "client_disconnected"
clientidstringclient ClientId
usernamestringclient Username, When not existed, the value is "undefined"
reasonstringerror reason

client.subscribe

KeyTypeDescription
actionstringevent name
fixed at: "client_subscribe"
clientidstringClient ClientId
usernamestringClient Username, When not existed, the value is "undefined"
topicstringTopics to be subscribed
optsjsonSubscription parameters

opts includes

KeyTypeDescription
qosenumQoS level, and the optional value is 0 1 2

client.unsubscribe

KeyTypeDescription
actionstringevent name
fixed at:"client_unsubscribe"
clientidstringclient ClientId
usernamestringclient Username, When not existed, the value is "undefined"
topicstringunsubscribed topic

session.subscribed: same as client.subscribe,action is session_subscribed

session.unsubscribed: same as client.unsubscribe,action is session_unsubscribe

session.terminated: same as client.disconnected,action is session_terminated

message.publish

KeyTypeDescription
actionstringevent name
fixed at: "message_publish"
from_client_idstringPublisher's ClientId
from_usernamestringPublisher's Username, When not existed, the value is "undefined"
topicstringUnsubscribed topic
qosenumQoS level, and the optional value is 0 1 2
retainboolWhether it is a Retain message
payloadstringMessage Payload
tsintegerTimestamp (second)

message.delivered

KeyTypeDescription
actionstringevent name
fixed at: "message_delivered"
clientidstringReceiver's ClientId
usernamestringReceiver's Username, When not existed, the value is "undefined"
from_client_idstringPublisher's ClientId
from_usernamestringPublisher's Username, When not existed, the value is "undefined"
topicstringUnsubscribed topic
qosenumQoS level, and the optional value is 0 1 2
retainboolWhether it is a Retain message
payloadstringMessage Payload
tsintegerTimestamp (second)

message.acked

KeyTypeDescription
actionstringevent name
fixed at: "message_acked"
clientidstringReceiver's ClientId
from_client_idstringPublisher's ClientId
from_usernamestringPublisher's Username, When not existed, the value is "undefined"
topicstringUnsubscribed topic
qosenumQoS level, and the optional value is 0 1 2
retainboolWhether it is a Retain message
payloadstringMessage Payload
tsintegerTimestamp (second)