HubSpot API: Master How to Add New Contact (PHP) 2024!

Share

As a developer or a business owner, sometimes you’re stuck at the point that you need to make things manually though HubSpot has a great deal of automations, it lacks things that you might want to consider!

This article will cover how to add one contact in HubSpot using PHP, and private app. Perhaps in another post, we will discuss more features. I think it’s important to learn this step by step and not jump around. Once you get a sense of this, you can fix this.

If you need assistance with something in HubSpot API, you can always contact me for free to consult.

Adding a single contact with multiple companies

You need to add more then one contact in a form, or you need to have one contact and multiple companies. HubSpot does not support repeaters or multiple companies in the form. Therefore, you can do this using their API and the endpoint they offer to you.

Here is the overview page: https://developers.hubspot.com/docs/api/overview

HubSpot Form does not support repeaters, however, HubSpot API gives you the power to create your own forms (APP or CMS) and add multiple objects at the same time.

Setting Up Your Environment in PHP

Note: you must know PHP (classes, interfaces, methods, loops) and Composer. We do not learn how to make the form itself.

Before we get started, you’ll need to have PHP and Composer installed on your system. Composer is a dependency manager for PHP, which will help us manage our project’s libraries.

  1. Install Composer: If you don’t have Composer installed, download and install it from Composer’s official website.
  2. Create a PHP Project: Navigate to your project directory and run composer init to create a new PHP project. Follow the prompts to set up your project.
  3. Install HubSpot API Client: Run the following command to include the HubSpot API client in your project:
composer require hubspot/api-client

Writing the Code

Our main script will be Contact.php, which will handle creating and updating contacts in HubSpot. Alongside, we’ll have an error handling class to manage any exceptions or issues that arise.

Contact.php

This file is the heart of our project. Let’s break down its components:

Initial Setup
if (!defined('ABSPATH')) {
    exit;
}

Here, we check if ABSPATH is defined. This is a security measure to prevent direct access to the script, a practice often seen in WordPress plugins.

define("HUBSPOT_ACCESS_TOKEN", "YOUR_ACCESS_TOKEN");

Replace "YOUR_ACCESS_TOKEN" with your actual HubSpot API access token. This token is essential for authenticating your API requests. You can also save this in your database, for a better security measure.

HubSpot API Access Token and Secret Key
Importing Required Classes

We need to include several classes from the HubSpot API client library:

use HubSpot\Factory;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectInputForCreate;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Contacts\ApiException;
use HubSpot\Client\Crm\Contacts\Model\Filter;
use HubSpot\Client\Crm\Contacts\Model\FilterGroup;
use HubSpot\Client\Crm\Contacts\Model\PublicObjectSearchRequest;

These imports allow us to interact with HubSpot’s CRM, specifically the contacts part, and handle data models and exceptions.

The Contact Class

if (!defined('ABSPATH')) {
    exit;
}

define("HUBSPOT_ACCESS_TOKEN", "WHATEVER");

//define necessary classes 
use HubSpot\Factory;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectInputForCreate;
use HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectInput;
use HubSpot\Client\Crm\Contacts\ApiException;
use HubSpot\Client\Crm\Contacts\Model\Filter;
use HubSpot\Client\Crm\Contacts\Model\FilterGroup;
use HubSpot\Client\Crm\Contacts\Model\PublicObjectSearchRequest;

class Contact
{
    private $client;
    //client id
    private $id;
    private $contact;
    private $properties = [
        'email' => '',
        'firstname' => '',
        'lastname' => '',
    ];

    public function __construct($client)
    {
        $this->client = $client;
    }

    public function create($properties): bool|null
    {
        $this->properties = $properties;

        if (count($this->properties) <= 0) {
            // throw new ApiException('No Properties', __LINE__);
            new HSErrorHandler('No properties were assigned', __LINE__ . __FILE__, __LINE__);
            return null;
        }
        if (!isset ($this->properties['email']) || empty ($this->properties['email'])) {
            new HSErrorHandler('No email property was defined.', __LINE__ . __FILE__, __LINE__);
            return null;
        }
        if ($this->findByEmail($this->properties['email']) !== null) {
            new HSErrorHandler('Found this email ' . $this->properties['email'], __LINE__ . __FILE__, __LINE__);

            return $this->update();
        }

        $simplePublicObjectInputForCreate = new SimplePublicObjectInputForCreate([
            'properties' => $this->properties,
        ]);

        try {
            $this->contact = $this->client->crm()->contacts()->basicApi()->create($simplePublicObjectInputForCreate);
            $this->id = $this->contact->getId();
            return true;
        } catch (Exception $e) {
            $code = json_encode($this->properties);
            new HSErrorHandler($e->getMessage() . $code, __LINE__ . __FILE__, $e->getCode());
            return null;
        }
    }

