Disclaimer: This is a get-your-hands-dirty type of blog post. It’s long and leverages somewhat technical concepts. However, you don't need to be an engineer to build out this kind of thing. You just need to be comfortable rolling up those sleeves!
Hey there Blue Whale from Bonnaroo hunters! In this very first edition of Automation Growth Hacker (a working title), I’ll show you how to use your lead capture forms to identify anonymous leads in your chat solution. For this blog, we’ll be using lead capture forms from Marketo and Intercom for chat, though you could very likely use a similar approach with forms generated by another marketing automation platform (MAP) in concert with another chat solution.
If your sales development representatives (SDRs) staff Intercom chat, you’re probably familiar with seeing new conversations from the likes of "Indigo Camera from San Jose":
This is Intercom’s way of letting you know you’re talking to an anonymous prospect.
From a customer experience standpoint, it’s great to not force an early-stage prospect to cough up their email before getting basic questions answered. However, for your sales team, it can be really frustrating to not get any credit after spending gobs of time helping someone, only to see the Purple Cows from Albuquerque vanish like Amber Gorillas in The Mist. For SDRs, whose job it is to actively warm up prospects in order to qualify them as opportunities, time is precious. The difference between hitting your goal or not often comes down to making sure you spend your time wisely.
Wouldn’t it be way cooler if you could use the form submissions you're already getting for inquiries, gated content, sign ups, or webinar registrations to help identify your anonymous chats BEFORE they ever start the chat? Like this:
Well, my friends - that's what we're here to do today! Here are the tools we’ll use:
Here’s a high-level architecture of how our solution will work:
For reference, a callback function is a software operation that you queue up to execute after another function runs to completion. In this case, our callback will listen for an event occuring (the prospect filling out our form).
After our callback hears the form submission, we'll use an AJAX request to send data from our form submission to a workflow which recieves that data using a webhook. (Again, this is much simpler than it sounds, and we’ll walk through every step.)
For those not familiar, let’s level-set on a few Intercom concepts/terms:
To clarify, we’re also assuming you’re using Marketo forms. This is important because the "callback" function I’m using is part of Marketo’s JS forms library, MktoForms2.
If you’re not using Marketo forms, you can still do everything we’ll cover here, however, you’ll have to figure out the callback part for your solution. Additionally, while we're loading our callback using Google Tag Manager (GTM), yours might be hard coded or deployed via another tag manager, like Tealium.
.whenReady(callback)fires a callback one time for each form on your page.
.onSuccess(callback)fires a callback after the user submits one of those forms.
Here’s a skeleton of our code with comments explaining the execution logic. Again, don’t let the code scare you off. You can just copy-paste this entire block directly into GTM.
What we’re really doing here is:
To load this into GTM, we need to create a new "HTML" tag and drop in the skeleton:
For testing, in order to simulate being an anonymous Visitor/Lead, use your browser’s private or incognito mode. Since it would be difficult to test using GTM’s "preview" mode, we can instead create a separate trigger. Specifically, we’ll build a trigger that looks for the following query parameter within the URL in order to fire our code: ?test=mkto2int. We’ll enter this string into our trigger configuration in GTM:
In order to update your anonymous Visitors/Leads, you'll need two sets of data:
We’re going to insert both into a payload data object - the actual data that we’ll transmit in this process - which we'll stringify before sending to the Tray Platform (where we’ll automatically parse the payload upon receipt): Code sample here
Try this! To follow every step in this process, add
console.logis a logging/debugging function you can use to inspect different outputs of your code. After adding it to your callback, open your browser's console and submit a test form to see what this object looks like for your forms. Don’t forget to add your testing query parameter (?test=mkto2int) or to remove the
console.log()when you’re done!
The objective here is to get the payload to arrive inside our Tray Platform workflow (which we’ll build shortly) where you can use it to identify your anonymous person.
Since we’ve already packaged everything up into the "payload", we can now pass it over to the Tray Platform using an AJAX call. The inline comments below cover what we’re going to do:
Some additional notes:
Now that you’re set up to send the payload somewhere, you’ll need an automated workflow to "receive" it.
We’ll create a new workflow with a "webhook" trigger, open the workflow settings, copy the "Workflow Public URL", and finish by enabling the workflow:
As you can see from the above animated GIF, we begin our workflow with a webhook trigger. This trigger generates a public URL we can use to connect our workflow with GTM. Copy the Workflow Public URL from the workflow settings menu and paste it over TRAY_WEBHOOK_URL in your GTM tag.
If you created an X-CSRF-Token, swap out YOUR_TOKEN in the tag as well. You can then finish this step by going back to the Tray Platform adding the same token in the "CSRF Token" field found under our webhook trigger’s "advanced settings" menu located at the very bottom right of the panel:
Your code in GTM should look something like this by this point: Code sample here
Assuming you’ve associated your testing trigger to the tag, you can now publish your GTM changes. Let’s test out some form submissions, shall we?
With your callback published and webhook workflow enabled, go to a page on your website while using your test query parameter (for instance, https://tray.io?test=mkto2int).
Fill out a form, then check the "output" of the trigger step in the "debug" panel of your Tray Platform workflow to see what you get:
In my case, I see the payload in the output of my logs has everything I need:
For Visitors, this is the "user_id" attribute on the Intercom Visitor object which can be used to look them up and convert them:
But! Not every person on your site is a Visitor in Intercom’s eyes. Some are already Leads (both anonymous and known) or Users. If you attempted to look up a Visitor by "user_id" using this ID, but they were in fact a Lead/User, Intercom’s visitor API will return a "not found" (404) response, even though Intercom technically returns a visitor ID for them using the aforementioned
The good news is that Intercom uses that same visitor ID as the Lead’s user_id when they're converted to a lead:
With this in mind, here’s how our workflow logic will function:
Let’s break down how this set of operations looks in workflow form. (Don’t worry, we’re almost done!):
Because we’re using some newer Intercom Visitor APIs, we’ll be using our HTTP-based Universal Connector (UC) for the steps leveraging the visitors API. The UC, which is the globe icon on the second step in the above screenshot, can accommodate these newer visitor-related calls. (Part of the beauty of a GAP is that even without pre-built operators, you can use the UC to write HTTP-based connectors to make the connections you need.)
We’ll use the same authentication in our Universal Connector as we're using in our Intercom connectors, we just need to add some headers. After doing this once, you can duplicate the configured UC and retain that same auth setup for the other calls.
This may look complicated, but don’t panic! It really isn’t. As we discussed, our workflow uses a webhook trigger to kick off the process when it receives the signal from GTM that someone has filled out a Marketo form. We then use our Universal Connector (UC) step to ascertain whether this person is a Visitor, as noted in the diagram above.
In the output of the UC’s "Lookup Visitor" step, there's going to be a "response object", which we can think of as the answer to the question: "Is the person who just filled out a form a Visitor in Intercom?" In that object is a "status code" attribute, the answer to that question.
We’ve built the next step in our workflow to pass that response object value to the "Visitor found?" Boolean check to ascertain whether the person is, in fact, a Visitor. We build out our Boolean step to detect a status code equal to 200. If the status code is 200, that means the person is a Visitor, which means the Boolean is considered to be "true". As a result, the process moves down the true path to the "convert to lead" step. However, if the status code didn’t equal 200, we move to the false path.
Let’s look more closely at what happens if the Visitor wasn’t found. In this branch of our workflow, we look up leads in a nearly identical process. The main difference is that we use ".../contacts" rather than ".../visitors":
We use another UC step to "Lookup lead by user_id" and a similar boolean step to check the status code in the response object. If it finds a lead, we use the "Update Lead" operation in our Intercom connector. In this case, we pass the form contents we wish to add to the lead to Intercom:
Now let’s go back a few steps and see what happens if our initial Boolean condition was "true" - that is, if we actually found a Visitor in the first step following the trigger.
First, we convert them to a lead within Intercom:
Within that same Intercom step, further down the right-hand connector configuration panel, we can add a "visitor" object with the user_id as an attribute inside the "raw" body object like this:
Finally, we can update that lead using the ID we got back from the response in the conversion step:
That's pretty much it! All you need to do to finalize this workflow is test it a few times. Once you're feeling good about it all, change your GTM tag to fire on "all pages:"
This blog may have gotten a bit technical, but you should hopefully see how you can use automation to fill in the gaps between your Marketo forms, Intercom chats, and GTM website tags. By stitching together the data, you can identify otherwise anonymous users and help your SDRs know who they are talking with. These are warmed-up leads who have demonstrated clear interest in your company’s products or services, and could become valuable opportunities for your sales team.
One last addition: I recommend going back and watching the example video showing the end result at the top of this post. Notice that little pop-up on the Thank You page after the form submit? That has a link in it to book an SDR meeting mapped to the email used in the form. We call this "Insta-book," and it’s already started to bring in meetings to our eager SDR team.
Follow this blog because the next edition of Automation Growth Hacker might just be an in-depth post explaining how to build Insta-book for your Thank You pages. After all, your next big sales deal could be that Neon Ninja Turtle from New York City ;) And if you’d prefer not to wait, you can see specific examples of how a GAP can help you connect the data dots among your revenue apps by joining a weekly demo.