The Box API supports two types of event streams -- one for the events specific to a particular user and one for all of the events in an enterprise.
The Box API provides an events endpoint that utilizes long-polling to send
events in real-time. The SDK provides an EventStream
class (which implements
stream.Readable) that automatically
handles long-polling and deduplicating events.
When the EventStream
is started, it will begin long-polling asynchronously.
Events received from the API are then forwarded to any listeners.
client.events.getEventStream(function(err, stream) {
if (err) {
// handle error
}
stream.on('data', function(event) {
// handle the event
});
});
By default, the stream will start at the current time. You can start the stream at a past stream position by passing a position marker:
client.events.getEventStream('1408838928446360', function(err, stream) { /* ... */ });
When you're done listening for events, call stream.pause()
to stop long-polling.
Since the Box API may send duplicate events, the EventStream
will remember the last 5000 received events and automatically ignore them.
It is possible to get the current stream position, which can later be used to fetch events from that point in time forward.
client.events.getCurrentStreamPosition(callback);
To get the latest chunk of events, you can call
events.get(options, callback)
.
client.events.get(null, callback);
You can also pass in a stream_position
parameter to get events from a specific
point in time:
client.events.get({stream_position: '1408838928446360'}, callback);
If you ever need to stop long-polling, use:
client.events.destroy();
This will not cancel in-process network requests. It will ensure no further long-polling nor event fetching takes place.
The Box API has an enterprise events endpoint that is available to admin users and service accounts.
The SDK includes an EnterpriseEventStream
class (which implements
stream.Readable) that automatically
handles polling for events and delivering them to the application.
When you attach a 'data'
event listener to an EnterpriseEventStream
, it will begin fetching events from Box.
Events received from the API are then forwarded to the listener.
client.events.getEnterpriseEventStream(function(err, stream) {
if (err) {
// Handle error
}
stream.on('data', function(event) {
// Handle the event
});
});
To get events from admin events stream you have to pick stream_type from admin_logs
or admin_logs_streaming
.
By default, the admin_logs
stream is selected. Emphasis of this stream is on completeness over latency,
which means that Box will deliver admin events in chronological order and without duplicates,
but with higher latency. You can specify start and end time/dates.
To monitor recent events that have been generated within Box across the enterprise use
admin_logs_streaming
as stream type. The emphasis for this feed is on low latency rather than chronological
accuracy, which means that Box may return events more than once and out of chronological order.
Events are returned via the API around 12 seconds after they are processed by Box
(the 12 seconds buffer ensures that new events are not written after your cursor position).
Only two weeks of events are available via this feed, and you cannot set start and end time/dates.
Use streamType
option to select stream type:
client.events.getEnterpriseEventStream({
streamType: 'admin_logs_streaming'
}, callback);
By default, the stream will start at the current time. You can also start the stream
from a specific date or from a previous stream position. To start from the earliest available events (~1 year),
pass streamPosition = '0'
. The stream will fetch all past events as quickly as your listener consumes them.
Once the stream catches up to the current time, it will begin polling for new events every pollingInterval
seconds
(default = 60).
client.events.getEnterpriseEventStream({
startDate: '2016-01-01T00:00:00-08:00',
pollingInterval: 60
}, callback);
Note that Box buffers enterprise events for ~60 seconds when using admin_logs
stream type, before making them available
to the /events
API (to ensure that events are delivered in-order and without duplicates), so polling with an interval
of less than 60 seconds is not normally needed with this event type. When using admin_logs_streaming
you can set pooling
interval to 12 seconds.
If you pass pollingInterval = 0
, then the stream will not use polling, but will end when all the currently
available events have been delivered.
client.events.getEnterpriseEventStream({
startDate: '2016-01-01T00:00:00-08:00',
endDate: '2017-01-01T00:00:00-08:00',
pollingInterval: 0
}, callback);
You can also filter the event stream to only receive specific event types. The set of enterprise event types
is available in client.events.enterpriseEventTypes
.
client.events.getEnterpriseEventStream({
eventTypeFilter: [client.events.enterpriseEventTypes.UPLOAD, client.events.enterpriseEventTypes.DOWNLOAD]
}, callback);
Since EnterpriseEventStream
implements stream.Readable,
you can use the usual flow-control mechanisms on the stream:
stream.pause();
stream.resume();
stream.isPaused();
You can also pipe the output to a stream.Writable stream (it must be an "object mode" stream):
stream.pipe(writableObjectModeStream);
If an API or network error occurs, the stream will ignore the error and continue polling at the usual rate until
the connection can be re-established. You can respond to errors with an 'error'
event listener:
stream.on('error', function(err) {
// Handle the error.
});
In many applications, you may need to persist the stream state so that you can resume processing events from the
same point if your application is interrupted and restarted. You can attach a newStreamState
event listener
to be notified each time the stream position changes.
client.events.getEnterpriseEventStream(function(err, stream) {
if (err) { // Handle error }
// Restore the stream state from the previous run.
stream.setStreamState(readState());
stream.on('newStreamState', function(streamState) {
// Persist the stream state each time the stream position changes.
writeState(streamState);
});
stream.on('data', function(event) {
// Handle the event.
});
});