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

107 lines (106 loc) 4.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Handlebars = require("handlebars"); const handlebars = require("handlebars"); const numeral = require("numeral"); const _ = require("lodash"); function formatPrice(price, pattern) { const number = numeral(price); return number.format(pattern); } const encodeClickUrl = () => (redirectUrls, clickUrl) => { let urls = redirectUrls.slice(0); urls.push(clickUrl); return urls.reduceRight((acc, current) => { return current + encodeURIComponent(acc); }, ""); }; const placeHolder = "{{MICS_AD_CONTENT_ID}}"; const uriEncodePlaceHolder = encodeURI(placeHolder); const doubleEncodedUriPlaceHolder = encodeURI(encodeURI(placeHolder)); // Encode recommendation click url => contains the contentId of the recommendation that will be // insrted into the campaign log const encodeRecoClickUrlHelper = () => (idx, rootContext, recommendation) => { rootContext.private.clickableContents.push({ item_id: recommendation.$id, catalog_token: recommendation.$catalog_token, $content_id: idx }); // recommendation.url replace placeHolder by idx const filledRedirectUrls = rootContext.private.redirectUrls.map((url) => { const url1 = _.replace(url, placeHolder, idx); const url2 = _.replace(url1, uriEncodePlaceHolder, idx); return _.replace(url2, doubleEncodedUriPlaceHolder, idx); }); const recommendationUrl = recommendation.$url ? recommendation.$url : ""; return encodeClickUrl()(filledRedirectUrls, recommendationUrl); }; function buildURLHandlebarsRootContext(adRenderRequest, instanceContext) { return { REQUEST: adRenderRequest, CREATIVE: { CLICK_URL: instanceContext.creative_click_url, WIDTH: instanceContext.width, HEIGHT: instanceContext.height }, ORGANISATION_ID: instanceContext.displayAd.organisation_id, AD_GROUP_ID: adRenderRequest.ad_group_id, MEDIA_ID: adRenderRequest.media_id, ENCODED_MEDIA_ID: adRenderRequest.media_id ? encodeURIComponent(adRenderRequest.media_id) : undefined, CAMPAIGN_ID: adRenderRequest.campaign_id, CREATIVE_ID: adRenderRequest.creative_id, CACHE_BUSTER: Date.now().toString(), IAS_CLIENT_ID: instanceContext.ias_client_id, CB: Date.now().toString() }; } exports.buildURLHandlebarsRootContext = buildURLHandlebarsRootContext; class HandlebarsEngine { // Initialisation of the engine. Done once at every InstanceContext rebuild. init() { this.engine = Handlebars.create(); /* Generic Helpers */ this.engine.registerHelper("formatPrice", formatPrice); this.engine.registerHelper("toJson", (object) => JSON.stringify(object)); } compile(template) { return this.engine.compile(template); } constructor() { } } exports.HandlebarsEngine = HandlebarsEngine; class RecommendationsHandlebarsEngine extends HandlebarsEngine { // Initialisation of the engine. Done once at every InstanceContext rebuild. init() { super.init(); /* URL Encoding witchcraft */ // We need to have 2 elements when doing the URL encoding: // 1. The "click tracking" array passed in the rootContext (for click tracking) // 2. The final URL (landing page, etc.) passed as a parameter of the helper // // In order to have both, we need to play smart and use an Handlebar partial // This handlebar partial is just a way to add "@root" as a parameter of the helper before calling it // // This is how the encodeClickUrl partial should be used in templates: // {{> encodeClickUrl url="http://www.mediarithmics.com/en/"}} const encodeClickUrlPartial = "{{encodeClickUrlInternal @root.private.redirectUrls url}}"; this.engine.registerPartial("encodeClickUrl", encodeClickUrlPartial); this.engine.registerHelper("encodeClickUrlInternal", encodeClickUrl()); // Same story than previously but this time the partial will inject: // @index -> the index of the recommendation, which is used to include it in the URL // @root -> the root context // this -> the recommendation item // Warning, this partial should only be used in a {{#each recommendations}}{{/each}} block // The $url field of the recommendation will be used as the final URL // // This is how the partial should be used in templates: // {{> encodeRecoClickUrl}} const encodeRecoClickUrlPartial = "{{encodeRecoClickUrlInternal @index @root this}}"; this.engine.registerPartial("encodeRecoClickUrl", encodeRecoClickUrlPartial); this.engine.registerHelper("encodeRecoClickUrlInternal", encodeRecoClickUrlHelper()); } constructor() { super(); } } exports.RecommendationsHandlebarsEngine = RecommendationsHandlebarsEngine;