Playground features

Call tracking for ad campaigns

Twilio call tracking + dynamic number insertion

Tells you which advert produced which phone call, and records the ones nobody answered. For a business whose customers ring rather than fill in a form.

Three colored billboards each running a matching cord down to one telephone, with one cord dimmed and its receiver lying off the cradle

A feature of the Playground

This is a feature of the Vibe Coder Playground. It runs inside the Playground, with its audit record and its caveats beside it.

Download the Playground See pricing

The mistake it removes

Three ways this is normally got wrong, all of them expensive. (1) No webhook signature validation: the URL is public, and an unvalidated voice handler will dial whatever a stranger POSTs to it, on your account. (2) Swapping the number everywhere: local ranking depends on the name/address/phone matching your Google Business Profile and every directory, so a footer swap damages the thing being measured. (3) Recording without consent: several states, Florida and California among them, require every party to agree.

What is already handled

Each of these was checked by running the code, not by reading it.

What you still have to do

The feature cannot own your secrets, your host or your legal obligations. This is the part it deliberately does not claim.

What lands in your project

php

  • php/twilio-signature.php
  • php/twilio-number.php
  • php/twilio-voice.php
  • php/twilio-status.php

For shared hosting — cPanel, GoDaddy, anything with PHP 8 and no Node. Upload all four beside the site, set the constants at the top of each handler, and point the Twilio number at the public URLs. twilio-signature.php is required by both handlers and is the security boundary; twilio-number.php holds the phone-number grammar, the self-forward decision AND the value that gets dialed, and twilio-voice.php requires it — do not deploy a handler without either. The grammar lives in its own file so a test can execute it: until ph105tsk37 the decision was buried in the handler beside header() and $_POST, nothing could run it, and this stack quietly kept a defect the Node stack had fixed. No composer, no dependencies, stdlib only. ext-intl is OPTIONAL: with it, full-width digits are normalized and recognized; without it they are refused as a format error, which is the fail-closed direction.

node

  • node/twilio-voice.js

Serverless-style default export (Vercel-shaped). ESM, because a CommonJS module.exports in a "type": "module" repo parses cleanly and exports nothing. Config from the environment. signatureOk is exported separately so it can be tested without a live call. No dependencies — the signature is node:crypto, not the twilio SDK.

vanilla

  • vanilla/dni.js

Dynamic number insertion. Swaps only elements carrying data-dni, so anything you forget to mark keeps the real number — the safe direction. Source is decided once per session, because document.referrer is empty by the time a visitor on their fourth page decides to call. A visit that arrives with NO referrer is bucketed `no-referrer`, never `direct`: an empty field is what a messaging app, an email client, a rel="noreferrer" link, a strict Referrer-Policy and an https-to-http hop all produce, and only one of them is somebody typing your name. Map that bucket to a number and dark-social callers become countable instead of invisible.

What you supply

Get it

Download the Playground See pricing

A feature of the Vibe Coder Playground.

Questions

Is Call tracking for ad campaigns audited?
No. No full audit has been run against this block yet, which is not the same as a pass. What is verified about it is listed on this page, and what is not is listed beside it.
What do I still have to do myself?
Serve the webhook over HTTPS at the EXACT url configured in the Twilio console, and keep TWILIO_AUTH_TOKEN in your host's environment. Signature validation is shipped and tested both directions, but it validates against the url you configure — rebuilding that url from request headers hands an attacker control of the signed string.
How do I get this?
It is a feature of the Vibe Coder Playground. Download the Playground, and see the pricing page for what each plan includes.

All Playground features · Free code blocks · Learn to build from zero · The coding guide