Send quiz events to a tag manager
Goal: every quiz event but identity.captured reaches Google Tag Manager (or Segment, or any script on the page) as a data layer push, with no personal data forwarded.
Uses: Storefront JS API, the document mirror. Nothing to install; no API key. Octane AI’s own Google Analytics and Meta integrations are configured in the dashboard; this recipe is for everything else.
Listen on the document
Section titled “Listen on the document”Every event is also dispatched on document as a CustomEvent named octaneai:<type> with the envelope in event.detail, so a listener works even when it is added before the quiz script loads, and a tag manager custom-event trigger can hear it. There is no wildcard: subscribe by name.
<script> (function () { var TYPES = [ 'quiz.viewed', 'quiz.started', 'page.viewed', 'page.rejected', 'question.answered', 'quiz.finished', 'product.shown', 'product.clicked', 'cart.add_requested', 'cart.added', 'cart.failed', 'discount.issued', 'discount.copied', 'quiz.closed', 'error' ]; TYPES.forEach(function (type) { document.addEventListener('octaneai:' + type, function (e) { var o = Object.assign({}, e.detail.data.object); delete o.identities; // quiz.finished delete o.answers; // quiz.finished delete o.value; // question.answered: may be free text delete o.values; delete o.product; // product events: keep the ids only delete o.session_id; // links the visit to a person on the REST API delete o.visitor_id; // quiz.viewed window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'octane_' + type.replace('.', '_'), octane: o }); if (window.analytics) window.analytics.track('Quiz ' + type, o); }); }); })();</script>identity.captured is left out on purpose: it carries the email or phone the shopper just typed. question.answered’s value and values can be free text, so they are dropped too; keep component_key and option_ids, which are safe to count on.
What each push carries
Section titled “What each push carries”Every object carries quiz_id, quiz_name, version_id and version_number, so a report can be split by quiz and by published version; session_id and visitor_id are dropped above because they tie the visit to a person on the REST API. The rest per event:
| Event | Useful for a tag |
|---|---|
quiz.viewed | placement (inline, fullscreen, tapcart) |
page.viewed | page_key, page_index, terminal_page (the result page reached) |
page.rejected | page_key, fields[].component_key, fields[].reason (required or invalid) |
question.answered | component_key, option_ids |
product.shown, product.clicked | product_id, variant_id (Shopify GIDs), block_key, recommendation_source / action |
discount.issued, discount.copied | code, discount_id |
error | code, request_id |
In GTM, create a Custom Event trigger per name (octane_quiz_finished) and read the fields as Data Layer variables (octane.quiz_id, octane.terminal_page).
Things to know
Section titled “Things to know”- Listeners registered with
octaneai.on()run before the document event, and the two see the same frozendata.object. - Events fire on the Plus and Enterprise plans; on another plan nothing is dispatched on
document(the console note about the plan appears only when something callsoctaneai.on()). - To see what is flowing, set
localStorage['octaneai:debug'] = '1'in the console.
