Simple Redirector for ad publishers
Tags: cloudflare, serverless
Published: 2019-07-30 15:55:31

## Premise
Retail owners publish and push ads that consist of news articles and blogs that talk about their products. 

For example - Uber Eats could create an ad with a Forbes article that talks about how great uber eats is. 

## Problem
Retail owners are unable to track users who have clicked on these ads when the ad content itself is for third party site.

For example - As the owner of Uber Eats I would like to ensure that I know when a user who has clicked on these ads visit my site so I can either target them with better pricing or better offers. 

## Solution 

DIY method (Cheapest Option): Create a CF worker that allows you to drop a cookie along with a redirect so you can track the cookie when a particular user visits your site
Paid Solution(A tad bit expensive): It's possible that Third-Party tools offer the same solution but they usually have a lot more other services that might not be required.


### CloudFlare Worker Solution

Three parts to the worker solution

a) Find a query string parameter within the incoming URL. Credits to [Emedara](https://community.cloudflare.com/u/emedara) for the code snippet 

```javascript
//function to handle the request
async function handleRequest(request) {
  const url = request.url
	// Function to parse query strings
	function getParameterByName(name) {
		name = name.replace(/[\[\]]/g, '\\$&')
		name = name.replace(/\//g, '')
		var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
			results = regex.exec(url)
		if (!results) return null
		else if (!results[2]) return ''
		else if (results[2]) {
			results[2] = results[2].replace(/\//g, '')
		}
		return decodeURIComponent(results[2].replace(/\+/g, ' '));
	}
```

b) Find final destination url and campaign cookie you set within the ad CTA url

```javascript 
// Using the function getParameterByName to extract finalurl
var finalURL = getParameterByName('finalurl')
console.log(finalURL)

//conditionally add a campaign cookie you wish to add to the url 
var utmcookie = getParameterByName('utm_camp')
var utmcookiedomain = 'campagincookie='+ utmcookie + '; Domain=redirect.akhil.workers.dev; Max-Age=40000'
console.log(utmcookie)

```

c) Issue the redirect to the final destination with the set-cookie parameter

```javascript
//issue the redirect 
return new Response('', {
  status: 302,
  headers: {
    Location: finalURL,
   'Set-Cookie':utmcookiedomain,
  }
 })

```

Full Code
```javascript 

addEventListener('fetch', async event => {
  event.respondWith(handleRequest(event.request))
})

//function to handle the request
async function handleRequest(request) {
  const url = request.url
	// Function to parse query strings
	function getParameterByName(name) {
		name = name.replace(/[\[\]]/g, '\\$&')
		name = name.replace(/\//g, '')
		var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
			results = regex.exec(url)
		if (!results) return null
		else if (!results[2]) return ''
		else if (results[2]) {
			results[2] = results[2].replace(/\//g, '')
		}
		return decodeURIComponent(results[2].replace(/\+/g, ' '));
	}

	// Using the function getParameterByName to extract finalurl
	var finalURL = getParameterByName('finalurl')
	console.log(finalURL)

//conditionally add a campaign cookie you wish to add to the url 
var utmcookie = getParameterByName('utm_camp')
var utmcookiedomain = 'campagincookie='+ utmcookie + '; Domain=*.akhil.workers.dev; Max-Age=40000'
console.log(utmcookie)
//issue the redirect 
  return new Response('', {
			status: 302,
			headers: {
            Location: finalURL,
            'Set-Cookie':utmcookiedomain,
      }
		})

}

```
### Final Solution

`https://redirect.akhil.workers.dev?finalurl=<<Enter Final URL for the arctile>>&utm_camp=<<Enter the cookie you want to set>>`


Example Link: https://redirect.akhil.workers.dev?finalurl=https%3A%2F%2Ftimesofindia.indiatimes.com%2Ftrend-tracking%2Fev-startups-crank-up-efforts-as-segments-mood-turns-electric%2Farticleshow%2F70416317.cms&utm_camp=akhilcookie