UNPKG

jsforce2

Version:

Salesforce API Library for JavaScript

137 lines (125 loc) 3.88 kB
/** * Faye Client extensions: https://faye.jcoglan.com/browser/extensions.html * * For use with Streaming.prototype.createClient() **/ var StreamingExtension = {}; /** * Constructor for an auth failure detector extension * * Based on new feature released with Salesforce Spring '18: * https://releasenotes.docs.salesforce.com/en-us/spring18/release-notes/rn_messaging_cometd_auth_validation.htm?edition=&impact= * * Example triggering error message: * * ``` * { * "ext":{ * "sfdc":{"failureReason":"401::Authentication invalid"}, * "replay":true}, * "advice":{"reconnect":"none"}, * "channel":"/meta/handshake", * "error":"403::Handshake denied", * "successful":false * } * ``` * * Example usage: * * ```javascript * const conn = new jsforce.Connection({ … }); * * const channel = "/event/My_Event__e"; * * // Exit the Node process when auth fails * const exitCallback = () => process.exit(1); * const authFailureExt = new jsforce.StreamingExtension.AuthFailure(exitCallback); * * const fayeClient = conn.streaming.createClient([ authFailureExt ]); * * const subscription = fayeClient.subscribe(channel, data => { * console.log('topic received data', data); * }); * * subscription.cancel(); * ``` * * @param {Function} failureCallback - Invoked when authentication becomes invalid */ StreamingExtension.AuthFailure = function(failureCallback) { this.incoming = function(message, callback) { if ( (message.channel === '/meta/connect' || message.channel === '/meta/handshake') && message.advice && message.advice.reconnect == 'none' ) { failureCallback(message); } else { callback(message); } } }; /** * Constructor for a durable streaming replay extension * * Modified from original Salesforce demo source code: * https://github.com/developerforce/SalesforceDurableStreamingDemo/blob/3d4a56eac956f744ad6c22e6a8141b6feb57abb9/staticresources/cometdReplayExtension.resource * * Example usage: * * ```javascript * const conn = new jsforce.Connection({ … }); * * const channel = "/event/My_Event__e"; * const replayId = -2; // -2 is all retained events * * const replayExt = new jsforce.StreamingExtension.Replay(channel, replayId); * * const fayeClient = conn.streaming.createClient([ replayExt ]); * * const subscription = fayeClient.subscribe(channel, data => { * console.log('topic received data', data); * }); * * subscription.cancel(); * ``` */ StreamingExtension.Replay = function(channel, replayId) { var REPLAY_FROM_KEY = "replay"; var _extensionEnabled = replayId != null ? true : false; var _replay = replayId; var _channel = channel; this.setExtensionEnabled = function(extensionEnabled) { _extensionEnabled = extensionEnabled; } this.setReplay = function (replay) { _replay = parseInt(replay, 10); } this.setChannel = function(channel) { _channel = channel; } this.incoming = function(message, callback) { if (message.channel === '/meta/handshake') { if (message.ext && message.ext[REPLAY_FROM_KEY] == true) { _extensionEnabled = true; } } else if (message.channel === _channel && message.data && message.data.event && message.data.event.replayId) { _replay = message.data.event.replayId; } callback(message); } this.outgoing = function(message, callback) { if (message.channel === '/meta/subscribe' && message.subscription === _channel) { if (_extensionEnabled) { if (!message.ext) { message.ext = {}; } var replayFromMap = {}; replayFromMap[_channel] = _replay; // add "ext : { "replay" : { CHANNEL : REPLAY_VALUE }}" to subscribe message message.ext[REPLAY_FROM_KEY] = replayFromMap; } } callback(message); }; }; module.exports = StreamingExtension;