# Send data from TYPO3 Form to Hubspot Form ## 1. Create hubspotFinisher: #### 1.1 Add `HubspotFinisher.php` - `RouteToExtension/Classes/Domain/Finishers/HubspotFinisher.php` ```php <?php namespace YourDomain\Finishers; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher; class HubspotFinisher extends AbstractFinisher { } ``` #### 1.2 Add `HubspotFinisher.yaml` - `RouteToExtension/Configuration/Yaml/Form/Finisher/HubspotFinisher.yaml` ```yaml TYPO3: CMS: Form: prototypes: standard: finishersDefinition: Hubspot: formEditor: iconIdentifier: 't3-form-icon-finisher' predefinedDefaults: options: removeAfter: '0' implementationClassName: 'YourDomain\Finishers\HubspotFinisher' options: ``` ## 2. Know Hubspot rules https://legacydocs.hubspot.com/docs/methods/forms/submit_form_v3_authentication ```json { "submittedAt": "1517927174000", // This millisecond timestamp is optional. Update the value from "1517927174000" to avoid an INVALID_TIMESTAMP error. "fields": [ { "objectTypeId": "0-1", "name": "email", "value": "example@example.com" }, { "objectTypeId": "0-1", "name": "firstname", "value": "Jeff" } ], "context": { "hutk": ":hutk", // include this parameter and set it to the hubspotutk cookie value to enable cookie tracking on your submission "pageUri": "www.example.com/page", "pageName": "Example page" }, "legalConsentOptions": { "consent": { // Include this object when GDPR options are enabled "consentToProcess": true, "text": "I agree to allow Example Company to store and process my personal data.", "communications": [ { "value": true, "subscriptionTypeId": 999, "text": "I agree to receive marketing communications from Example Company." } ] } } } ``` ## 3. Collect TYPO3 form data and put it into Hubspot data ```php $formvalues = $this->finisherContext->getFormValues(); $definition = $this->finisherContext->getFormRuntime()->getFormDefinition()->getElements(); $HubspotFormId = $this->parseOption('HubspotFormId'); ``` ```php $hubspotData = []; $hubspotNamesList = ['firstname','lastname','email','company','jobtitle','phone','country',...]; # this step collects data from TYPO3 form and put it into hubspotData array foreach ($definition as $element) { if (empty($element->getProperties()['hubspotName'])) { $logger->warning('Element ' . $element->getIdentifier() . ' in form '. $this->finisherContext- >getFormRuntime()->getIdentifier() . ' has no Hubspot field name set. This might cause API Errors or data loss.'); } if (in_array($element->getProperties()['hubspotName'],$hubspotNamesList)) { // The array $hubspotData contains the info that we will send to Hubspot // the index in the array are the names of the properties in the form // for example: $hubspotData['email'] has the value ...@pagemachine.de $hubspotData[$element->getProperties()['hubspotName']] = $values[$element->getIdentifier()]; } } ``` ## 4. Process Hubspot data: - Turn `$hubspotData` into `$requestBody` ```php $requestBody = [ 'fields' => [], ]; $field = []; foreach ($hubspotData as $field_key=>$field_value) { $field['objectTypeId'] = '0-1'; $field['name'] = $field_key; $field['value'] = $field_value; array_push($requestBody['fields'], $field); } ``` - Turn `$requestBody` into **json** `$encodedBody` ```php $encodedBody=json_encode($requestBody); ``` ## 5. Send processed Hubspot data via `https` request ```php # get $authToken $portalId and $formId $authToken=$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['f7forms']['hubspot_OAuth_token']; $portalId=$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['f7forms']['hubspot_portalId']; $formId=$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['f7forms']['hubspot_formId']; # create request $requestFactory=GeneralUtility::makeInstance(RequestFactory::class); $authorization = 'Bearer ' . $authToken; $url = 'https://api.hsforms.com/submissions/v3/integration/secure/submit/'; $url = $url . $portalId . '/' . $formId; # send request $response=$requestFactory->request($url,'POST',['headers' =>['Content-Type'=>'application/json', 'Authorization'=>$authorization], 'body'=>$encodedBody]); # check response if($response->getStatusCode()===200){ return $response->getBody()->getContents(); } if($response->getStatusCode()===602){ return false; } ```