Skip to content

Instantly share code, notes, and snippets.

@antishow
Last active October 13, 2020 05:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antishow/ea184211ceff6c5c86925b6d41c529cb to your computer and use it in GitHub Desktop.
Save antishow/ea184211ceff6c5c86925b6d41c529cb to your computer and use it in GitHub Desktop.

WordPress + HubSpot

A Tale of Two Mis-Capitalized Words

Lately we’ve run into some trouble here and there with the Gravity Forms Hubspot Add-On (and/or the Zapier... zap... thing) de-authenticating and losing its connection to the mothership. As a “workaround” we’re being asked to use HubSpot forms instead, but that solution sucks because then we lose all those sweet Gravity Forms styles we worked so hard on during development (not to mention whatever fancy backend stuff we did using filters/actions)

So, I did a little digging and I found that it’s actually super easy to integrate the entire site, forms and all, directly into HubSpot with no Gravity Forms add-on or Zapier integrations. The trick is that you need to install HubSpot’s official plugin: Contact Form Builder for WordPress – Conversion Tools by HubSpot. The title makes it sound like this is something you would use instead of Gravity Forms, but what it actually does is add the Hubspot tracking code to your site and automatically sets up all the session/cookie stuff.

(Additionally, it does provide a list of forms built in HubSpot and an interface to generate shortcodes for them, but that’s not what we’re talking about today)

Setting up the Tracking

There’s pretty much nothing to it. Install and activate the plugin on the WordPress side, then go to HubSpot and log into whatever account you want to connect. Now go back to the plugin settings and click the “Yes, I would like to connect” button. Done! You can now creep on visitors.

Setting up the Form Integration

Getting a baseline integration is actually very easy too! Log into HubSpot and go into the settings, then Marketing > Forms and click on the Non-Hubspot Forms tab. Turn this on. You are done. No, I am not joking.

Getting fancy with it

Form Titles The automatic setup works great for capturing contact data, and you can also still see the submissions on a per-form basis, but the UI isn't exactly the best. It’s important to remember that HubSpot doesn’t really know anything about the forms. Since it doesn't know the form’s title, it just makes one up using the id and class attributes on the form element. By default this is usually something like #gform_3, which kind of sucks. So, I suggest you hook into gform_form_tag and change the id to something a little more verbose. Skeletor already has some code setting a data-formtitle attribute anyway, so that’s a good spot!

add_filter( 'gform_form_tag', function ($form_tag, $form) {
	$form_tag = str_replace(
		'<form',
		sprintf('<form data-formtitle="%s"', $form['title']),
		$form_tag
	);

	$form_id = sprintf(
		'gravity-form-%s-%s',
		$form['id'],
		sanitize_title($form['title'])
	);

	$form_tag = preg_replace(
		"/id='gform_(\d+)'/i",
		"id=\"{$form_id}\"",
		$form_tag
	);

	return $form_tag;
}, 10, 2 );

Posting Directly to a Form This one requires a bit more code, but thankfully HubSpot themselves provide a really good starting point in their docs at https://developers.hubspot.com/docs/methods/forms/submit_form. Let’s clean it up a bit though, first they generate a “HubSpot Context” object which HubSpot uses to connect the form submission, to your ip address, to the tracking cookie. Before you do this, of course you’ll want to turn OFF the tracking of Non-HubSpot forms.

First I’ll write a function to generate the hs_context.

function get_hubspot_context_json($url, $title) {
	$hs_context = [
		'hutk'      => isset_and_true($_COOKIE, 'hubspotutk'),
		'ipAddress' => isset_and_true($_SERVER, 'REMOTE_ADDR'),
		'pageUrl'   => $url,
		'pageName'  => $title
	];

	return json_encode($hs_context);
}

Here’s where we hook into Gravity Forms’ gform_after_submission.

add_filter('gform_after_submission', function($entry, $form) {
	$post_id = $entry['post_id'];
	$url = get_the_permalink($post_id);
	$title = get_the_title($post_id);

	$post_data = [
		'hs_context' => get_hubspot_context_json($url, $title);
	];

	// Ok I'm cutting corners here because I didn't
	// have enough time to write this.
	foreach ($form['fields'] as $field) {
		// iterate over the fields and add each
		// key/value pair to $post_data
	}

	// Assume that we added a new settings
	// field to all forms for the id and a function
	// that gets the value.
	$form_id = get_the_hubspot_id($form);

	send_to_hubspot($post_data, $form_id);
}, 10, 2);

function send_to_hubspot($post_data, $form_id) {
	$portal_id = get_option('leadin_portalId');

	$endpoint = sprintf(
		'https://forms.hubspot.com/uploads/form/v2/%s/%s',
		$portal_id,
		$form_id
	);

	$str_post = http_build_query($post_data);

	$ch = @curl_init();
	@curl_setopt($ch, CURLOPT_POST, true);
	@curl_setopt($ch, CURLOPT_POSTFIELDS, $str_post);
	@curl_setopt($ch, CURLOPT_URL, $endpoint);
	@curl_setopt($ch, CURLOPT_HTTPHEADER, [
		'Content-Type: application/x-www-form-urlencoded'
	]);
	@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	$response    = @curl_exec($ch);
	$status_code = @curl_getinfo($ch, CURLINFO_HTTP_CODE);
	@curl_close($ch);

	return $response;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment