How can we help? 👋

Conversion snippet in 3rd party forms

How to add the conversion snippet to 3d party forms like Pipedrive, Calendly & Wordpress.

👋
So you use a third-party form and you’re unable to add any sort of snippet to that form. How do we then add that snippet?
 
 

REACT

1. Formik

If you’re using React, then you might wanna use a custom form builder like Formik for example.

Notion image

In order to install Formik to your React project, simply run the following on your Node.js terminal:

npm i formik
 

Then, insert the following code below to your React project:

Sample Form Code #1

import React from "react";
import ReactDOM from "react-dom";
import { Formik, Field, Form } from "formik";

function App() {
});
  return (
    <div className="App">
      <h1>Contact Us</h1>
      <Formik
        initialValues={{ name: "", email: "" }}
        onSubmit={async (values) => {
          await new Promise((resolve) => setTimeout(resolve, 500));
          alert(JSON.stringify(values, null, 2));
        }}
      >
        <Form>
          <Field name="name" type="text" />
          <Field name="email" type="email" />
          <button type="submit">Submit</button>
        </Form>
      </Formik>
    </div>
  );
}

export default App;
ReactDOM.render(<App />, document.getElementById("root"));

Sample Form Code #2

import logo from './logo.svg';
import './App.css';
import ReactDOM from "react-dom";
import { Formik, Field, Form } from "formik";
import TagManager from 'react-gtm-module'
import React, { Component } from 'react';
export default class FormDataComponent extends Component {
    render() {
        return (
            <div className="container">
                <form onSubmit={this.onSubmit}>
                    <div className="form-group">
                        <label>Name</label>
                        <input type="text" className="form-control" value={this.state.name} onChange={this.onChangeName} />
                    </div>
                    <div className="form-group">
                        <label>Email</label>
                        <input type="email" className="form-control" value={this.state.email} onChange={this.onChangeEmail} />
                    </div>
                    <div className="form-group">
                        <label>Phone</label>
                        <input type="tel" className="form-control" value={this.state.phone} onChange={this.onChangePhone} />
                    </div>
                    <button type="submit" className="btn btn-primary btn-block">Submit</button>
                </form>
            </div>
        )
    }
}

PIPEDRIVE

Pipedrive uses iframe to embed its form within your website.

What does this mean?

It means your form is not hosted within your own domain hence the data is only stored in their server instead of ours.

This is where the problem starts.

Notion image
PIPEDRIVE DOESN’T ALLOW CROSS-ORIGIN

Pipedrive implements a strict cross-origin policy which doesn’t allow any sort of data exchange happening between different domains. This means it will always have to be same-origin every time.

This means if we’re attempting to store any data from their iframe that is actually hosted in Pipedrive.com domain, that tracking script will never be initiated because ourdomain.com is not the same as Pipedrive’s.

 

Hence, we created this custom form that you can use to still send your form submission data to Pipedrive and while at the same time, installing our conversion snippet to track that form submission if it’s coming from our Partners.

 

1. Build a Custom Form

Copy this HTML code below:

<form class ="form" onsubmit="return false;">
<input class="form-control" id="firstname_create" name="firstname" placeholder="First Name" required type="text" value="">
<input class="form-control" id="lastname_create" name="lastname" placeholder="Last Name" required type="text" value="">
<input class="form-control" id="username_create" name="username" placeholder="Username" required type="text" value="">
<input class="input form-control" id="email_create" name="email" placeholder="Email" required type="email" value="">
<input class="form-control" id="pwd_create" name="phone" placeholder="phone" required type="phone" value="">
<input type="submit" name="register" id = "myBtn" class="button">
</form>

The form is then going to look like this:

Notion image

To beautify the form, create a style.css:

