Using Sulu Forms to create contacts in Hubspot
A requirement in one of our Sulu projects was to send the data of a form to Hubspot CRM. Thankfully, the Sulu FormsBundle comes with a few similar examples (e.g. Mailchimp integration), that made it easy to figure out how to deal with this requirement.
Thankfully, Sulu CMS triggers quite a few event notifications when certain things happen. For our case, we can subscribe to the Sulu\Bundle\FormBundle\Event\FormSavePostEvent
to get notified when form data got saved in the database. It is fine that the data is stored locally as it serves as a "backup" in case the Hubspot API is not working properly.
That means to process the data, we can create a class App\Event\HubspotSubscriber
which implements the Symfony\Component\EventDispatcher\EventSubscriberInterface
interface:
namespace App\Event;
use Sulu\Bundle\FormBundle\Entity\Dynamic;
use Sulu\Bundle\FormBundle\Event\FormSavePostEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class HubspotSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
FormSavePostEvent::NAME => 'addContact',
];
}
public function addContact(FormSavePostEvent $event): void
{
}
}
This is all it takes to get notified by Sulu CMS when form data got saved in the database and then process the form data by sending it to a 3rd party system.
To access the form data from the Sulu\Bundle\FormBundle\Event\FormSavePostEvent
the following steps are needed:
$dynamic = $event->getData();
if (!$dynamic instanceof Dynamic) {
return;
}
$form = $dynamic->getForm()->serializeForLocale($dynamic->getLocale(), $dynamic);
The form fields can be accessed via $form['fields']
. Once you have extracted all the data needed, the data can be
sent to Hubspot. The code snippet below contains a simplified version of our logic so that you can follow along easily:
// the Sulu form data got extracted into the variables below...
$email = '';
$fname = '';
$lname = '';
$contact = new \HubSpot\Client\Crm\Contacts\Model\SimplePublicObjectInput();
$contact->setProperties([
'email' => $email,
'firstname' => $fname,
'lastname' => $lname,
]);
/** @var \HubSpot\Discovery\Discovery $this->api */
$response = $this->api->crm()->contacts()->basicApi()->create($contact);
if ($response instanceof Error) {
throw new ApiException($response->getMessage());
}
Injecting the \HubSpot\Discovery\Discovery
needed a bit of configuration in the services.yaml
file to make Symfony
aware of the dependency and its configuration:
services:
HubSpot\Factory:
class: HubSpot\Factory
HubSpot\Discovery\Discovery:
factory: ['@HubSpot\Factory', createWithAccessToken]
arguments: ['%env(HUBSPOT_API_TOKEN)%']
The Hubspot API token needed for the communication is passed via an environment variable HUBSPOT_API_TOKEN
to the Symfony application and referenced as can be seen above.
The downside of this approach is, that the code triggered for all forms on the Sulu website. In the next blog post of this series, I will show you how this can be fixed.