The Consent API Plugin allows managing user consent preferences regarding cookies (referred to as “consent level”) over a DimML implementation. The Consent API Plugin allows for synchronizing consent over multiple domains. The Consent API Plugin ensures that the given consent level is enforced within the DimML implementation (i.e. when a user gives no consent for analytics, no data can be collected through DimML).
Parameters
Body
The Consent API Plugin does not allow for definition of a plugin body
Output effect
In web browser
The Consent API plugin exposes one object (`dimml.consent`) to the client. This object has two methods.
In web browser
The consent API plugin exposes two flows. One (urlFlow) that can be used for basic analytics on URLs based on server side data collection and one (proofFlow) that can be used for collecting the consent levels that people consent to.
The Consent plugin does not provide new DimML language constructs.
Additional Remarks
– For browser that have Do Not Track enabled, a first party cookie will be set with value 1 for `choice` since this mode is considered to be an implicit expression of non-consent by the user.
– If cookies (first and third party) are not supported through browser settings, this will be interpreted as an implicit consent of the lowest level. This choice will not show up in the proof flow. If only third party cookies are not accepted, the multi-domain consent will not be stored.
– The consent status is managed with browser cookies. Since this type of cookies is not shared among browsers, a user has to make a choice for each browser separately.
– Changes in given consent are not actively pushed to the client once O2MC Consent is loaded. In a situation where a client changes the consent level, the page code is within that pageview responsible for updating the consent status. Similarly, consent status will not be pushed to other tabs where the same page is opened.
Example
concept Global{ match '*' flow (proof) => debug flow (url) => debug plugin consent[ uid = '1', consentVersion = '1', callback = `websitenamespace.consentManager.init()`, lifetime = '31', proofFlow = 'proof', urlFlow = 'url' ] plugin debug }
The debug plugin allows the providing run time feedback on the current fields and their values. Any use of the debug flow element allows the feedback of the state at that time. Also any errors when compiling or executing the DimML code are provide in the browser. The information is share in the console log where the same concept is used as the one where the debug statement is used or the error occurs.
Parameters
None
Body
The Debug Plugin does not allow for definition of a plugin body
Output effect
Every use of the debug element for each data tuple results in the execution of a console log function contain the fields and their values. For that purpose the matched concept needs to be triggered by the browser. Note that the console flow element allows the use of server side data evaluation and debugging.
Example
concept Global{ match '*' val url = `document.location.href` flow => debug => code[view = `'1'`] => debug => code[done = `'1'`] plugin debug }
The input plugin allows the use of files as a basis for processing data. At this time only the CSV option is available for the input plugin. Every line in the file will be translated into a seperate event where each of the columns are used as fields of the input tuple. Since the files are translated into event immediately, files with a large number of lines of code could flood the output sources. Therefore it is possible to the rate at which the event are send to the flows. By default no more than 100 rows per second will be processed.
Parameters
List of string – As input the columns of the file. The names are used as fields
$options constant – Input rate: number of events per seconds
Body
The Input Plugin does not allow for definition of a plugin body
Output effect
Every line of the file will be translated into a separate event to the unnamed flow of the DimML concept. The columns of each line are translated into fields. All unnamed flows will be called immediately in parallel for each of the events in parallel; no sequence can be counted upon.
Example
concept Input { match '*' plugin input:csv['field1','field2'] flow => buffer:aggregate['1s', count = 'count field1'] => console const $options = `{inputRate: 500}` }
curl -H "Content-Type: text/csv" -i -X POST --data-binary @data.csv --referer http://www.example.com/csvinput/other?dimml=plem http://dynamic.dimml.io/input
concept Input { match '*csvinput*' plugin input:csv['field1','field2','field3','field4'] flow => select[`field4 != null`@groovy] => buffer:aggregate['1s', count = 'count field1'] => console const $options = `{inputRate: 500}` } concept Global { match '*' .. }
The output plugin allows the use of server side data inside an instruction back into the original source of an event. Code for the fields in the source (vals) is executed before server side processing takes place and does not provide a way to receive data afterwards. At this time the output plugin is only available for web pages triggering a request to DimML by the SLOC. Therefore the code block as body is currently only Javascript. In the execution of that block, data processed server side by a DimML application is available.
Parameters
Flow name – Flow name of the flow that executes server side and provides input to the output plugin
Body
Source code for the channel triggering the event
Output effect
With the use of the out code element all fields and their values at that time are collected and the output plugin is triggered. The fields will be available as local variables in the body of the plugin. After the flow has executed completely, the body will be send back to the source and executed there.
Example
concept Global { match '*' val url = `window.location.href` val SessionId = `sessionStorage.dimmlcid=sessionStorage.dimmlcid||guid()` flow(in) => session['SessionId', PagePath = `(session.pagepath=(session.pagepath?:[]))<<url`@groovy] //The out element is necessary for the output plugin to work! => out plugin debug plugin output[flowName = 'in'] ` console.log('data in the output plugin:'+PagePath); ` }
The request plugin makes headers and other properties of the request available as fields in the data tuple
Parameters
Body (only for rest)
Output effect
All field assignments are executed and the fields are available with their new values
Example
@groovy concept GetAllHeaders { match 'headers' request[allheaders = `headers`] flow => console } concept Test { match '*' request[ref = `headers.referer`] flow => console }
The rest plugin creates a REST API and allows the definition of endpoints and matching concepts. The plugin is used both in a high level concept as well as in the specific concepts that the high level concept points to. In the specific concepts the name of the plugin is rest:json, indicating that the data is processed in JSON format. Currently no other formatting options are available.
The rest plugin facilitates the HTTP methods GET, POST, PUT and DELETE. Apart from pointing a specific URI to a DimML concept, parameters can also be captured from the URI and made available as field in the data tuple. The out flow element is used to send the current data tuple as response. Additionally all query parameters of the URI are available as fields in the data tuple.
Parameters (only for rest:json)
Body (only for rest)
Output effect
Every call to the REST API will result in a event being processed according to the URI end point that is called. The data tuple that is set at the moment the out flow element is executed, is provided as response.
Example
@groovy concept API { match '*restapi*' rest ' GET /user => ListUsers POST /user => AddUser GET /user/:id => GetUser PUT /user/:id => UpdateUser * => Error ' } concept ListUsers extends JSON { flow(api_call) => code[conceptName = `'ListUsers'`] => filter['conceptName'] => out } concept AddUser extends JSON { flow(api_call) => code[conceptName = `'AddUser'`] => filter['conceptName'] => out } concept GetUser extends JSON { flow(api_call) => code[conceptName = `'GetUser'`] => filter['conceptName','id'] => out } concept UpdateUser extends JSON { flow(api_call) => code[conceptName = `'UpdateUser'`] => filter['conceptName','id'] => out } concept Error extends JSON { flow(api_call) => code[conceptName = `'Error'`] => filter['conceptName'] => out } concept JSON { rest:json[omitList = 'true', flowName = 'api_call', bodyField = 'body'] }
curl -H "Content-Type: text/csv" -i --referer "http://www.yourdomain.com/restapi?dimml=yourenvironment" dynamic.dimml.io/ListUsers
The Script plugin makes sure that a piece of Javascript code is executed whenever the concept is matched. The difference with executing Javascript code in the Pre Match is that the Pre Match code is run before concept matching takes place and therefore the Pre Match Javascript code is always executed. The script plugin has a code block as body which will always be executed as client side Javascript.
The script plugin is executed in parallel to the client side Javascript code in the val/field definitions. Therefore no data can be share accross these two options for executing Javascript code.
Note that the output plugin is executed after the execution of all flows and not when the concept is matched. The output plugin can be used to execute Javascript code, using data processed server side by a flow.
Example
concept Global { match '*' plugin script ` console.log('the script plugin executed this code') ` }
The O2MC Platform Validator Plugin allows users to validate arbitrary data input following user-defined rules. These rules are defined by extending the indivual fields at the start by extending the val statements. Validation on fields can occur based on fixed values, regular expressions and code (resulting in a boolean result). For each individual field validation an event is triggered in the validation flow. As a result a single event with 5 fields, could lead to 5 validation events handled by the validation flow.
Parameters
Body
When a body is specified, the validator plugin no longer collects data using the standard collection mechanism. The body is interpreted as Javascript that can use an injected function named ‘validate’ to send a JSON object that requires validation. This separates the code that collects data from the validator plugin and is mainly used when validating analytics and marketing pixels.
**NOTE:** In previous versions of the validator plugin collecting (additional) values required the plugin body to return a JSON object that includes these values. This is now achieved through the same mechanism as normal data collection: the *val* statement. Values are collected as they normally would; you should no longer use ‘= null'; the JSON object to validate (as described in the previous paragraph) is available as the variable ‘data’.A validation rule that uses data collected through the body of the validator plugin would look like this:
val pageName[validation = 'home'] = `data.pageName`
Output effect
In web browser
The validator plugin does not expose any new functionality within the client’s browser.
Server side
The validator plugin adds three language constructs to the DimML language. A full example of a validation rule with all supported functionality is as follows:
val pageName[ validation = `validatePagename(value)`, validationLabel = 'correct-pagename', validationMessage = 'something went wrong at :url' ] = `data.pageName`
The Validator Plugin implements a flow that can be named using the *flowName* parameter. The flow contains tuples with a tuple per validation rule and per tuple the label of the validation rule, the name of the variable, the result of the validation rule and an optional validation message. The implementation in the example would give the following output if the validation rule would not hold:
{validation: false, validationMessage: 'pagename at http://example.com/index.html is not home', validationLabel: 'correct-pagename', validationName: 'pageName'}
If the validation rule would hold the flow would contain the following tuple:
{validation: true, validationLabel: 'correct-pagename', validationName: 'pageName'}
Example
concept Global { val pageName[ validation = `validatePagename(value)`, validationLabel = 'correct-pagename', validationMessage = 'something went wrong at :url' ] = `data.pageName` val url = `location` def validatePagename = {pageName => ` if (pageName == 'home') return true; else return "pagename at :url is not home"; `} flow (validate) => debug plugin validator [flowName = 'validate'] `captureSC(validate)` def captureSC = {validate => ` validate({pageName: 'not home'}); `} plugin debug }