body {
  background: #59abe3;
  margin: 0;
}
.form {
  width: 340px;
  height: 440px;
  background: #e6e6e6;
  border-radius: 8px;
  box-shadow: 0 0 40px -10px #000;
  margin: calc(50vh - 220px) auto;
  padding: 20px 30px;
  max-width: calc(100vw - 40px);
  box-sizing: border-box;
  font-family: "Montserrat", sans-serif;
  position: relative;
}
h2 {
  margin: 10px 0;
  padding-bottom: 10px;
  width: 180px;
  color: #78788c;
  border-bottom: 3px solid #78788c;
}
input {
  width: 100%;
  padding: 10px;
  box-sizing: border-box;
  background: none;
  outline: none;
  resize: none;
  border: 0;
  font-family: "Montserrat", sans-serif;
  transition: all 0.3s;
  border-bottom: 2px solid #bebed2;
}
input:focus {
  border-bottom: 2px solid #78788c;
}
p:before {
  content: attr(type);
  display: block;
  margin: 28px 0 0;
  font-size: 14px;
  color: #5a5a5a;
}
button {
  float: right;
  padding: 8px 12px;
  margin: 8px 0 0;
  font-family: "Montserrat", sans-serif;
  border: 2px solid #78788c;
  background: 0;
  color: #5a5a6e;
  cursor: pointer;
  transition: all 0.3s;
}
button:hover {
  background: #78788c;
  color: #fff;
}
div {
  content: "Hi";
  position: absolute;
  bottom: -15px;
  right: -20px;
  background: #50505a;
  color: #fff;
  width: 320px;
  padding: 16px 4px 16px 0;
  border-radius: 6px;
  font-size: 13px;
  box-shadow: 10px 10px 40px -14px #000;
}
span {
  margin: 0 5px 0 15px;
}

Then link this style.css to your HTML code:

<link rel="stylesheet" href="styles.css">

Your form is then going to look something like this:

Notion image

2. Send Form Data to Pipedrive

Now the next step is you will need to add the following code in order to send your form data upon submission.

1: Add an event listener

To do that, first add an event listener that will listen to your Submit clicks.

     // Assigning event listeners to the button
    let btn = document.getElementById("myBtn");
    btn.addEventListener('click', event => { 
     // function goes here
    });

Then within that event listener, we’ll then add a function. Let’s call that function runReditusFunction ()

 // Assigning event listeners to the button
    let btn = document.getElementById("myBtn");
    btn.addEventListener('click', event => { 
				runReditusFunction()
    });

    function runReditusFunction(){
      if (emailExist()) {
        sendDatatoPipedrive();
        sendDatatoReditus();
      }
    }

    function emailExist(){
        var email_var = document.getElementsByName("email")[0].value;
        return email_var;
    }
     
    function sendDatatoPipedrive(){
      $.ajax({
        type: "POST",
        url: "https://(YOURDOMAINHERE).pipedrive.com/v1/persons?api_token=YOUR_TOKEN_HERE",
        dataType: 'json',
        data: {
          email: emailExist()
  }})}
 

Add a listener that will listen to our Button clicks by creating a Trigger.

Notion image
 

Add a listener that will listen to your email input within the form. This can be done by adding a Variable within GTM.

Notion image
 

2: Establish communication with Pipedrive API

There are 5 steps involved in order to ensure your data appears on:

a) Pipedrive > Persons/Contacts

b) Pipedrive > Leads Inbox

Notion image

STEP 1

Add this XMLHttpRequest code in order to let your form data be submitted to Pipedrive’s Persons API.

 

To understand more about their API, read here:

https://developers.pipedrive.com/docs/api/v1/Persons#addPerson

<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", 'https://
Notion image
 

This will make all form data appear under your Persons API.

Notion image
 

STEP 2

If you would like to make the form submission data appear under Leads as well like this below:

Notion image
 

You will need to create GET request to fetch the person_id that you created earlier in Step 1 and push that data to a new dataLayer event called ‘Pipedrive Persons API’ so that we can later fetch it in GTM:

