matelso & HubSpot

Integrationen Others

In this article, we describe the challenges that arise when combining Integrations 2.0 and HubSpot and how we can solve them.

HubSpot offers an API. Through this interface, records can be searched, created, modified and deleted.

For a call tracking integration, we are interested in deals and contacts in HubSpot. The first integration we build sends directly to HubSpot and creates a deal for each call. The second integration sends to a PHP script which then searches for a contact in HubSpot and then creates a deal for this contact.

ATTENTION: As of 30.11.2022, the HubSpot API no longer accepts API keys. Authentication is currently only possible via private app access token or OAuth. Matelso supports authentication via OAuth, but the following article still refers to the old method. An alternative is also to connect HubSpot via a third-party provider such as Zapier. We have shown a use case for this in our webinar.

HubSpot direct connection

The direct connection to HubSpot generates a deal for each call to a call tracking number. This variant does not require an additional script and can be set up in the control panel.

Setup in the CP

First we navigate to "Configuration"->"Integrations 2.0".



Then we create a custom push via the pre-selection button.



Then we assign a name and the time of the push.



In diesem Beispiel heißt der Push "HubSpot-Direct" und als Zeitpunkt wird "POST CALL" genutzt. Hier können auch Filter gesetzt werden, in diesem Beispiel nutzen wir das nicht.

Im nächsten Schritt tragen wir den Endpunkt der HubSpot API in den Bereich "Wohin?". Um einen Deal anzulegen nutzen wir den Endpunkt "https://api.hubapi.com/crm/v3/objects/deals".



No HTTP Basic authentication is used and the error handling is left at the default.

The last area we need to fill in is the "What?" area. Here we first set the HTTP method to "POST". In addition, we set an HTTP header "Content-Type".




Since the authentication of the HubSpot API works via API key, we have to set the API key as GET parameter.




In the last configuration step, we fill the POST body of the request with a JSON object defined in the HubSpot API.




This object contains a property with the name "properties". There are 4 properties in this "properties" object.

Line 3 "amount": The amount/value of the deal. Here we set 1 statically, since we cannot know this value yet.

Line 4 "dealname": Here we set the name of the deal that will be created in HubSpot. In our example, the name starts with "New call from " and is followed by the DDD key for the caller number. ex. "New call from +4971196589120".

Line 5 "dealstage": Here we define the phase of the deal. In our example we set the deal to "appointmentscheduled".

Line 6 "pipeline": Defines in which deal pipeline the deal is created.

HubSpot via PHP-Script

In this configuration, the push is sent to a PHP script. This script searches HubSpot for a contact with the caller number and creates this contact if it does not exist. Afterwards, a note with the call information is saved to this contact.

PHP Script

A PHP script is required to map the logic of the contact search/contact creation. This script must be installed as a .php file on a web server with PHP module.

This script must be saved as a .php file on a web server with PHP module.

<?php

/* ----- config starts here ----- */
define("WEB_PASSWORD", "SICHERES_PASSWORT");
define("DEBUG_LOG", true);
define("HUBSPOT_API_KEY", "0ab12c34-****-****-****-************");

/* ----- check access password ----- */
if(WEB_PASSWORD != $_GET["webPasswd"]) {
return;
}

/* ----- read values from request ----- */
$aNumber = $_GET["aNumber"];

/* ----- code starts here ----- */
// log a message to the output if DEBUG_LOG is set to true
function logDebug($msg) {
if (DEBUG_LOG == true) {
echo $msg . '<br/>';
}
}
// finds a contact in hubspot by the given phone number
function findContactByNumber($number) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.hubapi.com/crm/v3/objects/contacts/search?hapikey=" . HUBSPOT_API_KEY,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{ \"filterGroups\": [ { \"filters\": [ { \"value\": \"" . $number . "\", \"propertyName\": \"phone\", \"operator\": \"EQ\" } ] } ], \"properties\": [ \"id\", \"phone\" ], \"limit\": 100 }",
CURLOPT_HTTPHEADER => array(
"accept: application/json",
"content-type: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
return null;
} else {
return $response;
}
}
// create a new contact in hubspot with the given phone number and and email address based on the phone number
function createContact($number) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.hubapi.com/crm/v3/objects/contacts?hapikey=" . HUBSPOT_API_KEY,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{ \"properties\": { \"email\": \"" . $number . "@call.from.calltracking.de\", \"phone\": \"" . $number . "\" } }",
CURLOPT_HTTPHEADER => array(
"accept: application/json",
"content-type: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
return null;
} else {
return $response;
}
}
// create notice in hubspot
function createNotice($text, $contactId) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.hubapi.com/engagements/v1/engagements?hapikey=" . HUBSPOT_API_KEY,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{ \"engagement\": { \"active\": true, \"ownerId\": 1, \"type\": \"NOTE\", \"timestamp\": " . time() . "000 }, \"associations\": { \"contactIds\": [ " . $contactId . "], \"companyIds\": [ ], \"dealIds\": [ ], \"ownerIds\": [ ], \"ticketIds\":[ ] }, \"attachments\": [ ], \"metadata\": { \"body\": \"". $text . "\" } }",
CURLOPT_HTTPHEADER => array(
"accept: application/json",
"content-type: application/json"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
return null;
} else {
return $response;
}
}
// utility method for createContact and returns the id of the newly created contact
function createContactGetId($number) {
$createRes = createContact($number);
if($createRes == null) {
return -1;
}
$hsJson = json_decode($createRes, true);
return $hsJson['id'];
}

