Skip to main content
drupalreleases

Use direct release data with your AI assistant.

Learn more

ChatGPT Ads

Security covered Under active development 3 sites

This module tracks ad conversions from ChatGPT by sending data from both the browser and server to OpenAI, ensuring each conversion is counted only once. It integrates with e-commerce and webform submissions, respects user consent for tracking, and sends hashed personal data only when consent is given.

ChatGPT Ads measures ads bought in ChatGPT. It sends OpenAI the events of a visit, from the pages viewed to a sign-up, a lead, the cart and checkout steps and the order, so that OpenAI can tell which ads led to them. It loads OpenAI's Measurement Pixel on the pages you choose and, with the Conversions API sub-module, sends the conversions (orders, sign-ups and leads) from the server too, under the same event ids, so each is counted once. Drupal Commerce, Webform and account registrations are measured without custom code, and the pixel can wait for the visitor's consent.

Features

  • ⚙️ The pixel on the pages you choose. Enter the pixel id from the Ads Manager and limit the pixel with the conditions blocks use: pages, roles, content types and, on a multilingual site, languages. It sends page_viewed on every page it is on and, when turned on, registration_completed when a visitor creates an account. Optional advanced matching hands the pixel SHA-256 hashes of a logged-in user's email address and account id, computed on the server.
  • 🛡️ A consent gate. With it on, nothing is requested from OpenAI and no cookie is set until a consent manager reports the visitor's decision. Events raised before the decision wait in memory and are sent if the visitor accepts, so the landing page is still counted. The server copy follows the same rule: behind the gate, personal identifiers go only for a visitor whose consent was recorded.
  • 🧩 Klaro sub-module. Adds a ChatGPT Ads service to Klaro, off by default, and turns the gate on when installed. It passes on only a decision the visitor has saved, so a service that is off by default is not read as a refusal while the notice is on screen, and the status report says when the service is disabled or anonymous visitors cannot use Klaro.
  • 🧩 Commerce sub-module. Sends items_added, checkout_started and order_created with the order total. The click identifiers are kept on the order at every checkout step, so an order paid later can still be matched to the ad.
  • 🧩 Webform sub-module. A handler that measures a submission as a lead, a registration, an appointment, a subscription, a trial or a custom event, with an optional amount. The email, phone and name elements you map are normalized and hashed on the server.
  • 🧩 Conversions API sub-module. Sends orders, registrations and webform events from the server through a cron queue. An order paid off-site hours later, as with Multibanco or MB WAY, is counted when the payment arrives. The key lives in the Key module, and a validation-only test event checks it without recording anything.
  • ⚡ Pages stay cached. A page with the pixel stays in the Dynamic Page Cache. Each visitor's own events and identity arrive through a placeholder rendered on every request.
  • 🔌 A JavaScript API. Drupal.chatgptAds.measure() sends events of your own through the same gate, and consent(), hasConsent() and the chatgptAds:consent event connect any consent manager.

Quick start

composer require drupal/chatgpt_ads
drush en chatgpt_ads
  1. Go to Configuration > Web services > ChatGPT Ads.
  2. Enter the Pixel id from the Conversions tab of the ChatGPT Ads Manager.
  3. Under Where the pixel goes, limit it to some pages or roles if it should not be on every page, and click Save configuration.
  4. Open a page the pixel is on: it loads OpenAI's SDK from bzrcdn.openai.com and sends page_viewed. Reports > Status report shows ChatGPT Ads pixel with your pixel id.

With the Klaro sub-module, the pixel is a service in the visitor's consent dialog, off until they turn it on.

The Webform handler: the event, where it is sent from, and the elements used for matching.

Good to know

  • A community module, not affiliated with OpenAI.
  • What reaches OpenAI from the browser is what its SDK collects once the pixel loads. The Conversions API sends each event with its page address and the click identifier. With the consent gate on, it adds the hashed email, phone and names, the IP address and the user agent only for a visitor whose consent was recorded; for one who refused or has not decided, the event goes without anything about the person. With the gate off, they go for every visitor except one whose refusal was recorded.
  • The server learns the decision from the Klaro cookie. A consent manager connected through the JavaScript API alone, such as EU Cookie Compliance (GDPR Compliance) with the few lines in the README, records nothing on the server, so behind the gate its server events carry no personal identifiers, even for visitors who accepted. To change that, override the chatgpt_ads.consent_reader service with one that reads that manager's cookie.
  • Withdrawing consent stops every further event, but the SDK already loaded stays in the page. Visitors need a way to reopen the consent choice, such as Klaro's floating button, for the withdrawal to be reachable.
  • Server events are sent by cron, one request per event. A refused key suspends the queue and the status report shows the last failure; events older than the seven days the API accepts are not sent.
  • The Conversions API key comes from the Conversions tab of the Ads Manager. The key under Settings > API Keys is a different key and is refused with 401.
  • A site with a Content Security Policy allows https://bzrcdn.openai.com in script-src and connect-src, and https://bzr.openai.com in connect-src and img-src.
  • A visitor who lands from an ad and leaves before deciding on consent is not attributed, because nothing is stored before the decision.
  • contents_viewed, subscription_created and trial_started have no built-in source; send them with the Webform handler or Drupal.chatgptAds.measure().
  • Meta Pixel (Browser & Conversions API) 1.0.0-alpha2 empties the top of the page that other modules add to, which drops the events this module delivers there and, with advanced matching on, keeps the pixel from starting. The fix is on its 1.0.x branch.

Additional requirements

Recommended modules/libraries

  • Consent Audit: reports, from real visitors, every request to a third party made before they decide or after they refuse, which is how to check that the gate holds on your pages.
  • Klaro Cookie & Consent Management: the consent manager Drupal CMS uses. With the Klaro sub-module, it governs both the pixel and the identifiers the server sends.

Similar projects

  • Meta Pixel (Browser & Conversions API) measures Meta ads the same way, with a browser pixel and a server-side Conversions API, deduplicated between the two. It does not measure ChatGPT ads.
  • Asset Injector adds JavaScript to pages by rules, which is enough to paste OpenAI's snippet by hand. The Commerce and Webform events, the server copy and the consent wiring are then the site's own code.
  • Google Tag connects the site to Google Tag Manager, for sites that manage their measurement tags in Google's interface rather than in Drupal.

Community documentation

  • README: every setting, the events and their ids, consent with Klaro and other managers, Commerce, Webform, the Conversions API, caching and the known limitations.
  • OpenAI's documentation of the Measurement Pixel and the Conversions API.

Supporting this module

Developed and maintained by Bloomidea. Bloomidea offers support and custom development for this module.

Drupal 10–11

Ask your assistant about ChatGPT Ads

Check compatibility with your Drupal and PHP version, maintenance and security coverage, from current release data. How it works

Depends on

Dependencies of the latest stable release

Required by

Tracked projects that depend on this one

No tracked projects depend on this one yet.

Activity

Tracked releases
7
Tracked since
Sep 2026
Latest release
3 weeks ago
Releases (12 mo)
7 ▲ from 0
Maintenance
Active

Release Timeline

Releases

Version Type Core PHP Release date
1.0.3 Stable 10–11 Oct 3, 2026
1.0.2 Stable 10–11 Oct 2, 2026
1.0.1 Stable 10–11 Sep 27, 2026
1.0.0 Stable 10–11 Sep 22, 2026
1.0.0-beta2 Pre-release 10–11 Sep 16, 2026
1.0.0-beta1 Pre-release 10–11 Sep 12, 2026
1.0.x-dev Dev 10–11 Sep 12, 2026