    private function update()
    {

        $simplePublicObjectInput = new SimplePublicObjectInput([
            'properties' => $this->properties,
        ]);
        try {
            $this->client->crm()->contacts()->basicApi()->update($this->id, $simplePublicObjectInput);

            return true;
        } catch (Exception $e) {
            new HSErrorHandler($e->getMessage(), __LINE__ . __FILE__, $e->getCode());
            return null;
        }
    }

    public function getContactId(): string
    {
        return $this->id;
    }

    public function findByEmail($email)
    {
        $this->properties['email'] = $email;
        $filter1 = new Filter([
            'property_name' => 'email',
            'operator' => 'EQ',
            'value' => $this->properties['email'],
        ]);
        $filterGroup1 = new FilterGroup([
            'filters' => [$filter1]
        ]);
        $publicObjectSearchRequest = new PublicObjectSearchRequest([
            'limit' => 1,
            'properties' => ['email'],
            'filter_groups' => [$filterGroup1],
        ]);

        try {

            $search = $this->client->crm()->contacts()->searchApi()->doSearch($publicObjectSearchRequest);
            if (!empty ($search->getResults())) {
                $contact = $search->getResults()[0]; // Get the first contact from the results
                $this->id = $contact->getId();
                new HSErrorHandler('Found the email', __LINE__ . __FILE__, __LINE__);

                return $this->id;
            } else {
                return null; // No contacts found
            }

        } catch (ApiException $e) {
            new HSErrorHandler($e->getMessage(), __LINE__ . __FILE__, $e->getCode());
            return null;
        }

    }

}

//create a new client and contact

$client = Factory::createWithAccessToken(HUBSPOT_ACCESS_TOKEN);
$contact = new Contact($client);
$contactProperties = [
    'firstname' => '',
    'lastname' => '',
    'email' => '',
    // more properties...
];

// Create a contact and retrieve the contact ID if needed?
$contact->create($contactProperties);


$contactId = $contact->getContactId();

//if there was an error
if ($contactId === null)
    return;

The Contact class encapsulates all the functionality related to contact management:

Properties:

  • We define several private properties for internal use, including $client for the HubSpot client instance, $id for storing the contact’s ID, and $properties for the contact’s details.
  • private $client;: Holds the HubSpot client instance.
  • private $id;: Stores the ID of the current contact.
  • private $contact;: Stores the contact object.
  • private $properties: An array to hold contact properties like email, firstname, and lastname.
  • __construct($client)Initializes the Contact class with a HubSpot client instance.

create($properties): bool|null

  • Takes an array of contact properties.
  • Validates the presence of essential properties (e.g., email).
  • Checks if a contact with the given email already exists using findByEmail() method. If it exists, it updates the contact using the update() method.
  • If the contact does not exist, it creates a new contact using HubSpot’s API.
  • Returns true on success, null on failure.

  • update() Method
  • Updates the properties of an existing contact using the HubSpot API.
  • Returns true on success, null on failure.

findByEmail() Method

  • Searches for a contact by email.
  • Constructs a filter to search for the email.
  • Uses the HubSpot API to search for the contact.
  • If found, stores the contact ID and returns it. Otherwise, returns null.

Error Handling

The HSErrorHandler class is designed for logging errors that occur during API interactions. It formats and logs error messages for debugging purposes.

if (!defined('ABSPATH')) {
    exit;
}

class HSErrorHandler
{
    private $message;
    private $code;
    private $path;
    public function __construct($message, $path, $code)
    {
        $this->message = $message;
        $this->code = $code;
        $this->path = $path;
        $this->log();
    }

    public function log()
    {
        $logMessage = sprintf("[%s] Error in %s: %s (Code: %s)\n", date('Y-m-d H:i:s'), $this->path, $this->message, $this->code);
        // choose between one of these
        // error_log($logMessage, FILE_APPEND);
        // file_put_contents(HSFORM_PLUGIN_DIR . 'error_log.txt', $logMessage, FILE_APPEND);
    }
}
  • private $message;: Stores the error message.
  • private $code;: Stores the error code.
  • private $path;: Stores the file path where the error occurred.

__construct($message, $path, $code)

  • Initializes the class with the error message, file path, and code.

log()

  • Formats the error message and logs it, either by using error_log() or writing to a file. You’ll need to uncomment one of the logging methods to activate it.

Usage

Finally, the code creates an instance of the Contact class with the HubSpot client and attempts to create a contact with specified properties. If the contact creation or update is successful, it retrieves the contact ID for further use.

$client = Factory::createWithAccessToken(HUBSPOT_ACCESS_TOKEN);
$contact = new Contact($client);
$contactProperties = [
    'firstname' => '',
    'lastname' => '',
    'email' => '',
    // more properties...
];
$contact->create($contactProperties);
$contactId = $contact->getContactId();
if ($contactId === null)
    return;

This snippet initializes the HubSpot client, creates a Contact object, sets the properties for a new contact, and attempts to create or update the contact in HubSpot. If there’s an error (e.g., no contact ID is returned), the script exits early.

This overview explains the functionality and flow of the provided PHP code for integrating with the HubSpot API to manage contacts.

Download Composer here:

Composer