Handling events
The EventHub
is a class that provides functionality to interact with an ftrack event server. It allows you to connect to the event server, subscribe to specific events, publish events, and handle event responses.
Events are generated in ftrack when things happen such as a task being updated or a new version being published. Each Session can optionally connect to the event server and can be used to subscribe to specific events and perform an action as a result. That action could be updating another related entity based on a status change or generating folders when a new shot is created for example.
The EventHub
for each Session is accessible via session.eventHub
.
Connecting to event hub
To connect to the event hub, run session.eventHub.connect()
. You can also automatically connect the event hub when it is instantiated by providing the option autoConnectEventHub
when constructing the Session instance:
session = new ftrack.Session(..., { autoConnectEventHub: true });
session.eventHub.isConnected();
Subscribing to events
To listen to events, you register a function against a subscription using ’Session.eventHub.subscribe()’. The subscription uses the expression syntax and will filter against each Event instance to determine if the registered function should receive that event. If the subscription matches, the registered function will be called with the Event instance as its sole argument. The Event instance is a mapping like structure and can be used like a normal object.
The following example subscribes a function to receive all ‘ftrack.update’ events and then print out the entities that were updated:
import { Session } from "@ftrack/api";
// Define a function to handle the received event
function myCallback(event) {
// Iterate through the updated entities and print their data
event.data.entities.forEach((entity) => {
// Print data for the entity
console.log(entity);
});
}
// Create a session and automatically connect to the event hub
const session = new Session({ autoConnectEventHub: true });
// Subscribe to events with the 'ftrack.update' topic
session.eventHub.subscribe("topic=ftrack.update", myCallback);
Subscriber information
When subscribing, you can also specify additional information about your subscriber. This contextual information can be useful when routing events, particularly when targeting events. By default, the event hub will set some default information, but it can be useful to enhance this. To do so, simply pass in subscriber as a object of data to the
subscribe()
method:
session.eventHub.subscribe("topic=ftrack.update", myCallback, {
id: "my-unique-subscriber-id",
applicationId: "maya",
});
Sending replies
When handling an event it is sometimes useful to be able to send information back to the source of the event. For example, ftrack.location.request-resolve
would expect a resolved path to be sent back.
You can publish a custom reply event using publishReply()
, but an easier way is to return the appropriate data from your handler. Any returned value except null or undefined will be automatically sent as a reply:
function onEvent(event) {
// Send following data in automatic reply
return { success: true, message: "Cool!" };
}
session.eventHub.subscribe("topic=test-reply", onEvent);
Publishing events
So far we have looked at listening to events coming from ftrack. However, you are also free to publish your own events (or even publish relevant ftrack events).
To do this, simply construct an instance of Event
and pass it to EventHub.publish()
via the session:
import { Event } from "@ftrack/api";
event = new Event((topic = "my-company.some-topic"), (data = { key: "value" }));
session.eventHub.publish(event);
The event hub will automatically add some information to your event before it gets published, including the source of the event. By default the event source is just the event hub, but you can customise this to provide more relevant information if you want.
Handling replies
When publishing an event, you can specify onReply
as a function which will be invoked whenever a reply event is received:
function onReply(event) {
console.info("Reply received", event.data);
}
session.eventHub.publish(event, { onReply: onReply });
It is often the case that you want to wait for a single reply. In this case, you can use the convenience method publishAndWaitForReply()
. It will return a promise which will be resolved with the response. You can test this using two browser tabs. In the first, run the following to listen for event and reply:
// Listen for events and reply
function onEvent(event) {
console.info("Event received", event.data);
return { message: "Event acknowledged" };
}
session.eventHub.subscribe("topic=my-company.some-topic", onEvent);
In the second environment we will publish an event, wait for and log the response:
// Publish event and wait for reply
function onReply(event) {
console.info("Promise resolved with reply", event.data);
}
function onError(error) {
console.error("Reply not received", error);
}
var event = new ftrack.Event("my-company.some-topic", {
message: "Hello world!",
});
session.eventHub
.publishAndWaitForReply(event, { timeout: 5 })
.then(onReply, onError);
Limitations
The event hub in the JavaScript API has some minor differences and lacks some of the features available in the python counterpart.
Subscription expressions
The JavaScript API currently only support expressions on the format topic=value
including wildcard support topic=ftrack.*
, and more complex expressions such as filtering based on event source or data are not supported.
Target expression
Targeted events will invoke all subscribers of the topic, not just those matching the target expression.
Stopping events
Subscription callback priorities and the ability to stop events is not supported at this point.