@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
175 lines (148 loc) • 5.26 kB
text/typescript
import * as _ from "lodash";
import {
ItemProposal,
Creative,
AdRendererRequest,
UserCampaignResponse,
UserCampaignResource,
AdRendererRecoTemplateInstanceContext,
AdRendererBasePlugin,
RecommenderResponse,
TemplatingEngine,
AdRendererTemplateInstanceContext,
ViewabilityTags
} from "../../../index";
export abstract class AdRendererTemplatePlugin extends AdRendererBasePlugin<
AdRendererTemplateInstanceContext
> {
/**
* Helper to fetch the content of a template
* @param templatePath The raw (e.g. non URL encoded) mics URI to the template file as a string.
* @returns A Buffer with the file content in it. This have to be decoded with the proper encoding.
*/
async fetchTemplateContent(templatePath: string): Promise<Buffer> {
const templateContent = await super.fetchDataFile(templatePath);
this.logger.debug(`Fetched template : ${templateContent}`);
return templateContent;
}
/**
* Helper to fetch the properties of a template
*/
async fetchTemplateProperties(
organisationId: string,
adLayoutId: string,
versionId: string
): Promise<any> {
const templateProperties = await super.requestGatewayHelper(
"GET",
`${this
.outboundPlatformUrl}/v1/ad_layouts/${adLayoutId}/versions/${versionId}?organisation_id=${organisationId}`
);
return templateProperties;
}
/**
* The engineBuilder that can be used to compile the template
* during the InstanceContext building
*
* Have to be overriden (see examples)
*/
protected engineBuilder: TemplatingEngine<any, any, any>;
protected async instanceContextBuilder(
creativeId: string,
template?: string
): Promise<AdRendererTemplateInstanceContext> {
const baseInstanceContext = await super.instanceContextBuilder(creativeId);
const urlProperty = _.find(
baseInstanceContext.displayAdProperties,
p => p.property_type === "URL"
);
if (!urlProperty) {
const msg = `crid: ${creativeId} - url property is undefined`;
this.logger.warn(msg);
}
const IASProperty = _.find(
baseInstanceContext.displayAdProperties,
p => p.technical_name === "ias_client_id"
);
const additionalHTMLProperty = _.find(
baseInstanceContext.displayAdProperties,
p => p.technical_name === "additional_html"
);
// If no 'predefined' template was provided, we retrieve it from the platform
if (!template) {
const adLayoutProperty = _.find(
baseInstanceContext.displayAdProperties,
p => p.property_type === "AD_LAYOUT"
);
if (
!adLayoutProperty ||
!adLayoutProperty.value ||
!adLayoutProperty.value.id ||
!adLayoutProperty.value.version
) {
const msg = `crid: ${creativeId} - Ad layout undefined`;
this.logger.error(msg);
throw new Error(msg);
}
const templateProperties = await this.fetchTemplateProperties(
baseInstanceContext.displayAd.organisation_id,
adLayoutProperty.value.id,
adLayoutProperty.value.version
);
this.logger.info(
`crid: ${creativeId} - Loaded template properties
${adLayoutProperty.value.id} ${adLayoutProperty.value.version} =>
${JSON.stringify(templateProperties)}`
);
const templatePath = templateProperties.data.template;
// We assume that the template is in UTF-8
template = (await this.fetchTemplateContent(templatePath)).toString(
"utf8"
);
this.logger.info(
`crid: ${creativeId} - Loaded template content ${templatePath} =>
${JSON.stringify(template)}`
);
}
if (!this.engineBuilder) {
throw new Error(`No engine builder have been added to the plugin
An engine builder is mandatory to extend this plugin class`);
}
this.engineBuilder.init();
const compiledTemplate = this.engineBuilder.compile(template);
const creativeClickUrl =
urlProperty && urlProperty.value.url ? urlProperty.value.url : undefined;
const compiledClickUrl = creativeClickUrl
? this.engineBuilder.compile(creativeClickUrl)
: undefined;
const additionalHTML =
additionalHTMLProperty &&
additionalHTMLProperty.value &&
additionalHTMLProperty.value.value
? this.engineBuilder.compile(additionalHTMLProperty.value
.value as string)
: undefined;
const IASClientId =
IASProperty && IASProperty.value && IASProperty.value.value
? IASProperty.value.value as string
: undefined;
const width = baseInstanceContext.displayAd.format.split("x")[0];
const height = baseInstanceContext.displayAd.format.split("x")[1];
const context: AdRendererTemplateInstanceContext = {
displayAd: baseInstanceContext.displayAd,
displayAdProperties: baseInstanceContext.displayAdProperties,
width: width,
height: height,
creative_click_url: creativeClickUrl,
compiled_click_url: compiledClickUrl,
template: template,
compiled_template: compiledTemplate,
compiled_additional_html: additionalHTML,
ias_client_id: IASClientId
};
return context;
}
constructor() {
super();
}
}