export default async function main(args) {
// Map input variables: zendeskAPIKey, zendeskEmail, zendeskDomain, and userEmail
let { zendeskAPIKey, zendeskEmail, zendeskDomain, userEmail } = args.inputVars;
//Check if the user has inputted the required variables
if (!zendeskAPIKey || !zendeskEmail || !zendeskDomain || !userEmail) {
return {
//Returns the error path so we can continue the design
next: { path: 'error' },
//Renders a debug message in Voiceflow
trace: [{ type: "debug", payload: { message: "Missing required input variables for this function" } }]
};
}
// Custom function for base64 encoding
function base64Encode(str) {
const charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
let output = '';
for (let i = 0; i < str.length; i += 3) {
const byte1 = str.charCodeAt(i) & 0xFF;
const byte2 = i + 1 < str.length ? str.charCodeAt(i + 1) & 0xFF : 0;
const byte3 = i + 2 < str.length ? str.charCodeAt(i + 2) & 0xFF : 0;
const enc1 = byte1 >> 2;
const enc2 = ((byte1 & 0x3) << 4) | (byte2 >> 4);
const enc3 = ((byte2 & 0xF) << 2) | (byte3 >> 6);
const enc4 = byte3 & 0x3F;
if (isNaN(byte2)) {
output += charSet.charAt(enc1) + charSet.charAt(enc2) + '==';
} else if (isNaN(byte3)) {
output += charSet.charAt(enc1) + charSet.charAt(enc2) + charSet.charAt(enc3) + '=';
} else {
output += charSet.charAt(enc1) + charSet.charAt(enc2) + charSet.charAt(enc3) + charSet.charAt(enc4);
}
}
return output;
}
// Construct the credentials string and encode it using the custom base64Encode function
const encodedCredentials = base64Encode(`${zendeskEmail}/token:${zendeskAPIKey}`);
// Set up the headers with the encoded credentials
const headers = {
'Content-Type': 'application/json',
'Authorization': `Basic ${encodedCredentials}`
};
// The URL for the API endpoint with the search query
const url = `https://${zendeskDomain}.zendesk.com/api/v2/users/search?query=${userEmail}`;
//This is where we made the fetch request, we use try-catch for error handling
try {
//Make the fetch request
const response = await fetch(url, { method: 'GET', headers: headers });
// Check if the response status is OK (status in the range 200-299)
if (!response.ok) {
// If not OK, throw an error to be caught by the catch block
throw new Error(`HTTP error! status: ${response.status}`);
}
//Map the fetch request response
const responseBody = await response.json; //IMPORTANT: functions uses .json instead of .json() - see documentation for details
//Checks if the fetch request returned a body
if (!responseBody || typeof responseBody !== 'object') {
//If no body was returned, throw an error
throw new Error(`Invalid or missing response body from the API`);
}
//Map a value from the responseBody, we will use this as an output variable
const userID = responseBody.users[0].id; //Users field is an array of objects so use [0] to access the first object
// Create the return objects if this is successfull
return {
//Map our output variables
outputVars: { userID },
//Map the success path so we can continue in our flow
next: { path: 'success' },
};
}
//Catches all the errors we threw and displays the debug message
catch (error) {
return {
//Maps the error path so we can continue in our design
next: { path: 'error' },
//Renders a debug message in Voiceflow with the error
trace: [{ type: "debug", payload: { message: "Error:" + error.message } }]
};
}
}