Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Pipedrive Tracking Suite

Time-Gated Submission Detection + Geo/Traffic Enrichment for Pipedrive Web Forms

A dataLayer enrichment script for Pipedrive's embedded web forms — detects real form submissions (filtering out the iframe's initial resize postMessage, which looks identical to a submit event), and enriches the event with traffic attribution, click IDs, IP geolocation, and device/tech data.

Built and maintained by MD Niamul — Founder, Digital Soldier Agency. Data Analytics Architect & Conversion Tracking Partner. Official Stape partner.


Why the "time-gate" exists

Pipedrive's embedded web form iframe sends a postMessage with payload.source === 'pipedriveWebForms' on load (to tell the parent page how tall to resize the iframe) — and that message has the same shape as an actual form-submission message. Without filtering, this fires a false "conversion" the instant the form loads, before the visitor has done anything.

This script fixes that with two guards:

  1. Time gate — any Pipedrive message received within 3 seconds of page load is treated as the iframe's resize event and ignored. Real submissions require the visitor to fill in fields first, so they essentially never happen inside that window.
  2. Debounce — a second identical message within 2 seconds of the last accepted one is ignored, guarding against Pipedrive occasionally sending the confirmation event twice.

Both windows are hardcoded (3000ms / 2000ms) — see Customization to adjust them.


⚠️ Critical limitation — read before deploying

This script does NOT capture contact PII (email, phone, name, company) from Pipedrive submissions.

Pipedrive's web form iframe does not expose submitted field values to the parent page via postMessage — only a generic "form submitted" signal with a form UUID. Because of this, contact_email, contact_phone, contact_first_name, contact_last_name, and contact_company are hardcoded to empty strings in the payload, and the corresponding hashed_email / hashed_phone / hashed_firstname / hashed_lastname fields are always empty too.

What this script can still do reliably:

  • Fire a clean, de-duplicated pipedrive_form_submit conversion event (for GA4/Ads conversion counting)
  • Attach full traffic attribution (source/medium/campaign, all click IDs)
  • Attach IP geolocation, with hashed_city / hashed_state / hashed_zip / hashed_country populated (geo data comes from the IP lookup, not the form, so it works fine)
  • Attach GA4 client ID, device/tech info, and marketing cookies

What it cannot do without a workaround:

  • Enhanced Conversions / CAPI matching on the actual submitted email or phone — there's no submitted-value data to hash

If you need contact-level match data: the reliable fix is server-side — use Pipedrive's own webhook (fires on new Person/Deal creation, with full field data) into your CRM/sGTM pipeline instead of relying on the client-side iframe message. This script is best used as the client-side attribution layer that a server-side Pipedrive webhook integration then joins against (matched by timestamp + IP, or by a hidden UTM/click-ID field you pass into the Pipedrive form URL).


Known code-quality note

The file includes two SHA-256 implementations: an incomplete sha256() (left mid-implementation, returns a placeholder string, and is never actually called anywhere in the script) and a complete, working sha256_secure() (used for all real hashing). The dead sha256() function is harmless as-is — since nothing calls it — but it's safe to delete if you want to slim the file down.


Output

Pushes pipedrive_form_submit to window.dataLayer on a confirmed real submission:

{
  event: 'pipedrive_form_submit',
  traffic_source: '...', traffic_medium: '...', traffic_campaign: '...', traffic_campaign_id: '...',
  event_id: 'pd_...', client_id: '...',
  conversion_time: '...ISO...', conversion_timestamp: 173..., conversion_date: 'YYYY-MM-DD', conversion_timezone: '...',
  user_agent: '...', screen_resolution: '...', viewport_size: '...', browser_language: '...', device_type: 'Desktop', os_name: 'Windows',

  form_id: '...', form_type: 'pipedrive_webform',
  contact_email: '', contact_phone: '', contact_first_name: '', contact_last_name: '', contact_company: '', // always empty — see limitation above

  hashed_email: '', hashed_phone: '', hashed_firstname: '', hashed_lastname: '', // always empty — see limitation above
  hashed_city: '...', hashed_state: '...', hashed_zip: '...', hashed_country: '...', // populated from IP geo

  external_id: '', user_id: '', session_id: '...',

  user_ip: '...', user_country: '...', user_country_id: '...', user_city: '...', user_region: '...',
  user_province: '...', user_postal_code: '...', user_continent: '...', user_latitude: '...', user_longitude: '...',

  gclid: '', gbraid: '', wbraid: '', dclid: '', fbclid: '', ttclid: '', msclkid: '', li_fat_id: '',
  twclid: '', epik: '', sclid: '', rdt_cid: '', tblci: '', dicbo: '', amzn_id: '', qclid: '', clickid: '',

  cookie_ga: '...', cookie_gid: '...', cookie_gcl_au: '...', cookie_fbp: '...', cookie_fbc: '...', tt_webid: '...', cookie_ttp: '...',

  page_url: '...', page_title: '...', page_hostname: '...', page_path: '...',
  landing_page: '...', referrer: '...', original_referrer: '...'
}

Installation

GTM Custom HTML Tag (recommended)

  1. GTM → Tags → New → Custom HTML.
  2. Paste the contents of pipedrive-tracking-suite.js wrapped in <script> tags.
  3. Trigger: All Pages (or scoped to pages with an embedded Pipedrive web form).
  4. Publish.

Direct page embed

Paste the same <script>...</script> block before </body> on any page with an embedded Pipedrive form iframe.


Customization

  • Time-gate window — if (now - loadTime < 3000) — increase if your form is long/complex and a very fast real submission is getting filtered; decrease if you're confident visitors never submit within 3s and want faster event firing.
  • Debounce window — if (now - lastFire < 2000) — adjust if Pipedrive's double-fire behavior needs a wider gap.
  • Geo provider — currently geojs.io only, no fallback chain. For production reliability at scale, consider adding the multi-provider fallback pattern used in the companion ghl-ultimate-tracking-suite repo.

⚠️ Consent — read before deploying

Like the rest of this tracking suite family, this script captures click IDs, geolocation, and marketing cookies unconditionally — no built-in consent gate. Add a consent check before deploying on EU/UK/consent-regulated traffic (see custom-cookie-consent-banner for a reference CMP implementation).


File structure

.
├── pipedrive-tracking-suite.js   # the script — GTM Custom HTML ready
└── README.md                      # this file

Browser support

ES5-safe throughout, uses XMLHttpRequest for the geo lookup (not fetch) for broad compatibility. Works inside GTM's sandboxed Custom HTML environment.


About

Built by MD Niamul — Founder & CEO, Digital Soldier Agency. Data Analytics Architect and Conversion Tracking Partner, official Stape partner. Helping agencies and D2C brands turn ad spend into verifiable, accurately-tracked profit through data integrity and server-side architecture.

License

MIT — see LICENSE.

About

Pipedrive web form tracking with false-submission filtering, traffic attribution, and geo enrichment for GTM

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages