Hubspot is gaining popularity as a lean, cloud-based CRM and marketing automation platform, and new features are being developed continuously. When it is not sufficient out-of-the-box, one resorts to custom code. In this article, we present a simple custom code solution that allows you to create tasks with a due date based on other date entries (for example, the start date of a deal).
Unfortunately, this is not possible in the standard interface; you can only set the "Days from task creation" option:
The Problem
Our subsidiary, Lean Hive, offers personnel and freelancer placement. Good support for applicants and clients is crucial in the placement process. We represent each personnel placement in Hubspot as aDeal. Each deal has aStart Date, which is filled with the date of the start of work for the placed person.
To ensure a smooth project start and good follow-up, the business development consultants from Lean Hive additionally make contact at defined intervals:
- 1 month and 3 days before the project start, a call is made with the candidate to clarify any questions and prepare for a good project start.
- On the day of the project start, another call is made, also with the client-side support.
- 8 days after the project start, a call is made to check how well the project start is going.
- 1 month after the project start, the candidate is invited to a lunch where an exchange of experiences and a feedback round takes place.
Once a deal moves into theClosed Won stage, the corresponding tasks for the mentioned calls/meetings should be created.
The Solution
What is not possible via the GUI can be easily accomplished with custom code. First, we need to create our Hubspot API key as a secret and select it for the workflow step:
Then we need to define 2 properties. These will be passed from the workflow to the custom code:
- We use the hubspot_owner_id, which is the ID of the deal owner, as the task owner. Thus, the task is also assigned to the deal owner.
- We use the start_date as a reference point for our date calculations.
Now we can write the code. First, we write a function called createTask that creates a task in Hubspot:
const hubspot = require('@hubspot/api-client');\n\nconst createTask = async (hubspotClient, taskBodyObject) => { \n const url = `/engagements/v1/engagements`;\n hubspotClient.apiRequest({\n path: url,\n method: 'POST',\n body: taskBodyObject,\n json: true\n });\n}; Then we write another helper function that can perform the date calculations. It expects a timestamp (in Hubspot, date entries are stored as timestamps) and adds a number of days to this timestamp. To subtract days, i.e., to create a date that is before the given timestamp, you simply pass a negative number indays.
// Adds "days" days to the timestamp "ts" and returns the new timestamp\nconst addDaysToTimeStamp = (ts, days) => {\n let ret = new Date(ts);\n ret.setDate(ret.getDate() + days);\n return ret.getTime();\n} Then we write one last helper function that provides the body for the task to be created:
const buildDealTaskObject = (taskOwner, timestamp, dealId, subject) => {\n return {\n engagement: {\n active: true,\n type: 'TASK',\n ownerId: taskOwner,\n timestamp: timestamp\n },\n associations: {\n dealIds: [dealId],\n },\n metadata: {\n body: subject,\n subject: subject,\n status: "NOT_STARTED",\n forObjectType: "DEAL"\n }\n };\n} In the main method, we can now create new tasks very simply as follows:
exports.main = async (event, callback) => {\n const hubspotClient = new hubspot.Client({\n apiKey: process.env.HAPIKEY\n });\n\n const taskOwner = parseInt(event.inputFields['hubspot_owner_id']);\n const projectStart = parseInt(event.inputFields['start_date']);\n const dealId = event.object.objectId;\n \n const tasksToCreate = [\n buildDealTaskObject(taskOwner, projectStart, dealId, "Task at Project Start"),\n buildDealTaskObject(taskOwner, addDaysToTimeStamp(projectStart, -5), dealId, "Task 5 Days Before Project Start"),\n buildDealTaskObject(taskOwner, addDaysToTimeStamp(projectStart, 5), dealId, "Task 5 Days After Project Start"),\n ];\n\n tasksToCreate.forEach(task => createTask(hubspotClient, task));\n} Conclusion
Custom code solutions should be the last resort. If something can be solved configuratively, it should generally be solved configuratively. In fact, this problem could also be solved configuratively. For that, you would need 2 additional workflows and 1 dynamic list PER TASK. In our opinion, this is too confusing and difficult to maintain. If parameters change, potentially three configured objects need to be modified. Therefore, we prefer the custom code solution in this exceptional case.
Here again isthe entire code on Github.
Hubspot Automation, Development & Consulting
We offer support on the topic of Hubspot in companies - from training to workshops to consulting and project support. If interested, just reach out via social media or athello@lean-coders.at