// try to find contact by number
$contactRes = findContactByNumber($aNumber);
if($contactRes == null) {
// empty result from find. Create new contact
$hsContactId = createContactGetId($aNumber);
logDebug('No search result. Create contact ' . $hsContactId);
} else {
// deserialize the hubspot response
$hsJson = json_decode($contactRes, true);
// check whether the resultset contains entries
if(count($hsJson['results']) > 0) {
// get the id from the first search result
$hsContactId = $hsJson['results'][0]['id'];
logDebug('Found contact ' . $hsContactId);
} else {
// no search result found. create new contact
$hsContactId = createContactGetId($aNumber);
logDebug('Create contact ' . $hsContactId);
}
}

// check if hsContactId is an integer
if (!is_int(intval($hsContactId))) {
logDebug("error finding or creating contact");
return;
}

// TODO: create notice with contact
createNotice("Ein Anruf von " . $aNumber, $hsContactId);
logDebug("Notiz angelegt");

?>

The script is divided into 4 blocks. Each of these blocks begins with a line that starts with /* and ends with */.

Block 1 (Zeile 3):

Beginnt mit: /* ----- config starts here ----- */
Enthält: In diesem Block werden Konfigurationswerte gesetzt. Hier muss
man auch als Leser dieses Artikel aktiv werden.
Was tun?: Das WEB_PASSWORD und der HUBSPOT_API_KEY müssen vom Verwender gesetzt werden. Im ersten Abschnitt zur direkten Integration ist ein Link wie man einen HUBSPOT_API_KEY erzeugen kann.
Wenn DEBUG_LOG auf true gesetzt wird, werden Informationen in die Ausgabe/Rückgabe des Script geschrieben. Diese können dann auch in den Push Logs gesehen werden.

Block 2 (Zeile 8):

Beginnt mit: /* ----- check access password ----- */
Enthält: In diesem Abschnitt wird überprüft ob die Anfrage das korrekte WEB_PASSWORD enthält. Wenn dies nicht der Fall ist, wird die Anfrage an dieser Stelle beendet.
Durch diesen Abschnitt wird verhindert das Anfragen an das PHP Script von externen etwas in HubSpot verändern.

Block 3 (Zeile 13):

Beginnt mit: /* ----- read values from request ----- */
Enthält: In diesem Abschnitt werden die Anfrageparameter in Variablen extrahiert.

Block 4 (Zeile 16):

Beginnt mit: /* ----- code starts here ----- */
Enthält: Hilfsfunktionen und die eigentliche Logik welche ausgeführt wird.
Setup push in matelso control panel

We navigate to "Configuration"->"Integrations 2.0" and then click on "Custom Push" to create a push.




In the next step, we assign a name and select the time. In this case, we also do not use a filter.




Im Screenshot heißt der Push "HubSpot-PHP" und als Zeitpunkt ist "POST CALL" ausgewählt.

Im nächsten Schritt konfigurieren wir das "Wohin?". Hierzu brauchen wir die URL und den Namen der PHP-Datei im Webspace. In diesem Beispiel heißt die Datei "matelso-push.php" und liegt unter "https://scripts.matelso.com/matelso-push.php".



Now we only have to configure the "What? For this example script, 2 GET parameters must be transferred ("aNumber" & "webPasswd").


The DDD key "" is used for aNumber.