<script>
setTimeout(function(){  
  var xhr = new XMLHttpRequest();
  xhr.open("GET",'https://

In order to create a new lead in Pipedrive, a person_id is required because the Persons table is a dependency to their Leads table. A new lead cannot be created if a person_id doesn’t exist or if that lead doesn’t exist as a Person in our Pipedrive Contacts.

 

Once the data is pushed to GTM’s dataLayer, you can then create a new variable in GTM to make the person_id value readily available for the next API steps.

Notion image
 

STEP 3

Once the person_id is stored in the GTM variable you’ve created in Step 2 earlier, you can then deploy this script below to post that data back to Pipedrive Leads API so that a new lead record will be created from that person_id.

var xhr = new XMLHttpRequest();
xhr.open("POST", 'https://
 

STEP 4

Once you create a new lead record via the Leads API, a lead_id will then be generated which will allow us to use it later in Step 5 by sending extra fields like ‘Message’ form field that they filled in.

But before we can POST that, we need to GET the lead_id first.

setTimeout(function(){  
  var xhr2 = new XMLHttpRequest();
  xhr2.open("GET",'https://
 

Follow the same steps like how we create a new GTM variable earlier with Pipedrive Persons ID for Leads ID as well.

Notion image
 

STEP 5

Once we have the leads_id, we can then POST the custom Message field values together with the leads_id that we obtain to ensure that for every new lead record we’re adding in Pipedrive, the custom Message will also appear under the Lead Notes section as well.

var xhr = new XMLHttpRequest();
xhr.open("POST", 'https://

3. Add our Conversion Snippet

Then, the final step is to add our conversion snippet.

 

FIRST METHOD: USING HTML CODE

Remember our code earlier? Add these lines at the bottom of the function:

 // Assigning event listeners to the button
    let btn = document.getElementById("myBtn");
    btn.addEventListener('click', event => { 
				runReditusFunction()
    });

    function runReditusFunction(){
      if (emailExist()) {
        sendDatatoPipedrive();
 

SECOND METHOD: USING GOOGLE TAG MANAGER

Create a tag like this below and add our gr(track) conversion snippet that is triggered when myBtn button id is clicked.

Notion image

CALENDLY

Calendly uses Embed API to embed its form within your website.

What does this mean?

It means your form is not hosted within your own domain hence the data is only stored in their server instead of ours.

This is where it gets tricky because their Embed API works the same as how an iframe operates.

 
💡
But…fret not! We have the solution that’s easy for you to follow.
 

There are 3 server-side features that Calendly provide which allows us to track any Calendly booking form input:

 

FIRST FEATURE: window.postMessage()

Calendly JS widget uses window.postMessage() to post events to the parent window. The event payload is a JavaScript object of the following format where XXX is the name of the booking flow event:

{ event: 'calendly.XXX' }

Here are the events Calendly fires when an invitee follows the booking flow:

 

SECOND FEATURE: CROSS-ORIGIN ALLOW

Notion image

Unlike some tools, Calendly practices a very relaxed cross-origin policy which allows data resources sharing between different domains.

 

THIRD FEATURE: WITH CORS ALLOW, THIS MEANS WE CAN LEVERAGE GET API REQUEST

Notion image

Later in this guide, we are going to show how you can leverage Calendly API in order for you to fetch every successful form submission from Calendly.

 

Alright, let’s show you the steps based on the 3 server-side features that Calendly is providing us. You may also need to install Google Tag Manager to your site as well in order to make the steps work.

 

1. Create a JavaScript listener to push Calendly’s data in window.postMessage() to GTM’s dataLayer

In order to do that, we have built a code that you can use:

<script>
window.dataLayer = window.dataLayer ||[];
window.addEventListener('message',
  function(e) {
    if (e.data.event && e.data.event.indexOf('calendly') === 0) {
      window.dataLayer.push({
        'event' : 'calendly',
        'calendly_event_name' : e.data.event.split('.')[1],
        'calendly_event_details' : e.data.payload,
        'calendly_just_invitee' : e.data.payload.invitee.uri,
        'calendly_invitee_separate' : e.data.payload.invitee.uri.split('/'),
        'calendly_event_uuid' : e.data.payload.invitee.uri.split('/')[4],
        'calendly_invitee_uuid' : e.data.payload.invitee.uri.split('/')[6]
      });
    }
  }
)
</script>

Copy the code above and paste it inside a new tag in Google Tag Manager and set it to trigger in All Pages.

Notion image

Run GTM Debug Console to see the resulting JSON payload:

Notion image
 

The only 2 values we’re interested in are the:

Calendly Invite UUID:

Calendly Invitee UUID:

which we’re going to need for our 2nd step.

Notion image
 

2. Communicate with Calendly API to fetch email data

Remember the 2 values in the dataLayer earlier? We will now need to store them as GTM variables so that we can use it in our API request that we’re going to do in a bit.

Create the first GTM variable and set the Data Layer Variable Name as calendly_event_uuid

Notion image

Create the second GTM variable and set the Data Layer Variable Name as calendly_invitee_uuid

Notion image

Then, create a new Tag in GTM and copy the following code below:

⚠️
Remember the name of the 2 variables here must match what we setup above. On the left side are the data layer names that you set earlier above, and on the right hand side are the variable names you must set in the code snippet below: calendly_event_uuid = {{calendly_event_uuid}} calendly_invitee_uuid = {{calendly_invitee_uuid}} SHOULD THE NAMES DON’T MATCH, THIS CODE WON’T WORK.
<script>
  var xhr = new XMLHttpRequest();
  xhr.open("GET",'https://api.calendly.com/scheduled_events/{{calendly_event_uuid}}/invitees/{{calendly_invitee_uuid}}', true);
  xhr.setRequestHeader("Authorization", "Bearer Create your own Calendly API token");
  xhr.responseType = 'json';
  xhr.onload = function(e) {
  if (this.status == 200) {
    console.log('response', this.response); // JSON response  
    window.dataLayer.push({
        'event' : 'API', 
        'all' : this.response
    });
  }
};
xhr.send();
</script>

To make the code work, you will also need to generate your own API token from Calendly > Integration > Webhook:

Notion image
 

3. Acquire email data from API response

Now the API will be providing a response like below:

all: {
    resource: {
      cancel_url: "https://calendly.com/cancellations/02cf7215-49cc-4" +
                  "e56-9789-d5adafa0fb9c",
      created_at: "2022-06-17T07:12:42.721529Z",
      

The only value that we’re interested in is the email value which we’re going to need to trigger our conversion snippet.

Notion image

Hence, we create another variable in GTM and name the Data Layer Variable: all.resource.email.

⚠️
Remember the name of the variable here must match what we are going to setup below.
Notion image

And in GTM debug console, it will appear like this:

Notion image
 

FOURTH: Include the email data and trigger our conversion snippet

Create a new tag to place our conversion snippet:

gr('track', 'conversion', { email: 
⚠️
Remember the name of the variable here must match what we setup above. If you set the name of the data layer variable as all.resource.email, then here it should be {{all.resource.email}} SHOULD THE NAMES DON’T MATCH, THIS CODE WON’T WORK.
Notion image

Ensure the conversion snippet tag only triggers right after the API response and not before. Hence go back to our XMLHTTPRequest tag that we created earlier and set the trigger scheduling as below:

Notion image
 

And then voila! You’re done!

WORDPRESS

1. Forminator

🗣
You will need to install GTM first in order to proceed.

Firstly, let’s create a GTM variable

First you will need to create a variable in GTM that will listen to email field input within the form.

Go to Variables section.

Notion image

Create a new variable and input the following code below:

WHAT YOU SHOULD USE

function grabEmailForReditus() {
var email_data = document.querySelector('[id^="forminator-field-email-1"]').value;
return email_data }
Notion image

WHAT YOU SHOULD NEVER USE

function grabEmailForReditus() {
var email_data = document.

The reason why the code above will never work is because Forminator generates a unique ID for every form submission hence the number becomes dynamic and changes every time which can fail the ability for us to listen to form submissions.

Notion image

This means the right way to listen isn’t to use getElementById but to use querySelector instead.

Secondly is to create a trigger:

This trigger is for us to time when exactly the email field value that we listen to earlier to be sent back to us.

 

In GTM, go to Trigger section > Create a new trigger.

Notion image

Then pick Click - All Elements as the Trigger Type.

Notion image

Then pick Some Clicks instead of All Clicks followed by inputting the following within Click Classes value:

forminator-button forminator-button-submit

Then hit Save.

Notion image

Thirdly, let’s create the tags to initiate Reditus Base Script and Conversion Tracking Script.

Reditus Base Tag

Input the following code inside the tag:

<script> (function(w, d, s, p, t) { w.gr = w.gr || function() { w.gr.q = w.gr.q || []; w.gr.q.push(arguments); }; p = d.getElementsByTagName(s)[0]; t = d.createElement(s); t.async = true; t.src = "https://app.getreditus.com/gr.js?_ce=60"; p.parentNode.insertBefore(t, p); })(window, document, "script"); gr("track", "pageview"); </script>
Notion image

Reditus Conversion Tag

Input the following code below:

<script>
  gr('track','conversion', {email: {{email_data_var}} });
</script>
Notion image

2. Elementor

🗣
You will need to install GTM first in order to proceed.

Firstly, let’s create a GTM variable

First you will need to create a variable in GTM that will listen to email field input within the form.

Go to Variables section.

Notion image

Create a new variable and input the following code below:

WHAT YOU SHOULD USE

function grabEmailForReditus() {
var email_data = document.getElementById('form-field-email').value
return email_data } 
Notion image

Secondly is to create a trigger:

This trigger is for us to time when exactly the email field value that we listen to earlier to be sent back to us.

 

In GTM, go to Trigger section > Create a new trigger.

Notion image

Then pick Click - All Elements as the Trigger Type.

Notion image

Then pick Some Clicks instead of All Clicks followed by inputting the following within Click Text value:

Click Text value 

Then hit Save.

 

Thirdly, let’s create the tags to initiate Reditus Base Script and Conversion Tracking Script.

Reditus Base Tag

Input the following code inside the tag:

<script> (function(w, d, s, p, t) { w.gr = w.gr || function() { w.gr.q = w.gr.q || []; w.gr.q.push(arguments); }; p = d.getElementsByTagName(s)[0]; t = d.createElement(s); t.async = true; t.src = "https://app.getreditus.com/gr.js?_ce=60"; p.parentNode.insertBefore(t, p); })(window, document, "script"); gr("track", "pageview"); </script>
Notion image

Reditus Conversion Tag

Input the following code below:

<script>gr('track', 'conversion', { email: {{grabEmailForReditus}} })</script>

PHP

1. PHP Form with JavaScript Function

Assuming you have built a simple PHP form with the following code:

<form action="#" method="post">
            <div>
                <label for="name">Name:</label>
                <input type="text" name="name" required="required" placeholder="Enter your name" />
            </div>

            <div>
                <label for="name">Email:</label>
                <input id="email" type="email" name="email" required="required" placeholder="Enter your email" />
            </div>

            <button type="submit">Subscribe</button>
        </form>

In order to track the email input and pass it to our conversion tracking snippet, you will need to do the following:

a) Copy the following script below and paste it below the </form>

<script>
function validateFormOnSubmit() {
    var emaildata = document.getElementById("email").value;

    if (emaildata==emaildata) {
        gr("track", "conversion", { email: emaildata });
	    }
    }
</script>

What the script does:

1) First part of the function is to grab the value of the email field after being filled

var emaildata = document.getElementById("email").value;

2) Second part of the function is to tell the code that if the email data exists (when the email field is filled), only then store the data within gr(”track”)

    if (emaildata==emaildata) {
        gr("track", "conversion", { email: emaildata });
	    }
    }

b) Then, add the following code at the beginning of the <form> code:

<form action="#" onsubmit="return validateFormOnSubmit();" method="post">

What the script does:

We are trying to tell the code to run the validateFormOnSubmit() function at the point of completion of the form.

 

Then one last step is remember to add our Reditus Base Tag as well just at the beginning of the <script>:

(function(w, d, s, p, t) { w.gr = w.gr || function() { w.gr.q = w.gr.q || []; w.gr.q.push(arguments); }; p = d.getElementsByTagName(s)[0]; t = d.createElement(s); t.async = true; t.src = "https://app.getreditus.com/gr.js?_ce=60"; p.parentNode.insertBefore(t, p); })(window, document, "script"); gr("track", "pageview");

Finally your code would look something like this:

<form action="#" onsubmit="return validateFormOnSubmit();" method="post">
            <div>
                <label for="name">Name:</label>
                <input type="text" name="name" required="required" placeholder="Enter your name" />
            </div>

            <div>
                <label for="name">Email:</label>
                <input id="email" type="email" name="email" required="required" placeholder="Enter your email" />
            </div>

            <button type="submit">Subscribe</button>
        </form>

<script>
(function(w, d, s, p, t) { w.gr = w.gr || function() { w.gr.q = w.gr.q || []; w.gr.q.push(arguments); }; p = d.getElementsByTagName(s)[0]; t = d.createElement(s); t.async = true; t.src = "https://app.getreditus.com/gr.js?_ce=60"; p.parentNode.insertBefore(t, p); })(window, document, "script"); gr("track", "pageview");
function validateFormOnSubmit() {
    var emaildata = document.getElementById("email").value;

    if (emaildata==emaildata) {
        gr("track", "conversion", { email: emaildata });
    }
    }</script>
 
Did this answer your question?
😞
😐
🤩