UNPKG

@windingtree/wt-search-api

Version:

NodeJS app that enables quick search over data from Winding Tree platform

76 lines (70 loc) 2.64 kB
const request = require('request-promise-native'); const Subscription = require('../db/permanent/models/subscription'); const { baseUrl, logger } = require('../config'); const wtIndexGetter = require('./wt-index-getter'); class RemoteError extends Error {}; /** * Send a subscription request and return the subscription ID. * * @param {String} notificationsUri * @param {String} hotelAddress * @param {Function} requestLib optional * @return {Promise<String>} */ async function _sendSubscriptionRequest (notificationsUri, hotelAddress, token, requestLib) { requestLib = requestLib || request; let response; const wtIndexAddress = await wtIndexGetter.get(requestLib); try { response = await requestLib({ method: 'POST', uri: (new URL('/subscriptions', notificationsUri)).toString(), body: { wtIndex: wtIndexAddress, resourceType: 'hotel', resourceAddress: hotelAddress, url: (new URL(`/notifications/${token}`, baseUrl)).toString(), }, json: true, resolveWithFullResponse: true, }); } catch (err) { throw new RemoteError(`Could not subscribe: ${err.message}`); } const subscriptionId = response.body && response.body.subscriptionId; if (response.statusCode > 299 || !subscriptionId) { throw new RemoteError(`Invalid response: ${response.statusCode} with ${subscriptionId}`); } return subscriptionId; } /** * Create a subscription for the given hotel address, if not yet * present. * * @param {String} notificationsUri * @param {String} hotelAddress * @param {Function} requestLib optional * @return {Promise} */ async function subscribeIfNeeded (notificationsUri, hotelAddress, requestLib) { requestLib = requestLib || request; const subscription = await Subscription.get(hotelAddress); if (subscription && subscription.notificationsUri === notificationsUri) { return; // Nothing to do. } const token = await Subscription.generateToken(), remoteId = await _sendSubscriptionRequest(notificationsUri, hotelAddress, token, requestLib); logger.debug(`Subscribing for update notifications for ${hotelAddress} at ${notificationsUri}`); if (subscription) { // Notifications URI has changed. We don't need to // unsubscribe from the previous notificationsUri because, // presumably, updates for the given hotel will not be // broadcast through it anyway. return Subscription.update(hotelAddress, { notificationsUri, remoteId, token }); } return Subscription.create({ hotelAddress, remoteId, notificationsUri, token }); } module.exports = { subscribeIfNeeded, RemoteError, };