export default async function main(args) {
// Validate input variables from args - find the "validateInputs" function below
const invalidFieldTrace = validateInputs(args)
if (invalidFieldTrace) return invalidFieldTrace;
// Extract input variables from args (destructuring)
const {
userEmail,
hubspotApiToken,
} = args.inputVars;
/**
* Build the payload for batch reading contacts in HubSpot
*
* Check HubSpot documentation to learn what properties are available
*
* - https://developers.hubspot.com/docs/api/crm/contacts
*/
const payload = {
"properties": [
"email",
"firstname",
"lastname",
"lifecyclestage",
],
"idProperty": "email",
"inputs": [
{
"id": userEmail
}
]
}
/**
* Define the URL for HubSpot REST operations
*/
const endpointUrl = `https://api.hubapi.com/crm/v3/objects/contacts/batch/read`;
/**
* Configure the fetch request
*
* Get your HubSpot API Token from the settings in Integration > Private apps
*
* https://developers.hubspot.com/docs/api/private-apps
*/
const config = {
method: 'POST',
headers: {
'Authorization': `Bearer ${hubspotApiToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
};
try {
// Make the API call
const response = await fetch(endpointUrl, config);
// Check if the response status is OK
if (!response.ok) {
throw new Error(`HTTP status code ${response.status}`);
}
// Extract the JSON body from the response
const responseBody = response.json;
// Validate the responseBody structure as expected
if (!responseBody || typeof responseBody !== 'object') {
throw new Error("Invalid or missing response body");
}
// Extract data from the response
const exist = !!responseBody.results.length
const contact = exist ? responseBody.results[0] : null;
const contactFirstName = contact?.properties?.firstname
const contactId = contact?.id
// Create the success return trace with extracted data
return {
outputVars: {
contact: JSON.stringify(contact),
contactFirstName,
contactId,
exist,
},
next: {
path: 'success'
},
trace: [
{
type: "debug",
payload: {
message: 'HubSpot API call successful'
}
},
{
type: "debug",
payload: {
message: `Contact exist: ${exist}`
}
},
{
type: "debug",
payload: {
message: JSON.stringify(contact)
}
},
]
};
} catch (error) {
return {
next: {
path: 'error'
},
trace: [{
type: "debug",
payload: {
message: `HubSpot API call error: ${error.message}`
}
}]
};
}
/**
* Here we validate all the inputs of the Voiceflow function
*
* The function can be used in the first lines of the code
* because of a Javascript concept called hoisting
*
* Read more: https://developer.mozilla.org/en-US/docs/Glossary/Hoisting
*/
function validateInputs(args) {
// Extract input variables from args (destructuring)
const {
userEmail,
hubspotApiToken,
} = args.inputVars;
// Validate that userEmail variable is provided
if (!userEmail) {
return {
next: { path: 'error' },
trace: [{ type: "debug", payload: { message: "Missing required input variable: userEmail" } }]
};
}
// Validate that hubspotApiToken variable is provided
if (!hubspotApiToken) {
return {
next: { path: 'error' },
trace: [{ type: "debug", payload: { message: "Missing required input variable: hubspotApiToken" } }]
};
}
return null
}
}