Skip to main content

Using Sulu Forms to create contacts in Hubspot

This blog post might be outdated!
This blog post was published more than one year ago and might be outdated!
· 3 min read
Stephan Hochdörfer
Head of IT Business Operations

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) {

$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();
'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:

class: HubSpot\Factory

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.