UNPKG

@slack/client

Version:

A library for creating a Slack client

176 lines (147 loc) 4.83 kB
/** * */ var EventEmitter = require('eventemitter3'); var Promise = require('bluebird'); var async = require('async'); var bind = require('lodash').bind; var inherits = require('inherits'); var partial = require('lodash').partial; var retry = require('retry'); var SlackAPIError = require('./errors').SlackAPIError; var callTransport = require('./transports/call-transport'); var getLogger = require('../helpers').getLogger; var helpers = require('./helpers'); var requestsTransport = require('./transports/request').requestTransport; var retryPolicies = require('./retry-policies'); /** * Base client for both the RTM and web APIs. * @param {string} token The Slack API token to use with this client. * @param {Object} opts * @param {String} opts.slackAPIUrl The Slack API URL. * @param {String} opts.userAgent The user-agent to use, defaults to node-slack. * @param {Function} opts.transport Function to call to make an HTTP call to the Slack API. * @param {string=} opts.logLevel The log level for the logger. * @param {Function=} opts.logger Function to use for log calls, takes (logLevel, logString) params. * @param {Number} opts.maxRequestConcurrency The max # of concurrent requests to make to Slack's * API's, defaults to 3. * @param {Object} opts.retryConfig The configuration to use for the retry operation, * {@see https://github.com/SEAPUNK/node-retry} * @constructor */ function BaseAPIClient(token, opts) { var clientOpts = opts || {}; EventEmitter.call(this); /** * @type {string} * @private */ this._token = token; /** @type {string} */ this.slackAPIUrl = clientOpts.slackAPIUrl || 'https://slack.com/api/'; /** @type {Function} */ this.transport = clientOpts.transport || requestsTransport; /** @type {string} */ this.userAgent = clientOpts.userAgent || 'node-slack'; /** * Default to attempting 5 retries within 5 minutes, with exponential backoff. */ this.retryConfig = clientOpts.retryConfig || retryPolicies.FIVE_RETRIES_IN_FIVE_MINUTES; /** * * @type {Object} * @private */ this.requestQueue = async.priorityQueue( bind(this._callTransport, this), clientOpts.maxRequestConcurrency || 3 ); /** * The logger function attached to this client. * @type {Function} */ this.logger = clientOpts.logger || getLogger(clientOpts.logLevel); this._createFacets(); } inherits(BaseAPIClient, EventEmitter); BaseAPIClient.prototype.emit = function emit() { BaseAPIClient.super_.prototype.emit.apply(this, arguments); this.logger('debug', arguments); }; /** * Initializes each of the API facets. * @protected */ BaseAPIClient.prototype._createFacets = function _createFacets() { }; /** * Attaches a data-store to the client instance. * @param {SlackDataStore} dataStore */ BaseAPIClient.prototype.registerDataStore = function registerDataStore(dataStore) { this.dataStore = dataStore; }; /** * Calls the supplied transport function and processes the results. * * This will also manage 429 responses and retry failed operations. * * @param {object} task The arguments to pass to the transport. * @param {function} queueCb Callback to signal to the request queue that the request has completed. * @protected */ BaseAPIClient.prototype._callTransport = function _callTransport(task, queueCb) { var _this = this; var retryOp = retry.operation(_this.retryConfig); var retryArgs = { client: _this, task: task, queueCb: queueCb, retryOp: retryOp }; retryOp.attempt(function attemptTransportCall() { _this.transport(task.args, partial(callTransport.handleTransportResponse, retryArgs)); }); }; /** * Makes a call to the Slack API. * * @param {String} endpoint The API endpoint to send to. * @param {Object=} apiArgs * @param {Object=} apiOptArgs * @param {function=} optCb The callback to run on completion. * @private */ BaseAPIClient.prototype._makeAPICall = function _makeAPICall(endpoint, apiArgs, apiOptArgs, optCb) { var apiCallArgs = helpers.getAPICallArgs( this._token, this.userAgent, this.slackAPIUrl, endpoint, apiArgs, apiOptArgs, optCb); var cb = apiCallArgs.cb; var args = apiCallArgs.args; var promise; var _this = this; if (!cb) { promise = new Promise(function makeAPICallPromiseResolver(resolve, reject) { _this.requestQueue.push({ args: args, cb: function makeAPICallPromiseResolverInner(err, res) { if (err) { reject(err); } else { if (!res.ok) { reject(new SlackAPIError(res.error)); } else { resolve(res); } } } }); }); } else { this.requestQueue.push({ args: args, cb: cb }); } return promise; }; module.exports = BaseAPIClient;