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

119 lines 5.93 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.BidOptimizerPlugin = void 0; const lodash_1 = __importDefault(require("lodash")); const common_1 = require("../common"); class BidOptimizerPlugin extends common_1.BasePlugin { constructor(enableThrottling = false) { super(enableThrottling); this.initBidDecisions(); this.setErrorHandler(); } /** * * @param bidOptimizerId */ async fetchBidOptimizer(bidOptimizerId) { const bidOptimizerResponse = await super.requestGatewayHelper('GET', `${this.outboundPlatformUrl}/v1/bid_optimizers/${bidOptimizerId}`); this.logger.debug(`Fetched Bid Optimizer: ${bidOptimizerId} - ${JSON.stringify(bidOptimizerResponse.data)}`); return bidOptimizerResponse.data; } /** * * @param bidOptimizerId */ async fetchBidOptimizerProperties(bidOptimizerId) { const bidOptimizerPropertyResponse = await super.requestGatewayHelper('GET', `${this.outboundPlatformUrl}/v1/bid_optimizers/${bidOptimizerId}/properties`); this.logger.debug(`Fetched BidOptimizer Properties: ${bidOptimizerId} - ${JSON.stringify(bidOptimizerPropertyResponse.data)}`); return bidOptimizerPropertyResponse.data; } findBestSalesConditions(bidPrice, salesConditions) { // Optimization, we only do the stringify if we are really on debug / silly mode if (this.logger.level === 'debug' || this.logger.level === 'silly') { this.logger.debug(`Looking to find the best sale condition for CPM: ${bidPrice} in: ${JSON.stringify(salesConditions, null, 4)}`); } const eligibleSalesConditions = salesConditions.filter((sc) => { return sc.floor_price <= bidPrice; }); // Optimization, we only do the stringify if we are really on debug / silly mode if (this.logger.level === 'debug' || this.logger.level === 'silly') { this.logger.debug(`Found eligible sales condition for CPM: ${bidPrice} in: ${JSON.stringify(eligibleSalesConditions, null, 4)}`); } const sortedEligibleSalesConditions = eligibleSalesConditions.sort((a, b) => { return a.floor_price - b.floor_price; }); // Optimization, we only do the stringify if we are really on debug / silly mode if (this.logger.level === 'debug' || this.logger.level === 'silly') { this.logger.debug(`Sorted eligible sales condition for CPM: ${bidPrice} in: ${JSON.stringify(sortedEligibleSalesConditions, null, 4)}`); } return sortedEligibleSalesConditions[0]; } /** * Method to build an instance context * To be overriden to get a cutom behavior * This is a default provided implementation * @param bidOptimizerId */ async instanceContextBuilder(bidOptimizerId) { const bidOptimizerP = this.fetchBidOptimizer(bidOptimizerId); const bidOptimizerPropsP = this.fetchBidOptimizerProperties(bidOptimizerId); const results = await Promise.all([bidOptimizerP, bidOptimizerPropsP]); const bidOptimizer = results[0]; const bidOptimizerProps = results[1]; const context = { bidOptimizer: bidOptimizer, properties: new common_1.PropertiesWrapper(bidOptimizerProps), }; return context; } async getInstanceContext(bidOptimizerId) { if (!this.pluginCache.get(bidOptimizerId)) { void this.pluginCache.put(bidOptimizerId, this.instanceContextBuilder(bidOptimizerId).catch((err) => { this.logger.error(`Error while caching instance context: ${err.message}`); this.pluginCache.del(bidOptimizerId); throw err; }), this.getInstanceContextCacheExpiration()); } return this.pluginCache.get(bidOptimizerId); } initBidDecisions() { this.app.post('/v1/bid_decisions', this.asyncMiddleware(async (req, res) => { if (!this.httpIsReady()) { const msg = { error: 'Plugin not initialized', }; this.logger.error('POST /v1/bid_decisions : %s', JSON.stringify(msg)); return res.status(500).json(msg); } else if (!req.body || lodash_1.default.isEmpty(req.body)) { const msg = { error: 'Missing request body', }; this.logger.error('POST /v1/bid_decisions : %s', JSON.stringify(msg)); return res.status(500).json(msg); } else { if (this.logger.level === 'debug' || this.logger.level === 'silly') { this.logger.debug(`POST /v1/bid_decisions ${JSON.stringify(req.body)}`); } const bidOptimizerRequest = req.body; if (!this.onBidDecisions) { const errMsg = 'No BidOptimizer listener registered!'; this.logger.error(errMsg); return res.status(500).json({ error: errMsg }); } const instanceContext = await this.getInstanceContext(bidOptimizerRequest.campaign_info.bid_optimizer_id); const bidOptimizerResponse = await this.onBidDecisions(bidOptimizerRequest, instanceContext); if (this.logger.level === 'debug' || this.logger.level === 'silly') { this.logger.debug(`Returning: ${JSON.stringify(bidOptimizerResponse)}`); } return res.status(200).send(JSON.stringify(bidOptimizerResponse)); } })); } } exports.BidOptimizerPlugin = BidOptimizerPlugin; //# sourceMappingURL=BidOptimizerBasePlugin.js.map