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 */
});
});
})();
One Integration, 4+ Hours Saved Daily: How BlueStone Automated B2B Logistics with ClickPost Darwin
Before ClickPost Darwin, we were managing our logistics tracking through a separate third-party API integration. With ClickPost Darwin, we moved AWB generation and tracking onto the same platform, for both dispatch and shipments. - Vijendra Lakshman Kodale, Senior Logistics Manager, Bluestone
Bluestone's B2B dispatch ran on a patchwork of courier relationships. Every partner needed its own API integration, built and maintained separately by the tech team rather than the logistics team that actually depended on it day to day. AWB numbers had to be uploaded and generated by hand, dispatch data was sent to each courier individually, and checking a shipment's status meant logging into that specific courier's own website. Pulling AWB numbers off each site and lining them up for the courier teams alone ate 4+ hours of the day.
The Need for a Single Source of Truth
Bluestone needed a system that could:
Generate AWB numbers automatically as orders were processed, without a manual upload step.
Push dispatch data directly to courier partners, eliminating manual handoffs.
Bring tracking for every courier partner into one dashboard instead of many.
Replace the tech team's per-courier integration work with a single, ready-made connection.
Building a Smarter Flow
With ClickPost Darwin, Bluestone consolidated its courier operations onto one platform:
Automated AWB generation triggered the moment an order is processed for invoicing, no manual upload required.
Direct data pushed to couriers, with tracking pulled straight back into Bluestone's own order management and ERP system.
Single-point tracking across all courier partners from one dashboard, instead of checking each courier's own site.
One integration instead of many, replacing the tech team's per-courier API builds with ClickPost Darwin's existing multi-courier connection.
In the B2B part, we were doing manual data updates and manual AWB generation for every courier partner. That's been completely reduced by ClickPost Darwin - we have a single integration where we push data directly, and AWB generation happens directly from ClickPost Darwin. - Vijendra Lakshman Kodale
Impact in Numbers
Metric
Before ClickPost Darwin
After ClickPost Darwin
AWB Generation
Manual, uploaded per courier
Automatic, triggered at invoicing
Courier Integration
Separate API build per partner
Single integration via ClickPost Darwin
Tracking
Checked on each courier's own site
One dashboard, all couriers
AWB Download & Reconciliation
4 hours/day of manual work
Instant - pulled directly at invoicing
Dispatch Data Handling
Sent manually to each courier
Pushed automatically via API
Book a demo to see how ClickPost Darwin can centralize your courier bookings and tracking.
About Bluestone
Established in 2011, Bluestone is a digital-first, omnichannel fine jewellery brand and one of India's leading destinations for high-quality, exquisitely designed jewellery, operating a nationwide store and dispatch network across the country.
Industry: Jewellery
Solutions Used: AWB Generation | Tracking
Website:
Other Customer Success Stories
Fashion & Apparel
How DaMENSCH reduced RTO rate by 54% with the help of ClickPost