With this integration, you can connect Attentive to HubSpot Workflows via Attentive APIs so you can send SMS messages to your subscribers from within HubSpot. You can combine email and SMS to send messages at key moments in a user’s journey.
Prerequisites
Ensure that you meet the following requirements in order to set up this integration:
- You must have one of the following editions of HubSpot:
- Marketing Hub Professional, Enterprise
- Sales Hub Professional, Enterprise
- Service Hub Professional, Enterprise
- Operations Hub Professional, Enterprise
Set up Custom Code Action in HubSpot
Complete the following procedure to create a custom code action in HubSpot and connect the Attentive Custom Events API:
- Log in to your HubSpot account.
- Select the relevant workflow on the Automations tab or create a new workflow (from scratch or from a template).
- Add a Custom code action.
The following sample code calls the Attentive Custom Events API, which includes a contact’s phone number, email address, first name, and last name as properties. Adjust as needed.
- Language: Node.js 16x
- Description: "Calls Attentive Custom Events API"
-
Secrets:
- Follow these instructions to get an API key from Attentive.
- Add the Attentive API Key (add secret).
-
Secret name:
AttentiveAPIKey
-
Secret value:
Bearer ENTER_YOUR_API_KEY
Insert the following code snippet:const hubspot = require('@hubspot/api-client');
const axios = require('axios');
exports.main = async (event, callback) => {
// Your Attentive API endpoint
const attentiveApiUrl = 'https://api.attentivemobile.com/v1/events/custom';
// Your Attentive API access token
const attentiveApiToken = '<YOUR_ATTENTIVE_API_TOKEN>';
// Your HubSpot API access token
const hubspotApiToken = '<YOUR_HUBSPOT_API_TOKEN>';
const hubspotClient = new hubspot.Client({
accessToken: hubspotApiToken
});
try {
// Retrieve contact's properties from HubSpot
const contactId = event.object.objectId;
const propertiesToRetrieve = ["phone", "email", "firstname", "lastname"];
const contactResponse = await hubspotClient.crm.contacts.basicApi.getById(contactId, propertiesToRetrieve);
// Extract properties from the response
const phone = contactResponse.properties.phone;
const email = contactResponse.properties.email;
const firstName = contactResponse.properties.firstname;
const lastName = contactResponse.properties.lastname;
// Constructing the request payload for Attentive API
const attentivePayload = {
type: '<YOUR_EVENT_TYPE>',
user: {
phone: phone,
email: email
},
properties: {
firstname: firstName,
lastname: lastName
}
};
// Making the HTTP request to Attentive API
const attentiveResponse = await axios.post(attentiveApiUrl, attentivePayload, {
headers: {
Authorization: `Bearer ${attentiveApiToken}`,
'Content-Type': 'application/json'
}
});
console.log('Attentive API response:', attentiveResponse.data);
} catch (error) {
console.error('Error calling Attentive API:', error);
throw error;
}
};- Replace
<YOUR_ATTENTIVE_API_TOKEN>
,<YOUR_HUBSPOT_API_TOKEN>
, and<YOUR_EVENT_TYPE>
in the code snippet with the correct values. See HubSpot’s documentation to learn how to generate an API token in HubSpot.
- Replace
-
Secret name:
- Test the action at least once with a test subscriber that's already in Attentive and subscribed. You should see a SUCCESS message.
- Save the action.
- Log in to your Attentive account and set up the body of the message in Journeys. For more information about journeys that use custom triggers, see What are custom journey triggers?
Your HubSpot Workflows account is now connected to Attentive.
(Optional) Check subscriber status of contact before making Custom Events API call
If you’d like to check a subscriber’s subscription status in HubSpot workflows before calling the Custom Events API, follow these steps:
-
Before the Custom Events API custom code action, create another custom code action with the following:
- Language: Node.js 16x
- Description: "Checks subscriber status in Attentive (GET Subscriber API)"
-
Secrets: Use the same
AttentiveAPIKey
as above
Insert the following code snippet:const axios = require('axios');
const hubspot = require('@hubspot/api-client');
exports.main = async (event, callback) => {
// Your Attentive API endpoint for checking subscriptions
const attentiveApiUrl = 'https://api.attentivemobile.com/v1/subscriptions';
// Your Attentive API access token
const attentiveApiToken = '<YOUR_ATTENTIVE_API_TOKEN>';
// Your HubSpot API access token
const hubspotApiToken = '<YOUR_HUBSPOT_API_TOKEN>';
const hubspotClient = new hubspot.Client({
accessToken: hubspotApiToken
});
try {
// Retrieve contact's properties from HubSpot
const contactId = event.object.objectId;
const propertiesToRetrieve = ["phone", "email"];
const contactResponse = await hubspotClient.crm.contacts.basicApi.getById(contactId, propertiesToRetrieve);
// Extract properties from the response
const phone = contactResponse.properties.phone;
const email = contactResponse.properties.email;
// Making the HTTP GET request to check if subscriber exists
let attentiveResponse;
try {
attentiveResponse = await axios.get(attentiveApiUrl, {
headers: {
Authorization: `Bearer ${attentiveApiToken}`
},
params: {
phone: phone,
email: email
}
});
} catch (err) {
if (err.response && err.response.status === 404) {
// Subscriber not found, handle as expected behavior
attentiveResponse = { status: 404, data: {} };
} else {
// Other errors, throw as usual
throw err;
}
}
// Extracting subscription status
let marketingEligible = false;
let textEligible = false;
if (attentiveResponse.status === 200) {
const subscriptionEligibilities = attentiveResponse.data.subscriptionEligibilities;
if (Array.isArray(subscriptionEligibilities) && subscriptionEligibilities.length > 0) {
subscriptionEligibilities.forEach(subscriptionEligibility => {
if (subscriptionEligibility.subscription.type === "MARKETING" && subscriptionEligibility.eligibility.isEligible) {
marketingEligible = true;
}
if (subscriptionEligibility.subscription.channel === "TEXT" && subscriptionEligibility.eligibility.isEligible) {
textEligible = true;
}
});
}
}
// Determine if the subscriber is eligible based on conditions
const attentiveEligible = attentiveResponse.status === 200 && marketingEligible && textEligible;
// Return response using callback function
callback({
outputFields: {
Attentive_Response_Status: attentiveResponse.status,
Marketing_Subscriber: marketingEligible,
Text_Subscriber: textEligible,
Attentive_Eligible: attentiveEligible
},
attentiveApiResponse: attentiveResponse.data,
Attentive_Eligible: attentiveEligible
});
} catch (error) {
console.error('Error:', error);
throw error;
}
};- Replace
<YOUR_ATTENTIVE_API_TOKEN>
,<YOUR_HUBSPOT_API_TOKEN>
in the code snippet with the correct values. See HubSpot’s documentation to learn how to generate an API token in HubSpot. -
Data Outputs: Add an Output here that is a Number data type and name it
Attentive_Eligible
- Replace
- Test the action at least once with a test subscriber that is already in Attentive and subscribed. You should see a SUCCESS message.
- Save the action.
- Create a Branch action:
-
Logic: Based on a single action outcome
-
Property:
Attentive_Eligible
- Branch on the value Attentive_Eligible
- Branch 1: Yes
-
Branch 2: Leave this blank (this is for if the subscriber doesn't exist in Attentive)
-
Logic: Based on a single action outcome
-
Save the action.
Move the Custom Events API custom code action under the Yes branch.
Questions?
We’re here to help! Contact our White Glove team (whiteglove@attentivemobile.com) to ask about the Attentive + HubSpot Workflows integration.