UNPKG

opentok

Version:
254 lines (228 loc) 6.68 kB
/* eslint-env es2018 */ const errors = require('./errors'); const request = require('request'); const { version } = require('../package.json'); const _ = require('lodash'); const generateJwt = require('./generateJwt.js'); /** * An object representing an Experience Composer renderer. * * @property {String} id * The ID of the render instance * * @property {String} projectId * The ID of the project for the render. * * @property {String} sessionId * The ID of the session being rendered into. * * @property {Number} createdAt * The time at which the render was created, in milliseconds since the UNIX epoch. * * @property {Number} updatedAt ** * @property {Number} upddatedAt * The time at which the render was created, in milliseconds since the UNIX epoch. * * @property {String} url * A publically reachable URL controlled by the customer and capable of generating * the content to be rendered without user intervention. * * @proerpty {String} status * Current status of for the render. Will be one of `starting`, `started`, `stopped` * or `failed` * * @property {String} reason * Gives a short textual reason for why the Render failed or stopped. * * @property {String} callbackUrl * URL of the customer service where the callbacks will be received. * * @property {String} event * Last sent event of for the render * * @property {String} resoultion * Resolution of the display area for the composition. * * @see {@link OpenTok#getRender OpenTok.getRender()} * @see {@link OpenTok#startRender OpenTok.startRender()} * @see {@link OpenTok#stopRender OpenTok.stopRender()} * @see {@link OpenTok#listRenders OpenTok.listRenders()} * * @class Render */ const generateHeaders = (config, additionalHeaders = {}) => ({ 'User-Agent': 'OpenTok-Node-SDK/' + version, 'X-OPENTOK-AUTH': generateJwt(config), Accept: 'application/json', ...additionalHeaders }); const api = ( { method = 'GET', config, path, params = {}, body = null, headers = {} }, callback ) => { const rurl = new URL(config.apiEndpoint); rurl.pathname = Array.isArray(path) ? _.compact(path).join('/') : path; rurl.searchParams = params; // Increase the likely hood of cache hits rurl.searchParams.sort(); request.defaults(_.pick(config, 'proxy', 'timeout'))( { url: rurl.href, method: method, headers: generateHeaders(config, headers), json: body }, callback ); }; const guardParams = (method, options, callback) => { const cb = typeof options === 'function' ? options : callback; const opts = typeof options !== 'function' ? options : { count: 50 }; if (typeof cb !== 'function') { throw new errors.ArgumentError('No callback given to ' + method); } return [cb, opts]; }; const handleResponse = (callback, err, response) => { if (err) { callback(err); return; } try { const { statusCode } = response; // TODO use the http-errors package switch (statusCode) { case 200: callback(null, JSON.parse(response.body), response); break; case 202: callback(null, response.body, response); break; case 401: case 403: callback(new errors.AuthError(), null, response); break; case 404: callback(new errors.NotFoundError(), null, response); break; case 500: callback(new errors.RequestError(), null, response); break; default: callback( new errors.RequestError('Unexpected response code: ' + statusCode), null, response ); } } catch (exception) { // Most Likely from JSON.parse if (exception instanceof SyntaxError) { callback(new errors.RequestError('Cannot decode JSON response')); return; } callback(new Error('Uknown Error')); } }; /** * Return a list of {@link Render} objects, representing Experience composer in any status * * @param {Object} config - API configuration settings {@see OpenTok.listRenders} * @param {Object} options - Optional parameters for the API call {@see OpenTok.listRenders} * @param {Function} callback - Call back function */ exports.listRenders = (config, options, callback) => { const [cb, opts] = guardParams('listRenders', options, callback); const { offset, count } = opts; if (count > 1000 || count < 1) { throw new errors.ArgumentError('Count is out of range'); } const params = new URLSearchParams(); if (offset) { params.append('offset', offset); } if (count) { params.append('count', count); } api( { path: 'v2/project/' + config.apiKey + '/render', config: config, params: params }, _.partial(handleResponse, cb) ); }; /** * Gets an {@link Render} object for the given render ID. * * @param {Object} config - API config {@see OpenTok} * @param {String} renderId - The Render ID to fetch * @param {Function} callback - Call back function */ exports.getRender = (config, renderId, callback) => { const [cb] = guardParams('getRender', {}, callback); api( { path: 'v2/project/' + config.apiKey + '/render/' + renderId, config: config }, _.partial(handleResponse, cb) ); }; /** * Starts an Experience composer for an OpenTok session. * * * @param {Object} config - API configuration settings {@see OpenTok.startRender} * @param {Object} options - Optional parameters for the API call {@see OpenTok.startRender} * @param {Function} callback - Call back function */ exports.startRender = (config, options, callback) => { const [cb, opts] = guardParams('startRender', options, callback); api( { method: 'POST', path: 'v2/project/' + config.apiKey + '/render', config: config, body: { sessionId: _.get(opts, 'sessionId'), token: _.get(opts, 'token'), url: _.get(opts, 'url'), maxDuration: _.get(opts, 'maxDuration', 1800), resolution: _.get(opts, 'resolution', '1280x720'), statusCallbackUrl: _.get(opts, 'statusCallbackUrl') } }, _.partial(handleResponse, cb) ); }; /** * Stops an OpenTok render that is being rendered. * * @param {Object} config - API configuration settings {@see OpenTok.stopRender} * @param {String} renderId - The Render ID to fetch * @param {Function} callback - Call back function */ exports.stopRender = (config, renderId, callback) => { const [cb] = guardParams('getRender', {}, callback); api( { method: 'DELETE', path: 'v2/project/' + config.apiKey + '/render/' + renderId, config: config }, _.partial(handleResponse, cb) ); };