Note
MappIntelligenceTrackingandMappIntelligenceHybridcarry the data of the current request (user agent, IP address, cookies, everID). Create one instance per request and close it when the request is done:await mappIntelligence.close()(see close).The library adds no listener for signals (
SIGINT,SIGTERM) oruncaughtException, so it does not change how your application ends. An instance that is not closed sends its remaining requests only after it has been garbage collected or when the event loop runs empty (beforeExit), but not onprocess.exit()or a signal. If your application handlesSIGTERMitself (e.g. to stop the HTTP server), close the instances that are still open there.
Methods
constructor
For a complete configuration of the Mapp Intelligence js library please check Configuration.
/**
* @param config Mapp Intelligence configuration
*/
const mappIntelligence = new MappIntelligenceTracking(config: MappIntelligenceConfig);track
Adds the data to the request queue. Adding sends nothing: the queue is sent via flush(), every requestInterval seconds, when it reaches maxQueueSize or when the instance is closed (see close). For a complete data configuration of the Mapp Intelligence js library, please check Data.
The promise resolves to false if the data was not added (tracking deactivated, track ID or track domain missing, tracking deactivated by the include/exclude configuration, unsupported data or the instance is already closed). After close(), the request is logged at level ERROR: Request rejected, the tracking instance is already closed: <request>.
/**
* @param [data] Mapp Intelligence parameter or data map
*
* @return Promise<boolean>
*/
mappIntelligence.track(data?: MappIntelligenceParameterMap | MappIntelligenceDataMap);flush
Sends all requests in the queue to the Mapp tracking servers. The promise resolves to true if everything was delivered, and to false if requests are still in the queue or a batch was discarded. Flushes run one after another: a flush that starts while another one is running waits for it and then sends what is left.
After close(), flush() sends nothing: it logs Flush ignored, the tracking instance is already closed. at level WARN, calls the setOnFlushComplete callback and resolves to true if the queue is empty.
/**
* @return Promise<boolean>
*/
await mappIntelligence.flush();setOnFlushComplete
Here you can define a callback that is called after each flush with the result of the flush (true if everything was delivered). It is called for flush(), for the flush of requestInterval, for the flush when the queue reaches maxQueueSize and for close(). The result is false as well if a batch was discarded (see Data Transfer: Consumer). A callback that throws is logged at level ERROR.
A callback that references the tracking instance keeps it reachable: an instance that is never closed is then not cleaned up after garbage collection.
/**
* @param callback Callback after every flush, with the result of the flush
*/
mappIntelligence.setOnFlushComplete((wasRequestSuccessful: boolean) => {});close
Sends the remaining requests and releases the consumer. Afterwards every track() call is rejected (see above). The promise resolves to true if no request remains unsent and no batch was discarded.
close()waits for flushes that are still running, but at most 30 seconds, including the retries (maxAttempt×attemptTimeout) and the time the consumer needs. If the time expires,Timeout after 30000 ms while waiting for the queue to be flushed, ...is logged at level WARN and the promise resolves tofalse; the last batch is still sent in the background.close()is idempotent: every call returns the result of the first one.A consumer that you passed in via the configuration (
setConsumer) is not closed by the library.If the process ends with requests that were never sent (e.g.
process.exit()withoutclose()),The process ends with <n> unsent req. in the queue, call close() before the process ends.is logged at level ERROR.
/**
* @return Promise<boolean>
*/
await mappIntelligence.close();Example
app.get('/product', async function(request, response) {
// a new configuration per request, so no request data of a previous user is kept
const mappConfig = new MappIntelligenceConfig('111111111111111', 'analytics01.wt-eu02.net')
.setRequestURL('https://' + request.headers['host'] + request.url)
.setReferrerURL(request.headers['referer'])
.setUserAgent(request.headers['user-agent'])
.setRemoteAddress(request.socket.remoteAddress);
const mappIntelligence = new MappIntelligenceTracking(mappConfig);
try {
await mappIntelligence.track(new MappIntelligenceDataMap().page(new MappIntelligencePage('en.product')));
} finally {
await mappIntelligence.close();
}
response.send('...');
});getTransmittedCampaignsCookie
Returns the cookie wtstp_tcc with the campaigns that were already transmitted in this session, or null if nothing changed. Add it to the HTTP response, otherwise MappIntelligenceCampaign.setOncePerSession(true) cannot work across requests (see Campaign). It is a session cookie (getMaxAge() returns -1), not HttpOnly (the client-side pixel reads it as well) and Secure unless the request URL uses plain HTTP. The value is URL encoded and keeps the newest campaigns within 4000 characters.
/**
* @return IMappIntelligenceCookie
*/
const campaignCookie = mappIntelligence.getTransmittedCampaignsCookie();getUserIdCookie
It is important to uniquely identify a user to fully benefit from Mapp Intelligence tracking capabilities. Mapp Intelligence uses the everID (eid) internally to keep the tracking information aligned to a user. You can either pass your own unique identifier or you can use the library to use an existing everID (see Configuration → setCookie). If you track with both the server-side library and the pixel and you use the getUserIdCookie() method, an eid cookie is returned (see IMappIntelligenceCookie), which you then returned to the client.
If no everID exists yet, getUserIdCookie() creates one, and every request that is added afterwards contains it (eid). Call it before track(): requests that are already in the queue do not get the everID.
The method returns null:
without track ID or track domain (logged at level ERROR); no everID is created,
if an everID already exists: read from the cookies of the configuration (
wtstp_eid,wteid_<trackId>orwt3_eid, seesetCookie()) or created by an earlier call,with
SERVER_SIDE_COOKIEand a Mapp track domain (*.wt-*.net,*.webtrekk.net,*.webtrekk-*.net): the cookie can only be set for your own track domain,with
CLIENT_SIDE_COOKIEand a pixel version other thanV4,V5orSMART.
In the last two cases the everID is still created and added to the following requests.
Context / pixel version | Cookie |
|---|---|
|
|
|
|
|
|
Every returned cookie has the path /, a max age of 6 months (in seconds) and is Secure and HttpOnly.
Options
MappIntelligenceTracking.V4 | pixelVersion |
MappIntelligenceTracking.V5 | pixelVersion |
MappIntelligenceTracking.SMART | pixelVersion |
MappIntelligenceTracking.CLIENT_SIDE_COOKIE | context |
MappIntelligenceTracking.SERVER_SIDE_COOKIE | context |
/**
* @param pixelVersion Version ot the current pixel (v4, v5, smart)
* @param context Cookie context (1, 3)
*
* @return IMappIntelligenceCookie
*/
const mappCookie: IMappIntelligenceCookie = mappIntelligence.getUserIdCookie(pixelVersion: string, context: string);Example
const mappIntelligence = new MappIntelligenceTracking(mappConfig);
// before track(): the everID is added to the request
const mappUserCookie = mappIntelligence.getUserIdCookie(
MappIntelligenceTracking.SMART,
MappIntelligenceTracking.CLIENT_SIDE_COOKIE
);
try {
await mappIntelligence.track(new MappIntelligenceDataMap().page(new MappIntelligencePage('en.home')));
} finally {
await mappIntelligence.close();
}
if (mappUserCookie) {
response.cookie(mappUserCookie.getName(), mappUserCookie.getValue(), {
path: mappUserCookie.getPath(),
secure: mappUserCookie.isSecure(),
// seconds, Express expects milliseconds
maxAge: mappUserCookie.getMaxAge() * 1000,
httpOnly: mappUserCookie.isHttpOnly()
});
}Methods
constructor
For a complete configuration of the Mapp Intelligence Hybrid please check Configuration.
The hybrid writes the pixel requests into the request logging files: it switches the consumer type to FILE (batch size 1), only for this instance; the configuration of the caller keeps its consumer type. With the consumer type CUSTOM it keeps the configuration and uses the consumer of setConsumer() instead of the file. Like everywhere, a consumer set with setConsumer() is used with every consumer type (see Configuration).
/**
* @param config Mapp Intelligence configuration
*/
const mappIntelligenceHybrid = new MappIntelligenceHybrid(config: MappIntelligenceConfig);track
Reads all query parameters from the current request URL and saves them in the file.
Only pixel requests are saved: the query string must contain the parameter p and must not be larger than 64 KB, any other request is ignored with a warning (Request ignored, it has no pixel parameter "p" or is larger than 65536 bytes). The parameters that only the server adds (the IP address X-WT-IP, the user agent X-WT-UA and the client hints X-WT-SEC-CH-UA*) are removed from the request of the client, so a client cannot pretend to be another user; the library adds them from the configuration. An invalid request URL tracks nothing.
A request that was added is written right away (the hybrid flushes after every request). With setDeactivate(true) or without a request URL nothing happens. After close(), the request is rejected and logged at level ERROR.
/**
* @param [rURL] request url with query parameters, default: the request URL of the configuration
*
* @return Promise<void>
*/
await mappIntelligenceHybrid.track(rURL?: string);flush
Same as MappIntelligenceTracking.flush().
/**
* @return Promise<boolean>
*/
await mappIntelligenceHybrid.flush();setOnFlushComplete
Same as MappIntelligenceTracking.setOnFlushComplete().
/**
* @param callback Callback after every flush, with the result of the flush
*/
mappIntelligenceHybrid.setOnFlushComplete((wasRequestSuccessful: boolean) => {});close
Same as MappIntelligenceTracking.close(): sends the remaining requests, waits up to 30 seconds and is idempotent. Use one instance per request and close it (see the example below).
/**
* @return Promise<boolean>
*/
await mappIntelligenceHybrid.close();getUserIdCookie
Same as MappIntelligenceTracking.getUserIdCookie() (see above), with the constants MappIntelligenceHybrid.V4, V5, SMART, CLIENT_SIDE_COOKIE and SERVER_SIDE_COOKIE. The everID is not added to the pixel requests, the pixel sends its own.
/**
* @param pixelVersion Version ot the current pixel (v4, v5, smart)
* @param context Cookie context (1, 3)
*
* @return IMappIntelligenceCookie
*/
const mappCookie: IMappIntelligenceCookie = mappIntelligenceHybrid.getUserIdCookie(pixelVersion: string, context: string);getTransmittedCampaignsCookie
Same as MappIntelligenceTracking.getTransmittedCampaignsCookie(). The hybrid does not evaluate campaigns itself, so the method returns null.
/**
* @return IMappIntelligenceCookie
*/
const campaignCookie = mappIntelligenceHybrid.getTransmittedCampaignsCookie();isValidPixelRequest (static)
Checks a query string the way track() does: it must contain the pixel parameter p with a value and must not be larger than MappIntelligenceHybrid.MAX_REQUEST_LENGTH (65536 bytes).
/**
* @param queryString Query string of the pixel request (without "?")
*
* @return boolean
*/
const isValid = MappIntelligenceHybrid.isValidPixelRequest(queryString: string);getResponseAsBase64
As response, the method returns a 1x1px transparent gif, which you then returned to the client.
/**
* @return Returns a 1x1px transparent gif as base64 string.
*/
const imageString = mappIntelligenceHybrid.getResponseAsBase64();getResponseAsBuffer
As response, the method returns a 1x1px transparent gif, which you then returned to the client.
/**
* @return Returns a 1x1px transparent gif as buffer.
*/
const imageBytes = mappIntelligenceHybrid.getResponseAsBuffer();Example
import express from 'express';
import cookieParser from 'cookie-parser';
import {
MappIntelligenceConfig,
MappIntelligenceHybrid
} from '@mapp-intelligence/node';
import http from 'http';
const app = express();
app.use(cookieParser('secret'));
app.get(/\/pix\/.*/, async function(request, response) {
// set tracking configuration
const mappConfig = new MappIntelligenceConfig()
.setTrackId('111111111111111')
.setTrackDomain('analytics01.wt-eu02.net')
.setReferrerURL(request.headers['referer'])
.setRequestURL('http://' + request.headers['host'] + request.url)
.setRemoteAddress(request.headers['x-forwarded-for'] || request.socket.remoteAddress)
.setUserAgent(request.headers['user-agent']);
// read out all client cookies and add them to the configuration
const cookies = request.cookies;
if (cookies) {
for (let cookie in cookies) {
mappConfig.addCookie(cookie, cookies[cookie]);
}
}
const mappHybrid = new MappIntelligenceHybrid(mappConfig);
// writes the incoming request to the Mapp Intelligence request queue
await mappHybrid.track();
// writes the remaining requests and releases the instance
await mappHybrid.close();
// read out the existing Mapp Intelligence user cookie
const mappUserCookie = mappHybrid.getUserIdCookie(
MappIntelligenceHybrid.SMART,
MappIntelligenceHybrid.CLIENT_SIDE_COOKIE
);
if (mappUserCookie) {
response.cookie(
mappUserCookie.getName(),
mappUserCookie.getValue(),
{
domain: mappUserCookie.getDomain(),
path: mappUserCookie.getPath(),
secure: mappUserCookie.isSecure(),
// seconds, Express expects milliseconds
maxAge: mappUserCookie.getMaxAge() * 1000,
httpOnly: mappUserCookie.isHttpOnly()
}
);
}
// set content-type and length
response.writeHead(200, {
'Content-Type': 'image/gif;charset=UTF-8',
'Content-Length': '43'
});
// send an 1x1 pixel transparent gif back to the client
response.end(mappHybrid.getResponseAsBuffer(), 'binary');
});
http.createServer(app).listen(8090, '127.0.0.1', function() {
console.log('Server listen on 127.0.0.1:8090');
});MappIntelligenceDataMap
Collects the data objects of one request for track(). Every method returns the data map and replaces an object of the same kind set before. A value that is no Mapp Intelligence data object is ignored and logged at level WARN; null and undefined are ignored silently.
Method | Parameter |
|---|---|
action | |
campaign | |
customer | |
order | |
page | |
product | |
session | |
engage | |
registration | |
build | Returns the collected data as |
const dataMap = new MappIntelligenceDataMap()
.page(new MappIntelligencePage('en.product'))
.product(new MappIntelligenceProductCollection().add(new MappIntelligenceProduct('product-1')));
await mappIntelligence.track(dataMap);MappIntelligenceParameterMap
Collects the query parameters of one request for track() (see Request Parameters). track() works on a copy, so the map can be reused.
Method | Notes |
|---|---|
add(key: string, value: string) | Adds a parameter, the value is converted to a string. A key or value that is |
build() | Returns the parameters as |
MappIntelligenceProductCollection
Collects the products of one request for MappIntelligenceDataMap.product() (see Product).
Method | Notes |
|---|---|
add(value: MappIntelligenceProduct) | Adds a product. Anything that is no |
build() | Returns the products as |
MappIntelligenceQueue
The request queue behind MappIntelligenceTracking and MappIntelligenceHybrid. Use it directly only for special cases, e.g. requests that are already built. It does not check deactivate, the track ID, the track domain or the include/exclude configuration, and it is not closed automatically when it is garbage collected or the process ends: always call close().
/**
* @param config Built Mapp Intelligence configuration (MappIntelligenceConfig.build())
*/
const queue = new MappIntelligenceQueue(config.build());Method | Notes |
|---|---|
add(data: string | {[key: string]: string}) | Adds a request: a string with a complete request (e.g. |
flush() | Same as |
close(flushRemaining?: boolean, timeout?: number) | Same as |
setOnFlushComplete(callback) | Same as |
getQueue() | Returns the requests in the queue. It is the array of the queue itself, do not change it. |
isClosed() | Returns |
getUserIdCookie(pixelVersion, context) | Same as |
Constants
Class | Constants |
|---|---|
MappIntelligenceBatchResult |
|
MappIntelligenceConsumerType |
|
MappIntelligenceLogLevel |
|
MappIntelligenceTracking, MappIntelligenceHybrid |
|
MappIntelligenceHybrid |
|
MappIntelligenceQueue |
|
MappIntelligenceConfig |
|