and runs during HTML parse, but hubspotutk is set by
js.hs-analytics.net, measured loading at ~834ms. On a first visit the cookie
does not exist yet, so a single read returns nothing and the visitor gets no
external ID at all — and a first visit is exactly what an ad click is. So
poll briefly until HubSpot sets it. The SDK loads lazily (~4.5s) and replays
a queue, so an init queued a second or two in still lands before any events
are transmitted. */
(function attachExternalId() {
var attempts = 0;
var MAX_ATTEMPTS = 40; /* 40 x 200ms = 8s, then give up quietly */
var timer = null;
function tryAttach() {
var raw = getExternalId();
if (!raw) {
if (++attempts >= MAX_ATTEMPTS && timer) clearInterval(timer);
return;
}
if (timer) clearInterval(timer);
sha256Hex(raw).then(function (hash) {
oaiq("init", { user: { external_id_sha256: hash } });
}).catch(function () {});
}
tryAttach(); /* returning visitor: immediate */
if (!getExternalId()) timer = setInterval(tryAttach, 200);
})();
/* ---------------------------------------------------------------------------
2. Load the SDK off the critical path
Whichever comes first: the main thread going idle after load, or the first
sign of real user intent. No preconnect on purpose — a TLS handshake during
LCP for a script we deliberately deferred is a net loss.
Measured on clickpost.ai: load event 3614ms, SDK fetched 4508ms.
------------------------------------------------------------------------ */
var loaded = false;
var INTENT = ["pointerdown", "keydown", "scroll"];
function loadSdk() {
if (loaded) return;
loaded = true;
INTENT.forEach(function (t) { removeEventListener(t, loadSdk, { passive: true }); });
var s = document.createElement("script");
s.src = SDK;
s.async = true;
s.fetchPriority = "low";
document.head.appendChild(s);
}
INTENT.forEach(function (t) {
addEventListener(t, loadSdk, { passive: true, once: true });
});
addEventListener("load", function () {
window.requestIdleCallback
? requestIdleCallback(loadSdk, { timeout: 2500 })
: setTimeout(loadSdk, 1500);
}, { once: true });
/* ---------------------------------------------------------------------------
3. Conversion id
sha256(lowercase(email) + "|" + formId + "|" + ISO-hour), first 20 hex,
"lead_" prefix.
- email lowercased/trimmed so casing does not fork the id
- formId keeps two different forms in the same hour from colliding
- the hour bucket is only the server's fallback; the id computed here is
sent to the relay verbatim, so the two paths cannot disagree even when
a submit straddles an hour boundary
Ads Manager's own sample omits event_id. We send it so the pixel event and
the relay event collapse into one conversion instead of counting twice.
------------------------------------------------------------------------ */
function buildEventId(email, formId) {
var seed = [
String(email || "").trim().toLowerCase(),
String(formId || ""),
new Date().toISOString().slice(0, 13)
].join("|");
return crypto.subtle.digest("SHA-256", new TextEncoder().encode(seed)).then(function (buf) {
var hex = Array.prototype.map.call(new Uint8Array(buf), function (b) {
return b.toString(16).padStart(2, "0");
}).join("");
return "lead_" + hex.slice(0, 20);
});
}
/* Guards a re-fire from the history.pushState that book-a-demo-core.js runs
after submit, and from back-navigation onto the same state. */
function firedOnce(id) {
try {
if (sessionStorage.getItem("oaiq_" + id)) return true;
sessionStorage.setItem("oaiq_" + id, "1");
return false;
} catch (e) {
return false; /* private mode / blocked storage: fire rather than lose it */
}
}
/* Path 2. keepalive lets the request finish even if the page navigates away.
Failures are swallowed deliberately: a reporting call must never surface an
error to someone who just submitted a form.
The relay hashes the email server-side into user.emails_sha256 and adds the
caller's IP and user agent, so this event carries the same match signals the
pixel gets for free. */
function sendToRelay(email, formId, eventType, eventId) {
try {
var payload = {
token: RELAY_TOKEN,
email: email,
form_id: formId || "",
event_type: eventType,
event_id: eventId, /* verbatim, so both paths always match */
source_url: location.href
};
var oppref = getOppref();
if (oppref) payload.oppref = oppref;
var externalId = getExternalId();
if (externalId) payload.external_id = externalId;
fetch(RELAY_URL, {
method: "POST",
keepalive: true,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
}).catch(function () {});
} catch (e) {}
}
/* Capture the email while the form is still on the page. onFormSubmitted does
not reliably carry submissionValues, and by then the form may be removed. */
var lastEmail = "";
document.addEventListener("submit", function (e) {
var f = e.target;
if (!f || !f.querySelector) return;
var i = f.querySelector('input[name="email"], input[type="email"]');
if (i && i.value) lastEmail = i.value;
}, true);
/* Every HubSpot form on the site reports through this one message event, so no
module or theme JS needs editing to add coverage. */
window.addEventListener("message", function (e) {
var d = e.data;
if (!d || d.type !== "hsFormCallback" || d.eventName !== "onFormSubmitted") return;
var email = (d.data && d.data.submissionValues && d.data.submissionValues.email) || lastEmail;
if (!email) return; /* without an email there is no stable id to dedupe on */
var eventType = EVENT_BY_FORM[d.id] || EVENT_DEFAULT;
buildEventId(email, d.id).then(function (id) {
if (firedOnce(id)) return;
oaiq("measure", eventType, { type: DATA_TYPE }, { event_id: id }); /* path 1 */
sendToRelay(email, d.id, eventType, id); /* path 2 */
});
});
})();
How GO DESi Ships 3 Lakh Popz a Day - Without Adding Headcount with ClickPost Darwin
"ClickPost has helped us scale our operations seamlessly and without adding many resources, that has really helped us with our dispatches and deliveries on time to our customers." — Raksha, Co-founder, GO DESi
GO DESi sells across Quick Commerce, Modern Trade, Amazon, Flipkart, and their own website. As the brand scaled, so did the complexity of getting every order to the right place, on time.
The Problem
As GO DESi expanded its offline distribution, its shipping operation couldn't keep up. Everything was manual. Transporters wrote dockets by hand. Tracking numbers were copy-pasted into the ERP one by one. To check a shipment's status, someone had to visit each carrier portal individually.
The errors were expensive.
"The transporter would write each invoice manually - incorrect pin codes, billing address instead of shipping address, so the shipment would go to the wrong location. All these inefficiencies were costing us." - Akhil, Head of Operations, GO DESi.
Around 2% of shipments were being routed to the wrong locations every month, triggering rerouting costs that added up to 4–5% of per-shipment costs. The team was processing 80–90 invoices a day entirely by hand. Each shipment took a transporter 20–25 minutes to create manually. Labels ended up on wrong cartons. Rerouting costs piled up. And Proof of Delivery? Carriers stored PODs for only 30–180 days, when billing disputes came up months later, retrieving them across multiple portals was a losing battle.
The team was drowning in admin, not running logistics.
The Solution: ClickPost Darwin
GO DESi integrated ClickPost Darwin to connect their entire carrier network directly to their ERP via API, automating everything from order creation to proof of delivery.
The moment an invoice is ready, ClickPost Darwin creates the shipment, generates labels instantly, and syncs with the carrier. The transporter arrives, scans, and picks up. No manual writing. No mismatched stickers. No errors.
Tracking updates flow into the ERP in real time. WhatsApp notifications go out automatically to customers and internal stakeholders at every stage - pickup, dispatch, out for delivery, and POD. PODs are captured on delivery and tagged directly against the invoice in the ERP, making gathering info for dispute resolution a matter of minutes, not hours.
"I can, sitting here in Bangalore, generate labels for a shipment getting picked up from Delhi. Whereas otherwise I would have to have a human resource over there just to manage these operational tasks." — Akhil Suhas, Head of Operations, GO DESi
The Results
Dispatch Accuracy
Wrong shipments: ~2% → Near zero
Rerouting costs reduced by 5%
Labels generated and pasted before transporter arrives - mismatched stickers eliminated
Speed & Efficiency
Shipment creation: 20–25 mins (manual) → Automated in minutes
2–3 hours saved every day on dispatch operations
80–90 daily invoices processed automatically vs. by hand
Shipment Capacity
Daily dispatches: 50 → 75–80 shipments per day
Same team. 60% more shipments. No new hires.
POD & Reconciliation
POD accuracy: 99%
PODs auto-synced to ERP against invoice on delivery
Billing disputes resolved in hours, not weeks
Visibility
All carriers tracked on one platform - no more portal hopping
Real-time updates to customers and internal teams at every stage
"End to end, right from order creation, tracking of the shipment, and POD collection, ClickPost Darwin came in and saved us at multiple fronts. We get to analyse the data rather than preparing the data."
Akhil Suhas | Head of Operations, GO DESi
About Go DESi
GO DESi is India's fast-growing omni-channel, food brand. Founded in 2018, the company manufactures and ships authentic Indian treats - from its flagship DESi POPz to sweets, fruit bars, and savory snacks to consumers across India and globally.
Other Customer Success Stories
Fashion & Apparel
How DaMENSCH reduced RTO rate by 54% with the help of ClickPost