Solved

Segment EdgeSDK and payload modification

  • 9 March 2024
  • 3 replies
  • 65 views

Userlevel 1
Badge

We are starting to use the Segment EdgeSDK and I currently have some analytics.js middleware functions that I would like to move to my edge worker so that they can be maintained across our properties.  Specifically, I am modifying the campaign context to normalize UTM parameters to improve the adhoc reporting in GA.

Does anyone have any experience doing this? Or maybe an example they could share?

Thanks,

Chris

icon

Best answer by Chris Carrel 29 March 2024, 14:57

View original

3 replies

Userlevel 2

Hi Chris! 

Thank you for the question. I did some digging internally on this (apologies for the delayed reply) and was told that this is not currently supported on server side. Also, edge functions is only supported for mobile right now.

Based on this case and a few others, we’ve engaged our eng team to explore supporting this, so stay tuned!

 

Thanks again!

 

Userlevel 1
Badge

@Adam Barth thanks for looking into this for me.  Let me know if there is anything I can do to help support improving this functionality.

 

Updated: I did want to confirm we are talking about the same thing.  I was referring to Segment analytics.js running on Cloudfare Worker (https://segment.com/blog/twilio-segment-edge-sdk/).  The link you sent was for something different, but does highlight that there could be a “naming” problem here.

Userlevel 1
Badge

@Adam Barth and anyone else that is interested.  I was able to figure this out.  

In the index.ts file I added a function to update the payload of my page events, basically I am trying to handle outdated UTM parameters and inconsistency.

 

function cleanRequest(body:any):any {

console.log("Clean Page View");

 

if (body.hasOwnProperty('context') && body.context.hasOwnProperty('page')) {

let qs = (body.context.page.hasOwnProperty('search')) ? body.context.page.search : "";

let url = (body.context.page.hasOwnProperty('url')) ? body.context.page.url : "";

let queryParams = new URLSearchParams(qs);

let newURL = new URL(url);

 

let oSource:string = "";

if (! body.context.hasOwnProperty('campaign') ) body.context.campaign = {};

 

if ( body.context.campaign.hasOwnProperty('source') ) {

oSource = body.context.campaign.source.toLowerCase();

} else if (queryParams.has('utm_source')) {

oSource = (queryParams.get('utm_source') + "").toLowerCase();

}

// const map = sourcemap as CampaignSources;

console.log(JSON.stringify(sourcemap));

 

let newSrc = sourcemap.find(o => (o.origsrc+"").toLowerCase() === oSource);

 

if (typeof newSrc !== 'undefined' ) {

body.context.campaign.source = newSrc.source;

body.context.campaign.medium = newSrc.medium;

queryParams.set('utm_source', newSrc.source);

queryParams.set('utm_medium', newSrc.source);

 

body.context.page.search = "?"+queryParams.toString();

body.context.page.url = newURL.protocol + '//' + newURL.hostname

+ newURL.pathname + "?"+queryParams.toString();

body.properties.search = "?"+queryParams.toString();

body.properties.url =newURL.protocol + '//' + newURL.hostname

+ newURL.pathname + "?"+queryParams.toString();

 

}

}

return body;

};

 

In the default function I look for page calls or just pass the original call to Segment.

 

const url = new URL(request.url);

const parts = url.pathname.split("/");

const method = parts.pop();

 

let newRequest;

if (method == 'p') {

let body:any = await request.json();

body = cleanRequest(body);

newRequest = new Request(request, { body: JSON.stringify(body) } );

} else {

// newRequest = request;

newRequest = new Request(request);

}


 

console.log("Write Key: " + env.WRITEKEY);

const segment = new Segment(

{

writeKey: wKey, // writeKey: env.WRITEKEY,

routePrefix: "u", // path prefix for serving Segment assets

personasSpaceId: "...", // optional

personasToken: "...", // optional

},

{

ajsInjection: false,

edgeVariations: false,

proxyOrigin: false,

edgeContext: true,

serverSideCookies: true

}

);

const resp = await segment.handleEvent(newRequest);

return resp;

 

So effectively adding AJS Middleware functionality at the Edge.  The only issue I have with this solution is related to Heap Analytics because it uses its own JS and not PAGE calls which means it doesn’t pick up these changes, but that is more of a Heap issue.

Reply