diff --git a/README.md b/README.md index bcf27a4..49bbeb2 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,49 @@ var ad = vast.attachAd({ id : 1 , structure : 'inline' , sequence : 99 + , Error: 'http://error.err' , AdTitle : 'Common name of the ad' , AdSystem : { name: 'Test Ad Server', version : '1.0' } }); ``` +### Ad extensions + +```javascript +var VAST = require('vast-xml'); + +var vast = new VAST(); +var ad = vast.attachAd({ + id : 1 + , structure : 'inline' + , sequence : 99 + , Error: 'http://error.err' + , Extensions: ['data'] // accepts an array or string of XML, warning: XML is not validated by this library! + , AdTitle : 'Common name of the ad' + , AdSystem : { name: 'Test Ad Server', version : '1.0' } + }); +``` + +### AdVerifications (VAST 4.1) + +```javascript +var VAST = require('vast-xml'); + +var vast = new VAST({version: '4.1'}); +var ad = vast.attachAd({ + id : 'AdVerificationsExample' + , structure : 'wrapper' + , AdSystem : { name : '2.0', version : '2.0' } + , Error : 'https://error.url.com/path/p?error=true' + , AdVerifications: [{ vendor: 'thirdPartyVendor-com.omid' + , JavaScriptResource: { browserOptional: 'false', resourceUrl: 'https://path.to/adVerification/script.js'} + , trackingEvents: [{ event:'verificationNotExecuted', url: 'https://error.url.com/p?event=verificationNotExecuted?' }, {event:'secondEvent', url: 'https://second.url/p?secondEvent=true' }] + , VerificationParameters: 'Parameter=one&Parameter=two' + }] + , VASTAdTagURI : 'https://path.to.original/vast.xml' + }); +``` + ## Attach Impression tracking URLs ```javascript @@ -133,6 +171,7 @@ vast.xml({ pretty : true, indent : ' ', newline : '\n' }); Common name of the ad + http://impression.com http://sample-impression.com diff --git a/index.js b/index.js index 15ae052..3a894c5 100644 --- a/index.js +++ b/index.js @@ -16,7 +16,9 @@ var xml = function(options) { if (ad.structure.toLowerCase() === 'wrapper') { var wrapper = Ad.element('Wrapper'); wrapper.element('AdSystem', ad.AdSystem.name, { version : ad.AdSystem.version }); - wrapper.element('VASTAdTagURI', ad.VASTAdTagURI); + wrapper.element('VASTAdTagURI').cdata(ad.VASTAdTagURI); + if (ad.Error) + wrapper.element('Error').cdata(ad.Error); ad.impressions.forEach(function(impression) { if (track) wrapper.element('Impression').cdata(impression.url); }); @@ -56,7 +58,8 @@ var xml = function(options) { icon.element(r.type, r.uri, (r.creativeType) ? { creativeType : r.creativeType } : {}); }); }); - creativeType.element('Duration', c.Duration); + //creativeType.element('Duration', c.Duration); + creativeType.element('Duration').cdata(c.Duration); var trackingEvents = creativeType.element('TrackingEvents'); c.trackingEvents.forEach(function(trackingEvent){ if (track) { @@ -68,7 +71,7 @@ var xml = function(options) { if (c.AdParameters) creativeType.element('AdParameters').cdata(c.AdParameters); var videoClicks = creativeType.element('VideoClicks'); c.videoClicks.forEach(function(videoClick){ - videoClicks.element(videoClick.type, videoClick.url, { id : videoClick.id }); + videoClicks.element('ClickThrough', videoClick.attributes).cdata(videoClick.url) }); var mediaFiles = creativeType.element('MediaFiles'); c.mediaFiles.forEach(function(mediaFile) { @@ -97,6 +100,41 @@ var xml = function(options) { if (r.adParameters) companion.element('AdParameters', r.adParameters.data, { xmlEncoded : r.adParameters.xmlEncoded }); }); }); + if (ad.Extensions) { + var extensions; + if(inline != void 0) extensions = inline.element('Extensions'); + if(wrapper != void 0) extensions = wrapper.element('Extensions'); + [].concat(ad.Extensions).forEach(function(extension) { + extensions.element('Extension', {type: 'AdVerifications'}).raw(extension); + }); + } + + if (ad.AdVerifications){ + // VAST 4.1 necessary + var adVerifications; + if(wrapper != void 0) adVerifications = wrapper.element('AdVerifications'); + + [].concat(ad.AdVerifications).forEach(function(currentVerifiction){ + + var ad_verifications = adVerifications.element('Verification', {vendor: currentVerifiction.vendor}); + + [].concat(currentVerifiction).forEach(function(verif) { + // browserOptional -> true would signify that it's our native script -> e.g. to run in iOS' JSContext + // false meaning that the resource needs a true JS environment + ad_verifications.element('JavaScriptResource', {browserOptional: verif.JavaScriptResource.browserOptional}).cdata(verif.JavaScriptResource.resourceUrl); + + if(verif.trackingEvents) { + var trackElementsNode = ad_verifications.element('TrackingEvents'); + var currentTrackingEvent = verif.trackingEvents; + [].concat(currentTrackingEvent).forEach(function(currentTrackingEvent){ + trackElementsNode.element('Tracking', {event: currentTrackingEvent.event}).cdata(currentTrackingEvent.url); + }); + } + ad_verifications.element('VerificationParameters').cdata(verif.VerificationParameters); + }); // end of concat each Verification Node + }); + } + }); return response.end(options); }; diff --git a/lib/ad.js b/lib/ad.js index ce65f70..ef16a1b 100644 --- a/lib/ad.js +++ b/lib/ad.js @@ -40,6 +40,7 @@ function Ad(settings) { this.Error = settings.Error; this.Description = settings.Description; this.Advertiser = settings.Advertiser; + this.AdVerifications = settings.AdVerifications; // vast 4.1 this.surveys = []; this.attachSurvey = function(settings) { var survey = { url : settings.url }