What is a workflow?
A workflow is an automated sequence of actions triggered by specific criteria or events in HubSpot. It can help companies streamline repetitive tasks and processes such as lead generation, email marketing and customer follow-up. Workflows in HubSpot are customizable to meet the specific needs of each business and can include various actions such as sending emails, assigning tasks, updating contact properties and creating transactions or tickets. With HubSpot workflows, companies can save time while providing a more personalized and efficient experience for their customers. They can also increase productivity, increase revenue and improve customer satisfaction. Workflows are a powerful tool with multiple functionalities, some of which are still unknown. In fact, it is possible to exploit them even better thanks to the use of "Custom code" to perform personalized actions. (Available to Operations Hub Pro users)
In this article, you will learn how to create a contact from a text property containing an email and associate it with a deal. This is a rather technical maneuver that is not accessible to everyone, as it requires a bit of code play, but even without being a developer, you will be able to simply copy the code you find in this article.
1. Create a Private App
Navigate to "Settings/Account Setup/Integrations/Private Apps/Create a private app", and assign "Read/Write" permissions for "crm.objects.contacts" and "crm.objects.deals". Once you have created your "App", don't forget to write down your Token. For more information on how to create a "Private App", see the HubSpot documentation.
2. Create a workflow
Now create a workflow that will look for deals that do not have an associated contact, in addition to having an email in the required property.
As an action, we will use "Custom code". In the code panel, place your "API token" collected earlier.
3. Integrating the code
For the code part, let's start by finding the deal. It will be useful to use the properties in the next queries:
const ApiResponse = await hubspotClient.crm.deals.basicApi.getById(event.object.objectId, ["customer_email","num_associated_contacts"]);
dealId = ApiResponse.id;
Now, do a search in the Contact API to see if the contact already exists. If it exists, simply take its ID, if not, we can create it as follows:
if(ApiContactResponse.total == 1){
currentContact = ApiContactResponse.results[0];
toObjectId = currentContact.id;
}else{
const properties = {
"email": ApiResponse.properties.customer_email,
};
const SimplePublicObjectInput = { properties };
const ApiCreateContactResponse = await hubspotClient.crm.contacts.basicApi.create(SimplePublicObjectInput);
toObjectId = ApiCreateContactResponse.id;
}
All that remains is to make the association between the contact and the deal. And that's it!
const toObjectType = "contact";
const AssociationSpec = [
{
"associationCategory": "HUBSPOT_DEFINED",
"associationTypeId": 3
}
];
const ApiAssociationResponse = await
hubspotClient.crm.deals.associationsApi.create(dealId, toObjectType, toObjectId, AssociationSpec);
Here is the complete code that you can simply add to your workflow. In the code panel, you can choose a deal to test the code before activating the workflow to make sure everything works properly.
const hubspot = require('@hubspot/api-client');
exports.main = async (event, callback) => {
const hubspotClient = new hubspot.Client({
accessToken: process.env.apikey
});
let currentContact;
let toObjectId;
let dealId;
try {
const ApiResponse = await hubspotClient.crm.deals.basicApi.getById(event.object.objectId, ["customer_email","num_associated_contacts"]);
if(ApiResponse.properties.customer_email &&
ApiResponse.properties.num_associated_contacts == 0){
dealId = ApiResponse.id;
const PublicObjectSearchRequest = { filterGroups: [{"filters
[{"value":ApiResponse.properties.customer_email,"propertyName":"email","o
erator":"EQ"}]}], properties: ["email"], limit: 1 };
const ApiContactResponse = await
hubspotClient.crm.contacts.searchApi.doSearch(PublicObjectSearchRequest);
if(ApiContactResponse.total == 1){
currentContact = ApiContactResponse.results[0];
toObjectId = currentContact.id;
}else{
const properties = {
"email": ApiResponse.properties.customer_email,
};
const SimplePublicObjectInput = { properties };
const ApiCreateContactResponse = await
hubspotClient.crm.contacts.basicApi.create(SimplePublicObjectInput);
toObjectId = ApiCreateContactResponse.id;
}
const toObjectType = "contact";
const AssociationSpec = [
{
"associationCategory": "HUBSPOT_DEFINED",
"associationTypeId": 3
}
];
const ApiAssociationResponse = await hubspotClient.crm.deals.associationsApi.create(dealId, toObjectType, toObjectId, AssociationSpec);
}
} catch (err) {
console.error(err);
throw err;
}
}
In conclusion, "Custom Coded Workflows" can help you do actions that you would have thought impossible in HubSpot with a traditional workflow. The possibilities are endless: renewing a subscription, adding a sequential invoice number to a deal, linking different objects, complex calculated properties, list of recommendations for a newsletter based on a contact's visit history, and more.
If you want to move forward with optimizing your workflows, but don't have the knowledge or resources, feel free to contact one of our Globalia experts to add custom operations to your HubSpot account.