Last active
October 13, 2020 05:52
-
-
Save crtag/99176be730b6915c7d584406bb011a16 to your computer and use it in GitHub Desktop.
Hubspot workflow Node JS webhook to create a company record via API call.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// TODO: configure your own hubspot client | |
/** | |
* This webhook is triggered by Hubspot workflow and receives a full Hubspot contact object | |
* to create the company for. It does expect company name property, but will default | |
* company name to contact `${firstname} ${lastname} construct | |
* | |
*/ | |
module.exports = async (req, res) => { | |
if (req.method !== 'POST') return res.sendStatus(405); | |
// You can also check signature of the call (X-HubSpot-Signature header) | |
const payload = req.body; | |
const contactVid = payload.vid; | |
if (!payload['is-contact']) { | |
console.log('Received unexpected object!'); | |
return res.sendStatus(400) | |
}; | |
if (0 == Object.keys(payload.properties || {})) { | |
console.log('Missing contact properties!'); | |
return res.sendStatus(400) | |
}; | |
// can't lazy initialise it as it's async | |
let hubspotClient; | |
try { | |
// TODO: it's up to you how to cinfiugure Hubspot client | |
// this example uses https://github.com/MadKudu/node-hubspot | |
hubspotClient = await hubspot(); | |
} catch (error) { | |
console.log('Failed to create Hubspot API client'); | |
return res.sendStatus(503); | |
} | |
// check if there's an associated company to contact - this would be a conflict | |
try { | |
// 1 - association contact to company from https://developers.hubspot.com/docs/methods/crm-associations/crm-associations-overview | |
console.log(`Test contact associations with a company.`); | |
const associations = await hubspotClient.apiRequest({ | |
path: `/crm-associations/v1/associations/${contactVid}/HUBSPOT_DEFINED/1`, | |
}); | |
if (0 != associations.results.length) { | |
console.log(`Found associations`); | |
console.log(JSON.stringify(associations.results)); | |
console.log(`The contact [${contactVid}] is already associated with a company, nothing to do.`); | |
return res.sendStatus(204); | |
} else { | |
console.log(`No associations, proceed`); | |
} | |
} catch (error) { | |
console.log(`Failed to test contact [${contactVid}] associations with a company. Error stack: ${error}`); | |
return res.sendStatus(500); | |
} | |
const name = (payload.properties.company || {}).value || ''; | |
const firstName = (payload.properties.firstname || {}).value || ''; | |
const lastName = (payload.properties.lastname || {}).value || ''; | |
// constructing company name - falling back to contact name | |
const companyName = name || `${firstName} ${lastName}`; | |
let companyVid; | |
try { | |
console.log(`Creating company via Hubspot API with name [${companyName}]`) | |
const company = await hubspotClient.companies.create({ | |
properties: [ | |
{ | |
name: 'name', | |
value: companyName, | |
} | |
] | |
}); | |
companyVid = company.companyId; | |
if (companyVid) { | |
console.log(`Created company with response:`); | |
console.log(JSON.stringify(company)); | |
} else { | |
console.log(`Failed to create company with response:`); | |
console.log(JSON.stringify(company)); | |
return res.sendStatus(500); | |
} | |
} catch(error) { | |
console.log(`Failed to create company via API call. Error stack: [${error}]`); | |
return res.sendStatus(500); | |
} | |
// associate contact with the company | |
try { | |
console.log(`Associating contact [${contactVid}] with company [${companyVid}] via Hubspot API call`) | |
await hubspotClient.apiRequest({ | |
method: 'PUT', | |
path: `/crm-associations/v1/associations`, | |
body: { | |
fromObjectId: contactVid, | |
toObjectId: companyVid, | |
category: 'HUBSPOT_DEFINED', | |
definitionId: 1 | |
}, | |
}); | |
// above API call returns 204 on success | |
} catch (error) { | |
console.log(`Failed to associate contact [${contactVid}] with company [${companyVid}] via API call. Error stack: [${error}]`); | |
// TODO: this is really bad is it will leave behind unassociated company and contact, need to sort out recovery mechanism | |
return res.sendStatus(500); | |
} | |
return res.sendStatus(204); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment