{
  "exportFormatVersion": 2,
  "exportTime": "2026-09-14 10:20:00",
  "containerVersion": {
    "path": "accounts/0/containers/0/versions/0",
    "accountId": "0",
    "containerId": "0",
    "fingerprint": "0",
    "containerVersionId": "0",
    "name": "OpenAI Ads Pixel - Plug & Play v2.1",
    "description": "One-import setup for OpenAI/ChatGPT Ads Measurement Pixel. Replace one Pixel ID variable; standard GA4 ecommerce/lead events are then mapped automatically.",
    "container": {
      "path": "accounts/0/containers/0",
      "accountId": "0",
      "containerId": "0",
      "fingerprint": "0",
      "name": "OpenAI Ads Pixel - Plug & Play v2.1",
      "publicId": "GTM-XXXXXXX",
      "usageContext": [
        "WEB"
      ]
    },
    "builtInVariable": [
      {
        "accountId": "0",
        "containerId": "0",
        "fingerprint": "0",
        "type": "EVENT",
        "name": "Event"
      }
    ],
    "variable": [
      {
        "accountId": "0",
        "containerId": "0",
        "fingerprint": "0",
        "variableId": "1",
        "name": "OpenAI - Pixel ID",
        "type": "c",
        "parameter": [
          {
            "type": "TEMPLATE",
            "key": "value",
            "value": "PASTE_OPENAI_PIXEL_ID_HERE"
          }
        ]
      }
    ],
    "trigger": [
      {
        "accountId": "0",
        "containerId": "0",
        "fingerprint": "0",
        "triggerId": "1",
        "name": "OpenAI - All Pages",
        "type": "PAGEVIEW"
      },
      {
        "accountId": "0",
        "containerId": "0",
        "fingerprint": "0",
        "triggerId": "2",
        "name": "OpenAI - Supported GA4 / conversion events",
        "type": "CUSTOM_EVENT",
        "customEventFilter": [
          {
            "type": "MATCH_REGEX",
            "parameter": [
              {
                "type": "TEMPLATE",
                "key": "arg0",
                "value": "{{_event}}"
              },
              {
                "type": "TEMPLATE",
                "key": "arg1",
                "value": "^(view_item|view_item_list|add_to_cart|begin_checkout|purchase|generate_lead|sign_up|appointment_scheduled|subscription_created|trial_started|contents_viewed|items_added|checkout_started|order_created|lead_created|registration_completed)$"
              }
            ]
          }
        ]
      },
      {
        "accountId": "0",
        "containerId": "0",
        "fingerprint": "0",
        "triggerId": "3",
        "name": "OpenAI - SPA page_view (optional)",
        "type": "CUSTOM_EVENT",
        "customEventFilter": [
          {
            "type": "EQUALS",
            "parameter": [
              {
                "type": "TEMPLATE",
                "key": "arg0",
                "value": "{{_event}}"
              },
              {
                "type": "TEMPLATE",
                "key": "arg1",
                "value": "page_view"
              }
            ]
          }
        ]
      }
    ],
    "tag": [
      {
        "accountId": "0",
        "containerId": "0",
        "fingerprint": "0",
        "tagId": "1",
        "name": "OpenAI Ads - Plug & Play",
        "type": "cvt_0_1",
        "parameter": [
          {
            "type": "TEMPLATE",
            "key": "pixelId",
            "value": "{{OpenAI - Pixel ID}}"
          },
          {
            "type": "BOOLEAN",
            "key": "sendEvent",
            "value": "true"
          },
          {
            "type": "BOOLEAN",
            "key": "enableDebug",
            "value": "false"
          },
          {
            "type": "TEMPLATE",
            "key": "eventMode",
            "value": "inherit"
          },
          {
            "type": "BOOLEAN",
            "key": "enableGa4Mapping",
            "value": "true"
          },
          {
            "type": "BOOLEAN",
            "key": "mostRecentDataLayerOnly",
            "value": "true"
          },
          {
            "type": "BOOLEAN",
            "key": "enableAutoEventId",
            "value": "true"
          },
          {
            "type": "BOOLEAN",
            "key": "useTransactionIdAsEventId",
            "value": "false"
          },
          {
            "type": "BOOLEAN",
            "key": "enableGoogleConsentMode",
            "value": "true"
          },
          {
            "type": "BOOLEAN",
            "key": "optOut",
            "value": "false"
          }
        ],
        "firingTriggerId": [
          "1",
          "2"
        ],
        "tagFiringOption": "ONCE_PER_EVENT",
        "consentSettings": {
          "consentStatus": "NOT_NEEDED"
        },
        "monitoringMetadata": {
          "type": "MAP"
        }
      },
      {
        "accountId": "0",
        "containerId": "0",
        "fingerprint": "0",
        "tagId": "2",
        "name": "OpenAI Ads - SPA page_view (optional - paused)",
        "type": "cvt_0_1",
        "parameter": [
          {
            "type": "TEMPLATE",
            "key": "pixelId",
            "value": "{{OpenAI - Pixel ID}}"
          },
          {
            "type": "BOOLEAN",
            "key": "sendEvent",
            "value": "true"
          },
          {
            "type": "BOOLEAN",
            "key": "enableDebug",
            "value": "false"
          },
          {
            "type": "TEMPLATE",
            "key": "eventMode",
            "value": "inherit"
          },
          {
            "type": "BOOLEAN",
            "key": "enableGa4Mapping",
            "value": "true"
          },
          {
            "type": "BOOLEAN",
            "key": "mostRecentDataLayerOnly",
            "value": "true"
          },
          {
            "type": "BOOLEAN",
            "key": "enableAutoEventId",
            "value": "true"
          },
          {
            "type": "BOOLEAN",
            "key": "useTransactionIdAsEventId",
            "value": "false"
          },
          {
            "type": "BOOLEAN",
            "key": "enableGoogleConsentMode",
            "value": "true"
          },
          {
            "type": "BOOLEAN",
            "key": "optOut",
            "value": "false"
          }
        ],
        "firingTriggerId": [
          "3"
        ],
        "tagFiringOption": "ONCE_PER_EVENT",
        "paused": true,
        "consentSettings": {
          "consentStatus": "NOT_NEEDED"
        },
        "monitoringMetadata": {
          "type": "MAP"
        }
      }
    ],
    "customTemplate": [
      {
        "accountId": "0",
        "containerId": "0",
        "fingerprint": "0",
        "templateId": "1",
        "name": "ChatGPT Ads Pixel – Plug & Play",
        "templateData": "___TERMS_OF_SERVICE___\nBy creating or modifying this file you agree to Google Tag Manager's Community\nTemplate Gallery Developer Terms of Service available at\nhttps://developers.google.com/tag-manager/gallery-tos (or such other URL as\nGoogle may provide), as modified from time to time.\n\n___INFO___\n{\n  \"type\": \"TAG\",\n  \"id\": \"cvt_chatgpt_ads_pixel_plug_play_v2\",\n  \"version\": 1,\n  \"categories\": [\n    \"ADVERTISING\",\n    \"CONVERSIONS\",\n    \"ANALYTICS\"\n  ],\n  \"displayName\": \"ChatGPT Ads Pixel – Plug & Play\",\n  \"brand\": {\n    \"id\": \"searchbase\",\n    \"displayName\": \"Searchbase\"\n  },\n  \"description\": \"Plug-and-play OpenAI/ChatGPT Ads Measurement Pixel template with automatic GA4/dataLayer event mapping, ecommerce value/items mapping, Consent Mode support and browser/server event ID support.\",\n  \"containerContexts\": [\n    \"WEB\"\n  ],\n  \"securityGroups\": []\n}\n\n___TEMPLATE_PARAMETERS___\n[\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"pixelSettings\",\n    \"displayName\": \"Pixel setup\",\n    \"groupStyle\": \"ZIPPY_OPEN\",\n    \"subParams\": [\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"pixelId\",\n        \"displayName\": \"OpenAI Pixel ID\",\n        \"simpleValueType\": true,\n        \"valueValidators\": [\n          {\n            \"type\": \"NON_EMPTY\"\n          }\n        ],\n        \"help\": \"Pixel ID from ChatGPT Ads / OpenAI Ads Manager.\",\n        \"alwaysInSummary\": true\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"sendEvent\",\n        \"checkboxText\": \"Send a measurement event when this tag fires\",\n        \"simpleValueType\": true,\n        \"defaultValue\": true\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"enableDebug\",\n        \"checkboxText\": \"Enable SDK debug logging\",\n        \"simpleValueType\": true,\n        \"defaultValue\": false,\n        \"help\": \"Debug is also enabled automatically in GTM Preview/Debug mode.\"\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"eventSettings\",\n    \"displayName\": \"Event\",\n    \"groupStyle\": \"ZIPPY_OPEN\",\n    \"enablingConditions\": [\n      {\n        \"paramName\": \"sendEvent\",\n        \"paramValue\": true,\n        \"type\": \"EQUALS\"\n      }\n    ],\n    \"subParams\": [\n      {\n        \"type\": \"SELECT\",\n        \"name\": \"eventMode\",\n        \"displayName\": \"Event source\",\n        \"simpleValueType\": true,\n        \"defaultValue\": \"inherit\",\n        \"selectItems\": [\n          {\n            \"value\": \"inherit\",\n            \"displayValue\": \"Inherit and map GTM / GA4 event\"\n          },\n          {\n            \"value\": \"override\",\n            \"displayValue\": \"Choose OpenAI event manually\"\n          }\n        ],\n        \"help\": \"Inherit maps common GA4 event names automatically. Unknown events are sent as sanitized custom events.\"\n      },\n      {\n        \"type\": \"SELECT\",\n        \"name\": \"eventName\",\n        \"displayName\": \"OpenAI event name\",\n        \"simpleValueType\": true,\n        \"defaultValue\": \"page_viewed\",\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"eventMode\",\n            \"paramValue\": \"override\",\n            \"type\": \"EQUALS\"\n          }\n        ],\n        \"selectItems\": [\n          {\n            \"value\": \"page_viewed\",\n            \"displayValue\": \"Page viewed\"\n          },\n          {\n            \"value\": \"contents_viewed\",\n            \"displayValue\": \"Contents viewed\"\n          },\n          {\n            \"value\": \"items_added\",\n            \"displayValue\": \"Items added\"\n          },\n          {\n            \"value\": \"checkout_started\",\n            \"displayValue\": \"Checkout started\"\n          },\n          {\n            \"value\": \"order_created\",\n            \"displayValue\": \"Order created\"\n          },\n          {\n            \"value\": \"lead_created\",\n            \"displayValue\": \"Lead created\"\n          },\n          {\n            \"value\": \"registration_completed\",\n            \"displayValue\": \"Registration completed\"\n          },\n          {\n            \"value\": \"appointment_scheduled\",\n            \"displayValue\": \"Appointment scheduled\"\n          },\n          {\n            \"value\": \"subscription_created\",\n            \"displayValue\": \"Subscription created\"\n          },\n          {\n            \"value\": \"trial_started\",\n            \"displayValue\": \"Trial started\"\n          },\n          {\n            \"value\": \"custom\",\n            \"displayValue\": \"Custom event\"\n          }\n        ]\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"customEventName\",\n        \"displayName\": \"Custom event name\",\n        \"simpleValueType\": true,\n        \"enablingConditions\": [\n          {\n            \"paramName\": \"eventMode\",\n            \"paramValue\": \"override\",\n            \"type\": \"EQUALS\"\n          },\n          {\n            \"paramName\": \"eventName\",\n            \"paramValue\": \"custom\",\n            \"type\": \"EQUALS\"\n          }\n        ],\n        \"help\": \"1–64 characters. Lowercase letters, numbers, underscores and dashes are recommended.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"eventId\",\n        \"displayName\": \"Event ID\",\n        \"simpleValueType\": true,\n        \"help\": \"Optional. Reuse the same ID in the Conversions API for browser/server deduplication.\"\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"optOut\",\n        \"checkboxText\": \"Set opt_out=true for this event\",\n        \"simpleValueType\": true,\n        \"defaultValue\": false,\n        \"help\": \"OpenAI event option for opting this event out of future user-level personalization.\"\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"ga4Settings\",\n    \"displayName\": \"GA4 / Data Layer mapping\",\n    \"groupStyle\": \"ZIPPY_OPEN_ON_PARAM\",\n    \"enablingConditions\": [\n      {\n        \"paramName\": \"sendEvent\",\n        \"paramValue\": true,\n        \"type\": \"EQUALS\"\n      }\n    ],\n    \"subParams\": [\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"enableGa4Mapping\",\n        \"checkboxText\": \"Automatically map GA4 ecommerce data\",\n        \"simpleValueType\": true,\n        \"defaultValue\": true,\n        \"help\": \"Reads ecommerce.items, ecommerce.value and ecommerce.currency (with top-level fallbacks). GA4 major currency units are converted to ISO 4217 minor units required by OpenAI.\"\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"mostRecentDataLayerOnly\",\n        \"checkboxText\": \"Read only the most recent Data Layer event\",\n        \"simpleValueType\": true,\n        \"defaultValue\": true,\n        \"help\": \"Uses Data Layer version 1 instead of version 2 to reduce recursive merging from previous ecommerce pushes.\"\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"enableAutoEventId\",\n        \"checkboxText\": \"Automatically read event_id / eventId from the Data Layer\",\n        \"simpleValueType\": true,\n        \"defaultValue\": true,\n        \"help\": \"Recommended when the same event ID is also sent through OpenAI Conversions API for browser/server deduplication.\"\n      },\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"useTransactionIdAsEventId\",\n        \"checkboxText\": \"For purchases, fall back to ecommerce.transaction_id as event_id\",\n        \"simpleValueType\": true,\n        \"defaultValue\": false,\n        \"help\": \"Enable only if your server-side/CAPI implementation uses the same transaction_id as event_id.\"\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"manualEventData\",\n    \"displayName\": \"Manual event data / overrides\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"enablingConditions\": [\n      {\n        \"paramName\": \"sendEvent\",\n        \"paramValue\": true,\n        \"type\": \"EQUALS\"\n      }\n    ],\n    \"subParams\": [\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"amount\",\n        \"displayName\": \"Amount (minor units)\",\n        \"simpleValueType\": true,\n        \"help\": \"Optional manual override. Enter an integer in minor units, e.g. 2599 for 25.99 SEK/USD/EUR.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"currency\",\n        \"displayName\": \"Currency\",\n        \"simpleValueType\": true,\n        \"help\": \"3-letter ISO 4217 code, e.g. SEK, EUR, USD.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"planId\",\n        \"displayName\": \"Plan ID\",\n        \"simpleValueType\": true,\n        \"help\": \"Optional for trial_started, subscription_created and custom events.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"contentsVariable\",\n        \"displayName\": \"Contents array variable\",\n        \"simpleValueType\": true,\n        \"help\": \"Optional GTM variable returning an array of OpenAI Content objects. When provided, it overrides automatically mapped GA4 items.\"\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"userMatching\",\n    \"displayName\": \"Advanced matching (hashed identifiers)\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"subParams\": [\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"emailSha256\",\n        \"displayName\": \"Email SHA-256\",\n        \"simpleValueType\": true,\n        \"help\": \"Pass only a normalized SHA-256 hash. Do not pass raw email.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"phoneSha256\",\n        \"displayName\": \"Phone SHA-256\",\n        \"simpleValueType\": true,\n        \"help\": \"Pass only a normalized SHA-256 hash.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"externalIdSha256\",\n        \"displayName\": \"External ID SHA-256\",\n        \"simpleValueType\": true,\n        \"help\": \"Stable pseudonymous customer ID, SHA-256 hashed.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"firstNameSha256\",\n        \"displayName\": \"First name SHA-256\",\n        \"simpleValueType\": true\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"lastNameSha256\",\n        \"displayName\": \"Last name SHA-256\",\n        \"simpleValueType\": true\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"country\",\n        \"displayName\": \"Country\",\n        \"simpleValueType\": true,\n        \"help\": \"Two-letter ISO 3166-1 code, e.g. SE.\"\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"city\",\n        \"displayName\": \"City\",\n        \"simpleValueType\": true\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"region\",\n        \"displayName\": \"Region\",\n        \"simpleValueType\": true\n      },\n      {\n        \"type\": \"TEXT\",\n        \"name\": \"postalCode\",\n        \"displayName\": \"Postal code\",\n        \"simpleValueType\": true\n      }\n    ]\n  },\n  {\n    \"type\": \"GROUP\",\n    \"name\": \"consentSettings\",\n    \"displayName\": \"Consent\",\n    \"groupStyle\": \"ZIPPY_CLOSED\",\n    \"subParams\": [\n      {\n        \"type\": \"CHECKBOX\",\n        \"name\": \"enableGoogleConsentMode\",\n        \"checkboxText\": \"Use Google Consent Mode\",\n        \"simpleValueType\": true,\n        \"defaultValue\": true,\n        \"help\": \"Recommended default. Maps ad_storage to OpenAI Pixel consent. Measurement events are not sent while ad_storage is denied; advanced matching is withheld while ad_user_data is denied. If Consent Mode is not configured, GTM treats unset consent as granted.\"\n      }\n    ]\n  }\n]\n\n___SANDBOXED_JS_FOR_WEB_TEMPLATE___\nconst callInWindow = require('callInWindow');\nconst copyFromWindow = require('copyFromWindow');\nconst createArgumentsQueue = require('createArgumentsQueue');\nconst getContainerVersion = require('getContainerVersion');\nconst injectScript = require('injectScript');\nconst logToConsole = require('logToConsole');\nconst copyFromDataLayer = require('copyFromDataLayer');\nconst isConsentGranted = require('isConsentGranted');\nconst addConsentListener = require('addConsentListener');\nconst makeString = require('makeString');\nconst makeNumber = require('makeNumber');\nconst makeInteger = require('makeInteger');\nconst getType = require('getType');\nconst Math = require('Math');\n\nconst SDK_URL = 'https://bzrcdn.openai.com/sdk/oaiq.min.js';\nconst CACHE_TOKEN = 'chatgpt_ads_pixel_sdk';\nconst containerVersion = getContainerVersion() || {};\nconst debugEnabled = data.enableDebug === true || containerVersion.debugMode === true || containerVersion.previewMode === true;\n\nconst EVENT_DATA_TYPES = {\n  page_viewed: 'contents',\n  contents_viewed: 'contents',\n  items_added: 'contents',\n  checkout_started: 'contents',\n  order_created: 'contents',\n  lead_created: 'customer_action',\n  registration_completed: 'customer_action',\n  appointment_scheduled: 'customer_action',\n  subscription_created: 'plan_enrollment',\n  trial_started: 'plan_enrollment',\n  custom: 'custom'\n};\n\nconst GA4_EVENT_MAP = {\n  page_view: 'page_viewed',\n  'gtm.init': 'page_viewed',\n  'gtm.js': 'page_viewed',\n  'gtm.dom': 'page_viewed',\n  'gtm.load': 'page_viewed',\n  'gtm.historyChange': 'page_viewed',\n  view_item: 'contents_viewed',\n  view_item_list: 'contents_viewed',\n  add_to_cart: 'items_added',\n  begin_checkout: 'checkout_started',\n  purchase: 'order_created',\n  generate_lead: 'lead_created',\n  sign_up: 'registration_completed',\n  appointment_scheduled: 'appointment_scheduled',\n  subscription_created: 'subscription_created',\n  trial_started: 'trial_started'\n};\n\nconst hasValue = value => value !== undefined && value !== null && value !== '';\nconst addString = (target, key, value) => { if (hasValue(value)) target[key] = makeString(value); };\nconst addInteger = (target, key, value) => { if (hasValue(value)) target[key] = makeInteger(value); };\nconst hasKeys = object => { for (const key in object) return true; return false; };\n\nconst callOaiq = (command, arg1, arg2, arg3) => {\n  if (copyFromWindow('oaiq')) {\n    if (arg3 !== undefined) callInWindow('oaiq', command, arg1, arg2, arg3);\n    else if (arg2 !== undefined) callInWindow('oaiq', command, arg1, arg2);\n    else if (arg1 !== undefined) callInWindow('oaiq', command, arg1);\n    else callInWindow('oaiq', command);\n    return;\n  }\n  const oaiq = createArgumentsQueue('oaiq', 'oaiq.queue');\n  if (arg3 !== undefined) oaiq(command, arg1, arg2, arg3);\n  else if (arg2 !== undefined) oaiq(command, arg1, arg2);\n  else if (arg1 !== undefined) oaiq(command, arg1);\n  else oaiq(command);\n};\n\nconst dl = key => copyFromDataLayer(key, data.mostRecentDataLayerOnly === true ? 1 : 2);\n\nconst sanitizeCustomEventName = value => {\n  const input = makeString(value || 'custom_event').toLowerCase();\n  const allowed = 'abcdefghijklmnopqrstuvwxyz0123456789_-';\n  const alnum = 'abcdefghijklmnopqrstuvwxyz0123456789';\n  let output = '';\n  for (let i = 0; i < input.length && output.length < 64; i += 1) {\n    const char = input.charAt(i);\n    output += allowed.indexOf(char) >= 0 ? char : '_';\n  }\n  if (!output) output = 'custom_event';\n  if (alnum.indexOf(output.charAt(0)) < 0) output = 'event' + output;\n  if (output.length > 64) output = output.substring(0, 64);\n  if (alnum.indexOf(output.charAt(output.length - 1)) < 0) {\n    output = output.substring(0, output.length - 1) + '0';\n  }\n  if (EVENT_DATA_TYPES[output]) {\n    output = 'event_' + output;\n    if (output.length > 64) output = output.substring(0, 64);\n  }\n  return output;\n};\n\nconst getEventInfo = () => {\n  if (data.eventMode === 'override') {\n    const eventName = data.eventName || 'page_viewed';\n    return eventName === 'custom'\n      ? { eventName: 'custom', customEventName: sanitizeCustomEventName(data.customEventName) }\n      : { eventName: eventName };\n  }\n  const inherited = dl('event') || 'page_view';\n  if (GA4_EVENT_MAP[inherited]) return { eventName: GA4_EVENT_MAP[inherited] };\n  if (EVENT_DATA_TYPES[inherited] && inherited !== 'custom') return { eventName: inherited };\n  return { eventName: 'custom', customEventName: sanitizeCustomEventName(inherited) };\n};\n\nconst toMinorUnits = (value, currency) => {\n  if (!hasValue(value)) return undefined;\n  const zero = ['BIF','CLP','DJF','GNF','ISK','JPY','KMF','KRW','PYG','RWF','UGX','VND','VUV','XAF','XOF','XPF'];\n  const three = ['BHD','IQD','JOD','KWD','LYD','OMR','TND'];\n  const four = ['CLF'];\n  const curr = hasValue(currency) ? makeString(currency).toUpperCase() : '';\n  let multiplier = 100;\n  if (zero.indexOf(curr) >= 0) multiplier = 1;\n  else if (three.indexOf(curr) >= 0) multiplier = 1000;\n  else if (four.indexOf(curr) >= 0) multiplier = 10000;\n  return makeInteger(Math.round(makeNumber(value) * multiplier));\n};\n\nconst mapGa4Contents = currency => {\n  const ecommerce = dl('ecommerce');\n  const ecommerceObj = getType(ecommerce) === 'object' ? ecommerce : {};\n  const items = getType(ecommerceObj.items) === 'array' ? ecommerceObj.items : dl('items');\n  if (getType(items) !== 'array') return [];\n  const contents = [];\n  for (let i = 0; i < items.length; i += 1) {\n    const item = items[i] || {};\n    const content = { content_type: 'product' };\n    addString(content, 'id', item.item_id);\n    addString(content, 'name', item.item_name);\n    if (hasValue(item.quantity)) addInteger(content, 'quantity', item.quantity);\n    else content.quantity = 1;\n    if (hasValue(item.price)) content.amount = toMinorUnits(item.price, item.currency || currency);\n    if (hasValue(item.currency)) content.currency = makeString(item.currency).toUpperCase();\n    contents.push(content);\n  }\n  return contents;\n};\n\nconst buildEventProps = eventName => {\n  const dataType = EVENT_DATA_TYPES[eventName] || 'custom';\n  const props = { type: dataType };\n  const ecommerce = dl('ecommerce');\n  const ecommerceObj = getType(ecommerce) === 'object' ? ecommerce : {};\n\n  if (data.enableGa4Mapping === true) {\n    const mappedCurrency = ecommerceObj.currency || dl('currency');\n    const mappedValue = hasValue(ecommerceObj.value) ? ecommerceObj.value : dl('value');\n    if (hasValue(mappedCurrency)) props.currency = makeString(mappedCurrency).toUpperCase();\n    if (hasValue(mappedValue)) props.amount = toMinorUnits(mappedValue, props.currency);\n    if (dataType === 'contents' || dataType === 'custom' || dataType === 'plan_enrollment') {\n      const mappedContents = mapGa4Contents(props.currency);\n      if (mappedContents.length > 0) props.contents = mappedContents;\n    }\n  }\n\n  if (hasValue(data.currency)) props.currency = makeString(data.currency).toUpperCase();\n  if (hasValue(data.amount)) props.amount = makeInteger(data.amount);\n  if ((dataType === 'custom' || dataType === 'plan_enrollment') && hasValue(data.planId)) props.plan_id = makeString(data.planId);\n\n  if (getType(data.contentsVariable) === 'array' && (dataType === 'contents' || dataType === 'custom' || dataType === 'plan_enrollment')) {\n    props.contents = data.contentsVariable;\n  }\n\n  return props;\n};\n\nconst buildEventOptions = info => {\n  const options = {};\n  let eventId = data.eventId;\n  if (!hasValue(eventId) && data.enableAutoEventId === true) {\n    eventId = dl('event_id') || dl('eventId');\n    if (!hasValue(eventId)) {\n      const ecommerce = dl('ecommerce');\n      const ecommerceObj = getType(ecommerce) === 'object' ? ecommerce : {};\n      eventId = ecommerceObj.event_id;\n      if (!hasValue(eventId) && data.useTransactionIdAsEventId === true && info.eventName === 'order_created') {\n        eventId = ecommerceObj.transaction_id || dl('transaction_id');\n      }\n    }\n  }\n  addString(options, 'event_id', eventId);\n  if (info.eventName === 'custom') addString(options, 'custom_event_name', info.customEventName);\n  if (data.optOut === true) options.opt_out = true;\n  return options;\n};\n\nconst buildInitConfig = allowUserData => {\n  const config = { pixelId: makeString(data.pixelId) };\n  if (debugEnabled) config.debug = true;\n  if (allowUserData) {\n    const user = {};\n    addString(user, 'email_sha256', data.emailSha256);\n    addString(user, 'phone_number_sha256', data.phoneSha256);\n    addString(user, 'external_id_sha256', data.externalIdSha256);\n    addString(user, 'first_name_sha256', data.firstNameSha256);\n    addString(user, 'last_name_sha256', data.lastNameSha256);\n    addString(user, 'country', data.country);\n    addString(user, 'city', data.city);\n    addString(user, 'region', data.region);\n    addString(user, 'postal_code', data.postalCode);\n    if (hasKeys(user)) config.user = user;\n  }\n  return config;\n};\n\nconst validate = (info, props) => {\n  if (!hasValue(data.pixelId)) return 'Pixel ID is required.';\n  if (info.eventName === 'custom' && !hasValue(info.customEventName)) return 'Custom event name is required.';\n  if (hasValue(props.amount) && !hasValue(props.currency)) return 'Currency is required when amount is set.';\n  if (hasValue(props.currency) && makeString(props.currency).length !== 3) return 'Currency must be a 3-letter ISO 4217 code.';\n  return null;\n};\n\nconst fail = message => {\n  if (debugEnabled) logToConsole('[ChatGPT Ads Pixel] ' + message);\n  data.gtmOnFailure();\n};\n\nif (!hasValue(data.pixelId)) {\n  fail('Pixel ID is required.');\n  return;\n}\n\nlet measurementGranted = true;\nlet userDataGranted = true;\nif (data.enableGoogleConsentMode === true) {\n  measurementGranted = isConsentGranted('ad_storage');\n  userDataGranted = isConsentGranted('ad_user_data');\n  callOaiq('consent', measurementGranted);\n\n  addConsentListener('ad_storage', (type, granted) => {\n    if (type === 'ad_storage') callOaiq('consent', granted);\n  });\n}\n\ncallOaiq('init', buildInitConfig(data.enableGoogleConsentMode === true ? userDataGranted : true));\n\nif (data.sendEvent === true && measurementGranted) {\n  const info = getEventInfo();\n  const props = buildEventProps(info.eventName);\n  const validationError = validate(info, props);\n  if (validationError) {\n    fail(validationError);\n    return;\n  }\n  callOaiq('measure', info.eventName, props, buildEventOptions(info));\n}\n\ninjectScript(SDK_URL, data.gtmOnSuccess, () => fail('Failed to load ' + SDK_URL), CACHE_TOKEN);\n\n___WEB_PERMISSIONS___\n[\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"read_container_data\",\n        \"versionId\": \"1\"\n      },\n      \"param\": []\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"logging\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"environments\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"debug\"\n          }\n        }\n      ]\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"access_globals\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"keys\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"key\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"read\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"write\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"execute\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"oaiq\"\n                  },\n                  {\n                    \"type\": 8,\n                    \"boolean\": true\n                  },\n                  {\n                    \"type\": 8,\n                    \"boolean\": true\n                  },\n                  {\n                    \"type\": 8,\n                    \"boolean\": true\n                  }\n                ]\n              },\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"key\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"read\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"write\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"execute\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"oaiq.queue\"\n                  },\n                  {\n                    \"type\": 8,\n                    \"boolean\": true\n                  },\n                  {\n                    \"type\": 8,\n                    \"boolean\": true\n                  },\n                  {\n                    \"type\": 8,\n                    \"boolean\": false\n                  }\n                ]\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"inject_script\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"urls\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 1,\n                \"string\": \"https://bzrcdn.openai.com/sdk/oaiq.min.js\"\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"read_data_layer\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"allowedKeys\",\n          \"value\": {\n            \"type\": 1,\n            \"string\": \"any\"\n          }\n        }\n      ]\n    },\n    \"isRequired\": true\n  },\n  {\n    \"instance\": {\n      \"key\": {\n        \"publicId\": \"access_consent\",\n        \"versionId\": \"1\"\n      },\n      \"param\": [\n        {\n          \"key\": \"consentTypes\",\n          \"value\": {\n            \"type\": 2,\n            \"listItem\": [\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"consentType\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"read\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"write\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"ad_storage\"\n                  },\n                  {\n                    \"type\": 8,\n                    \"boolean\": true\n                  },\n                  {\n                    \"type\": 8,\n                    \"boolean\": false\n                  }\n                ]\n              },\n              {\n                \"type\": 3,\n                \"mapKey\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"consentType\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"read\"\n                  },\n                  {\n                    \"type\": 1,\n                    \"string\": \"write\"\n                  }\n                ],\n                \"mapValue\": [\n                  {\n                    \"type\": 1,\n                    \"string\": \"ad_user_data\"\n                  },\n                  {\n                    \"type\": 8,\n                    \"boolean\": true\n                  },\n                  {\n                    \"type\": 8,\n                    \"boolean\": false\n                  }\n                ]\n              }\n            ]\n          }\n        }\n      ]\n    },\n    \"isRequired\": true\n  }\n]\n\n___TESTS___\nscenarios: []\nsetup: ''\n\n___NOTES___\nPlug-and-play enhanced GTM template for the OpenAI/ChatGPT Ads Measurement Pixel. Built against OpenAI's official GTM template and measurement documentation current 2026-09-14. Adds automatic GA4/dataLayer mapping, Consent Mode integration and automatic event_id lookup. This is an independent enhanced template, not the official OpenAI template.\n"
      }
    ]
  }
}
