pub
Pushes a message to a channel subscribed by a running robot, so that systems outside the platform (TradingView webhook alerts, your own trading system, monitoring scripts and so on) can send data to the robot. The robot reads it with GetChannelData; for how channels work see Communication Between Live Trading Strategies.
Unlike the other methods, pub needs no API key and no signature: the request URL is https://www.fmz.com/api/v1?method=pub&robot={robotId}&channel={channel} and the message goes in the request body (POST). Anyone who knows the robot ID and the channel name can push, so use a hard-to-guess random string as the channel name, and have the strategy validate what it receives as untrusted input.
Examples
Receiving strategy: subscribe to the channel, parse the JSON messages it receives, and use id to tell new messages from old ones.
javascript
// receiving robot (assume its ID is 123456)
var CHANNEL = "6BC42A119B5DBFA2188A8279DA3B5C30"
function main() {
var lastId = null
while (true) {
var msg = GetChannelData(CHANNEL) // the first call subscribes and returns null
if (typeof msg == "string") {
var obj = null
try {
obj = JSON.parse(msg) // parse again when the body is JSON text
} catch (e) {
Log("non-JSON message:", msg)
}
// the channel keeps only the latest message; use id to spot new ones
if (obj && obj.id != lastId) {
lastId = obj.id
Log("external message received:", obj)
}
}
Sleep(1000)
}
}
python
import json
CHANNEL = "6BC42A119B5DBFA2188A8279DA3B5C30"
def main():
lastId = None
while True:
msg = GetChannelData(CHANNEL) # the first call subscribes and returns None
if isinstance(msg, str):
try:
obj = json.loads(msg) # parse again when the body is JSON text
except ValueError:
obj = None
Log("non-JSON message:", msg)
if isinstance(obj, dict) and obj.get("id") != lastId:
lastId = obj.get("id")
Log("external message received:", obj)
Sleep(1000)Returns
| Type | Description |
object | On success |
Arguments
| Name | Type | Required | Description |
robot | number | Yes | ID of the robot that receives the message (URL parameter). The robot must be running and already subscribed to |
channel | string | Yes | Channel name (URL parameter); a 32-character random string (a UUID without hyphens) is recommended. It must not be all digits (that is taken as a robot ID, i.e. the robot's own channel); names shorter than 10 characters are not delivered. |
message | string | No | Message content. For |
Attributes
| Name | Type | Description |
data.status | string |
|
data.robot | number | Echo of the request's |
data.channel | string | Echo of the request's |
data.message | string | The message pushed. |
data.affected | number | Number of dockers that received the message. |
Remarks
Delivery rules
- Subscribe first, then push: the robot's first
GetChannelData(channel)call subscribes to the channel (and returns a null value); the subscription is reported with the docker's heartbeat, so the external system can push successfully only after a short while. Requests fail while no robot subscribes. - The message is delivered to the docker of the
robotrobot, and every robot on that docker subscribed to the same channel receives it; robots on other dockers do not. - A channel keeps only the latest message, with no queue:
GetChannelData()returns the most recent one each time, and reading does not clear it. To tell new messages from old ones, include an increasing number or a timestamp in the message. - Each robot can subscribe to at most 10 channels (other robots' channels included); beyond that
GetChannelData()returns a null value and logs the errorchannel subscriber exceed limit. - The robot receives a string (the raw request body). When the body is JSON text, the strategy has to parse it again.
Example push request
An external system pushes a message:
bash
curl -X POST \
"https://www.fmz.com/api/v1?method=pub&robot=123456&channel=6BC42A119B5DBFA2188A8279DA3B5C30" \
-d '{"id": 1, "action": "buy", "symbol": "BTC_USDT"}'
In TradingView, put the URL above in the alert's webhook URL; the alert message becomes the request body.
Example response
json
{
"code": 0,
"data": {
"status": "ok",
"robot": 123456,
"channel": "6BC42A119B5DBFA2188A8279DA3B5C30",
"message": "{\"id\": 1, \"action\": \"buy\", \"symbol\": \"BTC_USDT\"}",
"affected": 1
}
}
When no robot subscribes to the channel:
json
{
"code": 5,
"error": "No subscribers for channel: 6BC42A119B5DBFA2188A8279DA3B5C30",
"data": null
}