Lua scripts are stored in 'data/scripts' directory, and will be loaded automatically. If a script is changed during runtime, it should be reloaded to take effect.
Each lua script could export several functions binding with emqx hooks, triggered by message publish, topic subscribe, client connect, etc. Different lua scripts may export same type function, binding with a same event. But their order being triggered is not guaranteed.
To start this plugin, run following command:
```shell
bin/emqx_ctl plugins load emqx_lua_hook
```
## NOTE
* Since lua VM is run on erlang VM, its performance is poor. Please do NOT write long or complicated lua scripts which may degrade entire system.
* It's hard to debug lua script in emqx environment. Recommended to unit test your lua script in your host first. If everything is OK, deploy it to emqx 'data/scripts' directory.
* Global variable will lost its value for each call. Do NOT use global variable in lua scripts.
# Example
Suppose your emqx is installed in /emqx, and the lua script directory should be /emqx/data/scripts.
Make a new file called "test.lua" and put following code into this file:
```lua
function on_message_publish(clientid, username, topic, payload, qos, retain)
return topic, "hello", qos, retain
end
function register_hook()
return "on_message_publish"
end
```
Execute following command to start emq-lua-hook and load scripts in 'data/scripts' directory.
```
/emqx/bin/emqx_ctl plugins load emqx_lua_hook
```
Now let's take a look at what will happend.
- Start a mqtt client, such as mqtt.fx.
- Subscribe a topic="a/b".
- Send a message, topic="a/b", payload="123"
- Subscriber will get a message with topic="a/b" and payload="hello". test.lua modifies the payload.
If there are "test1.lua", "test2.lua" and "test3.lua" in /emqx/data/scripts, all these files will be loaded once emq-lua-hook get started.
If test2.lua has been changed, restart emq-lua-hook to reload all scripts, or execute following command to reload test2.lua only:
```
/emqx/bin/emqx_ctl luahook reload test2.lua
```
# Hook API
You can find all example codes in the `examples.lua` file.
## on_client_connected
```lua
function on_client_connected(clientId, userName, returncode)
return 0
end
```
This API is called after a mqtt client has establish a connection with broker.
### Input
* clientid : a string, mqtt client id.
* username : a string mqtt username
* returncode : a string, has following values
- success : Connection accepted
- Others is failed reason
### Output
Needless
## on_client_disconnected
```lua
function on_client_disconnected(clientId, username, error)
return
end
```
This API is called after a mqtt client has disconnected.
### Input
* clientId : a string, mqtt client id.
* username : a string mqtt username
* error : a string, denote the disconnection reason.
### Output
Needless
## on_client_subscribe
```lua
function on_client_subscribe(clientId, username, topic)
-- do your job here
if some_condition then
return new_topic
else
return false
end
end
```
This API is called before mqtt engine process client's subscribe command. It is possible to change topic or cancel it.
### Input
* clientid : a string, mqtt client id.
* username : a string mqtt username
* topic : a string, mqtt message's topic
### Output
* new_topic : a string, change mqtt message's topic
* false : cancel subscription
## on_client_unsubscribe
```lua
function on_client_unsubscribe(clientId, username, topic)
-- do your job here
if some_condition then
return new_topic
else
return false
end
end
```
This API is called before mqtt engine process client's unsubscribe command. It is possible to change topic or cancel it.
### Input
* clientid : a string, mqtt client id.
* username : a string mqtt username
* topic : a string, mqtt message's topic
### Output
* new_topic : a string, change mqtt message's topic
* false : cancel unsubscription
## on_session_subscribed
```lua
function on_session_subscribed(ClientId, Username, Topic)
return
end
```
This API is called after a subscription has been done.
### Input
* clientid : a string, mqtt client id.
* username : a string mqtt username
* topic : a string, mqtt's topic filter.
### Output
Needless
## on_session_unsubscribed
```lua
function on_session_unsubscribed(clientid, username, topic)
return
end
```
This API is called after a unsubscription has been done.
### Input
* clientid : a string, mqtt client id.
* username : a string mqtt username
* topic : a string, mqtt's topic filter.
### Output
Needless
## on_message_delivered
```lua
function on_message_delivered(clientid, username, topic, payload, qos, retain)
-- do your job here
return topic, payload, qos, retain
end
```
This API is called after a message has been pushed to mqtt clients.
### Input
* clientId : a string, mqtt client id.
* username : a string mqtt username
* topic : a string, mqtt message's topic
* payload : a string, mqtt message's payload
* qos : a number, mqtt message's QOS (0, 1, 2)
* retain : a boolean, mqtt message's retain flag
### Output
Needless
## on_message_acked
```lua
function on_message_acked(clientId, username, topic, payload, qos, retain)
return
end
```
This API is called after a message has been acknowledged.
### Input
* clientId : a string, mqtt client id.
* username : a string mqtt username
* topic : a string, mqtt message's topic
* payload : a string, mqtt message's payload
* qos : a number, mqtt message's QOS (0, 1, 2)
* retain : a boolean, mqtt message's retain flag
### Output
Needless
## on_message_publish
```lua
function on_message_publish(clientid, username, topic, payload, qos, retain)