// venue.js // Copyright (C) 2022 Digital Telepresence, LLC // License: Apache-2.0 'use strict'; const https = require('https'); const fetch = require('node-fetch'); // jshint ignore:line const CACHE_DURATION = 60 * 5; const { SiteService, SiteError } = require('../../lib/site-lib'); class VenueService extends SiteService { constructor (dtp) { super(dtp, module.exports); this.soapboxDomain = process.env.DTP_SOAPBOX_HOST || 'shing.tv'; } async start ( ) { process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; this.httpsAgent = new https.Agent({ rejectUnauthorized: false, }); } channelMiddleware ( ) { return async (req, res, next) => { try { if (!res.locals.site || !res.locals.site.shingChannelSlug) { return next(); } res.locals.shingChannelFeed = await this.getChannelFeed(res.locals.site.shingChannelSlug, { allowCache: false }); res.locals.shingChannelStatus = await this.getChannelStatus(res.locals.site.shingChannelSlug, { allowCache: false }); this.log.debug('channel status', { status: res.locals.shingChannelStatus }); return next(); } catch (error) { this.log.error('failed to populate Soapbox channel feed', { error }); return next(); } }; } async getChannelFeed (channelSlug, options) { const { cache: cacheService } = this.dtp.services; const cacheKey = `venue:ch:${channelSlug}`; options = Object.assign({ allowCache: true }, options); let json; if (options.allowCache) { json = await cacheService.getObject(cacheKey); if (json) { return json; } } const requestUrl = `https://${this.soapboxDomain}/channel/${channelSlug}/feed/json`; this.log.info('fetching Shing channel feed', { channelSlug, requestUrl }); const response = await fetch(requestUrl, { agent: this.httpsAgent, }); if (!response.ok) { throw new SiteError(500, 'Failed to fetch Shing channel feed'); } json = await response.json(); await cacheService.setObjectEx(cacheKey, CACHE_DURATION, json); return json; } async getChannelStatus (channelSlug, options) { const { cache: cacheService } = this.dtp.services; const cacheKey = `venue:ch:${channelSlug}:status`; options = Object.assign({ allowCache: true }, options); let json; if (options.allowCache) { json = await cacheService.getObject(cacheKey); if (json) { return json; } } const requestUrl = `https://${this.soapboxDomain}/channel/${channelSlug}/status`; this.log.info('fetching Shing channel status', { channelSlug, requestUrl }); const response = await fetch(requestUrl, { agent: this.httpsAgent, }); if (!response.ok) { throw new SiteError(500, 'Failed to fetch Shing channel status'); } json = await response.json(); const { channel } = json; await cacheService.setObjectEx(cacheKey, 10, channel); return channel; } } module.exports = { slug: 'venue', name: 'venue', create: (dtp) => { return new VenueService(dtp); }, };