UNPKG

@mediarithmics/plugins-nodejs-sdk

Version:

This is the mediarithmics nodejs to help plugin developers bootstrapping their plugin without having to deal with most of the plugin boilerplate

162 lines (137 loc) 5.94 kB
import express from 'express'; import _ from 'lodash'; import { PluginProperty, PluginPropertyResponse } from '../../api/core/plugin/PluginPropertyInterface'; import { CheckEmailsRequest, EmailRoutingRequest, } from '../../api/plugin/emailtemplaterouter/EmailRouterRequestInterface'; import { BasePlugin, PropertiesWrapper } from '../common/BasePlugin'; export interface EmailRouterBaseInstanceContext { properties: PropertiesWrapper; } export interface EmailRoutingPluginResponse { result: boolean; } export interface CheckEmailsPluginResponse { result: boolean; } export abstract class EmailRouterPlugin extends BasePlugin<EmailRouterBaseInstanceContext> { instanceContext: Promise<EmailRouterBaseInstanceContext>; constructor(enableThrottling = false) { super(enableThrottling); // We init the specific route to listen for activity analysis requests this.initEmailRouting(); this.initEmailCheck(); this.setErrorHandler(); } // Method to build an instance context // To be overriden to get a cutom behavior async fetchEmailRouterProperties(id: string): Promise<PluginProperty[]> { const response = await super.requestGatewayHelper<PluginPropertyResponse>( 'GET', `${this.outboundPlatformUrl}/v1/email_routers/${id}/properties`, ); this.logger.debug(`Fetched Email Router Properties: ${id} - ${JSON.stringify(response.data)}`); return response.data; } // This is a default provided implementation protected async instanceContextBuilder(routerId: string): Promise<EmailRouterBaseInstanceContext> { const emailRouterProps = await this.fetchEmailRouterProperties(routerId); const context: EmailRouterBaseInstanceContext = { properties: new PropertiesWrapper(emailRouterProps), }; return context; } // To be overriden by the Plugin to get a custom behavior protected abstract onEmailRouting( request: EmailRoutingRequest, instanceContext: EmailRouterBaseInstanceContext, ): Promise<EmailRoutingPluginResponse>; protected async getInstanceContext(emailRouterId: string): Promise<EmailRouterBaseInstanceContext> { if (!this.pluginCache.get(emailRouterId)) { void this.pluginCache.put( emailRouterId, this.instanceContextBuilder(emailRouterId).catch((err) => { this.logger.error(`Error while caching instance context: ${(err as Error).message}`); this.pluginCache.del(emailRouterId); throw err; }), this.getInstanceContextCacheExpiration(), ); } return this.pluginCache.get(emailRouterId) as Promise<EmailRouterBaseInstanceContext>; } // To be overriden by the Plugin to get a custom behavior protected abstract onEmailCheck( request: CheckEmailsRequest, instanceContext: EmailRouterBaseInstanceContext, ): Promise<CheckEmailsPluginResponse>; private initEmailRouting(): void { this.app.post( '/v1/email_routing', this.asyncMiddleware(async (req: express.Request, res: express.Response) => { if (!this.httpIsReady()) { const msg = { error: 'Plugin not initialized', }; this.logger.error('POST /v1/email_routing : %s', JSON.stringify(msg)); return res.status(500).json(msg); } else if (!req.body || _.isEmpty(req.body)) { const msg = { error: 'Missing request body', }; this.logger.error('POST /v1/email_routing : %s', JSON.stringify(msg)); return res.status(500).json(msg); } else { this.logger.debug(`POST /v1/email_routing ${JSON.stringify(req.body)}`); const emailRoutingRequest = req.body as EmailRoutingRequest; if (!this.onEmailRouting) { const errMsg = 'No Email Routing listener registered!'; this.logger.error(errMsg); return res.status(500).json({ error: errMsg }); } const instanceContext = await this.getInstanceContext(emailRoutingRequest.email_router_id); const pluginResponse = await this.onEmailRouting(emailRoutingRequest, instanceContext); this.logger.debug(`Returning: ${JSON.stringify(pluginResponse)}`); res.status(200).send(JSON.stringify(pluginResponse)); } }), ); } private initEmailCheck(): void { this.app.post('/v1/email_router_check', (req: express.Request, res: express.Response) => { if (!this.httpIsReady()) { const msg = { error: 'Plugin not initialized', }; this.logger.error('POST /v1/email_router_check : %s', JSON.stringify(msg)); return res.status(500).json(msg); } else if (!req.body || _.isEmpty(req.body)) { const msg = { error: 'Missing request body', }; this.logger.error('POST /v1/email_router_check : %s', JSON.stringify(msg)); res.status(500).json(msg); } else { this.logger.debug(`POST /v1/email_router_check ${JSON.stringify(req.body)}`); const emailCheckRequest = req.body as CheckEmailsRequest; if (!this.onEmailRouting) { throw new Error('No Email Check listener registered!'); } this.getInstanceContext(emailCheckRequest.email_router_id) .then((instanceContext: EmailRouterBaseInstanceContext) => { return this.onEmailCheck(emailCheckRequest, instanceContext).then((response) => { this.logger.debug(`Returning: ${JSON.stringify(response)}`); res.status(200).send(JSON.stringify(response)); }); }) .catch((error: Error) => { this.logger.error( `Something bad happened : ${error.message} - ${error.stack ? error.stack : 'stack undefined'}`, ); return res.status(500).send(`${error.message} \n ${error.stack ? error.stack : 'stack undefined'}`); }); } }); } }