Updating users in Zendesk via proxy
Requirements
I make use of a Cloudflare Worker account. This is free to create via:
You'll also need a Zendesk API token, your Zendesk subdomain and an admin email.
Creating the worker
Go to the Cloudflare dashboard and click on Workers and Pages > Overview
Click the Create Worker button to create a new, free, worker. Give your worker a useful name like update_user_tags
.
Follow the steps until you reach the successfully deployed screen.
Adding variables
Click Continue to project to setup the worker.
Our worker needs to authenticate to Zendesk.
Navigate to the Settings > Variables and click the Add Variable button.
Add three variables:
subdomain
and add your Zendesk subdomainemail
and add a valid email from a Zendesk Admintoken
and add a Zendesk API token
Press Deploy.
Adding the code
Below you'll find the code for this worker. I annotated it where possible but in essence we do:
- We get the
ID
andtag
we want to set from the URL we're calling - We handle CORS and other security requirements of your browser
- We get the user's
current tags
, since updating a tag would overwrite the existing tags - We add our new
tag
to thecurrent tags
- We update the user to set the
new tags
- We return a 200 OK
Code
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const id = url.searchParams.get('id');
const tag = url.searchParams.get('tag');
//Handle CORS
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, HEAD, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
"content-type": "application/json"
};
if (request.method === "OPTIONS") {
return new Response(null, {
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, HEAD, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
}
})
}
//Check for missing metadata
if (!id || !tag) {
return new Response('Missing id or tag', { headers: corsHeaders, status: 400 });
}
const api_url = `https://${env.subdomain}.zendesk.com/api/v2/users/${id}.json`;
const auth = 'Basic ' + btoa(`${env.email}/token:${env.token}`);
try {
// Fetch the current tags so we don't overwrite them
const getUserResponse = await fetch(api_url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': auth
}
});
//Handle an issue with the tags, eg the user does not exist.
if (!getUserResponse.ok) {
const errorData = await getUserResponse.json();
return new Response(JSON.stringify(errorData), { headers: corsHeaders, status: getUserResponse.status });
}
const userData = await getUserResponse.json();
const currentTags = userData.user.tags;
// Add the new tag to the existing tags
const updatedTags = new Set(currentTags);
updatedTags.add(tag);
const putBody = JSON.stringify({
user: {
tags: Array.from(updatedTags)
}
});
// Update the user's tags
const updateUserResponse = await fetch(api_url, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': auth
},
body: putBody
});
if (updateUserResponse.ok) {
return new Response('200 OK', { headers: corsHeaders, status: 200 });
} else {
const errorData = await updateUserResponse.json();
return new Response(JSON.stringify(errorData), { headers: corsHeaders, status: updateUserResponse.status });
}
} catch (error) {
return new Response(error.message, { headers: corsHeaders, status: 500 });
}
}
};
After deploying your variables in the previous step, click the Edit Code button top right.
You'll be greeted with the editor below. Replace the existing sample code with our Workers code above.
Press Deploy.
Testing
In the right side of the editor we can test our new Worker.
Edit the URL to https://update-user-tags.yourdomain.workers.dev?id=123456789&tag=example
In this URL id
is the ID of the user we want to update, and tag
is the tag we want to add. Note the yourdomain
is whatever domain you picked for your workers instance.
Press send and you should get a 200 OK if all goes well, or an error message if not.
Refresh your user profile in Zendesk and you'll see the tag added.
Help Center
Final step is to combine this with the Help Center.
The code below does the following:
- Get the current user ID
- Check if we're looking at an article with a specific ID
987654321
- Make a call to our worker:
https://update-user-tags.yourdomain.workers.dev?id=123456789&tag=example
with example the tag we want to set for this article.
Code
document.addEventListener('DOMContentLoaded', function () {
// Function to get the current user info using Zendesk API
function getCurrentUser() {
return fetch('/api/v2/users/me.json', {
method: 'GET',
credentials: 'same-origin'
})
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error('Failed to fetch user information');
}
})
.then(data => {
return data.user;
})
.catch(error => {
throw new Error('User not logged in or unable to fetch user data');
});
}
// Function to check if the current URL contains the specific article ID
function checkArticleURL() {
return window.location.href.includes('987654321');
}
// Function to make the API call
function makeAPICall(userId) {
const apiUrl = `https://example.workers.dev?id=${userId}&tag=example`;
fetch(apiUrl, {
method: 'GET'
})
.then(response => {
if (response.ok) {
console.log('API call success');
} else {
console.error('API call failed', response.statusText);
}
})
.catch(error => {
console.error('API call error', error);
});
}
// Main function to check conditions and make API call
function main() {
getCurrentUser()
.then(user => {
if (checkArticleURL()) {
makeAPICall(user.id);
}
})
.catch(error => {
console.error(error);
});
}
// Run the main function
main();
});
Code Editor
I added the code at the bottom of the article_page.hbs
document, wrapped in a <script></script>
tag