Part 3: Run Adobe Target NodeJS SDK for Experimentation and Personalization on Edge Platforms (CloudFlare Workers)
Author: Artur Ciocanu (arturc85303583)

Adobe Target NodeJS SDK with On-Device Decisioning capabilities and how to run it in a serverless/edge compute environment. In this third installment, we will be covering Cloudflare Workers. The parts are:- Part 1: Akamai Edge Workers and Adobe Target NodeJS SDK
- Part 2: AWS Lambda@Edge and Adobe Target NodeJS SDK
- Part 3: Cloudflare Workers and Adobe Target NodeJS SDKStep by step guide
Step by step guide
- Cloudflare Account: You will need a valid Cloudflare account and credentials. Terraform relies on these credentials.
- Terraform: We will use it to create all the required Cloudflare resources. Please check the official Hashicorp documentation on how to install Terraform on your particular OS. In this article we will be showing examples using Mac OS X.
- NodeJS: We will use NodeJS to get the Adobe Target NodeJS SDK dependency as well as using NPM to package the JavaScript code and prepare it for Cloudflare Worker.
Creating the zone
resource "cloudflare_zone" "zone" {
zone = var.zone_name
}
cloudflare_zone resource like plan, type, etc but what we have is enough for our sample.Creating the worker script
Adobe Target NodeJS SDK dependency. This can be achieved using:$ npm i /target-nodejs-sdk -P
import TargetClient from "@adobe/target-nodejs-sdk";
import RULES from "./rules";
const createTargetClient = () => {
return new Promise(resolve => {
const result = TargetClient.create({
client: "targettesting",
organizationId: "74F652E95F1B16FE0A495C92@AdobeOrg",
decisioningMethod: "on-device",
artifactPayload: RULES,
logger: console,
events: {
clientReady: () => resolve(result)
}
});
});
};
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
const headers = {
headers: {
"content-type": "application/json"
}
};
const body = await request.json();
const response = await createTargetClient()
.then(client => client.getOffers({request: body}))
.then(deliveryResponse => deliveryResponse.response)
.catch(error => error);
return new Response(JSON.stringify(response), headers);
}
Note: The RULES constant references the On-Device Decisioning artifact rules.json file. This file can be downloaded from https://assets.adobetarget.com/<client code>/production/v1/rules.json. This file will be available only after you have enabled On-Device Decisioning for your Adobe Target account.
As in all the previous blogs, we have configured Adobe Target NodeJS SDK instance to use On-Device Decisioning to avoid hitting Target Edge network.
The Cloudflare Worker environment is quite similar to a browser ServiceWorker, so we can't really use Adobe Target NodeJS SDK as-is. We will have to make sure that the worker script is bundled for the "browser" environment, instead of the default NodeJS runtime. We will be leveraging Rollup and it's resolve plugin to make sure that we package everything neatly for the worker environment. More details and the necessary configurations for Rollup can be found in this repo.
Creating the worker route
So far we have created the zone and the worker script. To be able to access the worker via HTTP we have to create a worker route. Using Terraform this can be accomplished using this script:
resource "cloudflare_worker_route" "route" {
zone_id = cloudflare_zone.zone.id
pattern = var.route_pattern
script_name = cloudflare_worker_script.script.name
}
zone ID and script name. Another important piece is the pattern which in the simplest case can represent just the URL path that will be used to execute the worker script.Testing it out
Cloudflare Worker. To make sure that everything is running properly we can use cURL:curl --location --request POST 'https://odd.bpack.workers.dev/rest/v1/personalization' \
--header 'Content-Type: application/json' \
--data-raw '{
"execute": {
"pageLoad": {}
}
}
'
workers.dev domain for demo purposes. The output of the cURL command would look something like this:{
"status": 200,
"requestId": "9a08adf5a9d04d9bb014f810facee8bb",
"id": {
"tntId": "3665f03437a64ce886e0f1d4a95bb4dc.37_0"
},
"client": "targettesting",
"execute": {
"pageLoad": {
"options": [
{
"type": "html",
"content": "<div>Srsly, who dis?</div>",
"responseTokens": {
"activity.id": 125880,
"activity.name": "[unit-test] target-global-mbox browsers",
"experience.id": 3,
"experience.name": "Experience A",
"offer.id": 246867,
"offer.name": "/_unit-test_target-global-mboxbrowsers/experiences/3/pages/0/zones/0/1612389131041",
"option.id": 5,
"option.name": "Offer5",
"activity.decisioningMethod": "on-device"
}
},
{
"type": "html",
"content": "<div>lion</div>",
"responseTokens": {
"activity.id": 125884,
"activity.name": "[unit-test] target-global-mbox creatures",
"experience.id": 2,
"experience.name": "Experience C",
"offer.id": 246876,
"offer.name": "/_unit-test_target-global-mboxcreatures/experiences/2/pages/0/zones/0/1612389727806",
"option.id": 4,
"option.name": "Offer4",
"activity.decisioningMethod": "on-device"
}
}
]
}
}
}
Closing thoughts
I really enjoyed working with Cloudflare Worker. The Cloudflare Terraform provider covers everything that I need and it was really, really easy to have everything up and running, even for a newcomer like myself.
I should highlight that I haven’t used Cloudflare Wrangler. For anyone doing serious Cloudflare Worker development, Wrangler should be the go-to tool. In my case the development flow was something like:
- Adjust worker script
- Run
NPMbuild script - Run
Terraformto upload the new bundle - Run
cURL - If something is not quite OK, go to
1.
Terraform scripts, Rollup configuration and the sample worker script. It was quite a surprise to see how quickly I can change the code, upload it to Cloudflare network and see it running via cURL, literally in a matter of seconds. This is in stark contrast to Akamai EdgeWorkers which required many minutes until I could see the changes on the staging and production networks.ServiceWorker. Anyone who has done any WebWorker or ServiceWorker development will feel at home. For the most part standard Web APIs like fetch, Cache API, etc works as you would expect, which cuts down, significantly, the amount of "new" stuff you have to learn. This was a very smart decision made by Cloudflare Worker team.- Workers KV
- Durable Objects
- Scheduled Event
- Workers Unbound
Previous Blogs
Resources
- Source code — https://github.com/artur-ciocanu/odd-cloudflare-workers
- Adobe Target — https://business.adobe.com/products/target/adobe-target.html
- Adobe Experience Platform — https://business.adobe.com/products/experience-platform/adobe-experience-platform.html
- Adobe Target NodeJS SDK — https://adobetarget-sdks.gitbook.io/docs/sdk-reference-guides/nodejs-sdk
- Terraform — https://www.terraform.io/
- Cloudflare provider — https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs
- Cloudflare Wrangler — https://developers.cloudflare.com/workers/cli-wrangler
Originally published: Jun 3, 2021