|
| 1 | +# SMS Verification with Twilio |
| 2 | + |
| 3 | +A Next.js app demonstrating phone number verification (SMS OTP) using the [Twilio Verify](https://www.twilio.com/docs/verify) API, powered by the emulated Twilio service from `emulate`. |
| 4 | + |
| 5 | +No real SMS is sent. The emulator runs the Verify flow entirely in-memory, so you can complete the verification with the seeded code or inspect state through the inspector UI. |
| 6 | + |
| 7 | +## How it works |
| 8 | + |
| 9 | +1. User enters their phone number on the home page |
| 10 | +2. The server starts a verification via the official Twilio SDK: `verify.v2.services(SID).verifications.create({ to, channel: "sms" })` |
| 11 | +3. The user is redirected to a verification page |
| 12 | +4. The user enters the code and the server checks it: `verify.v2.services(SID).verificationChecks.create({ to, code })` |
| 13 | +5. On success, a session cookie is set and the user lands on the dashboard |
| 14 | + |
| 15 | +The seeded Verify Service accepts the code `123456` for every verification, so the demo can be completed without reading an SMS. |
| 16 | + |
| 17 | +## Pointing the SDK at the emulator |
| 18 | + |
| 19 | +The official Twilio SDK builds absolute URLs against product hosts like `api.twilio.com` and `verify.twilio.com`. `src/lib/twilio.ts` installs a custom request client that rewrites those hosts onto the embedded emulator, which mounts each product under a path prefix: |
| 20 | + |
| 21 | +| Real Twilio URL | Emulator URL | |
| 22 | +| ---------------------------------------- | --------------------------------------------------- | |
| 23 | +| `https://api.twilio.com/2010-04-01/...` | `http://localhost:3000/emulate/twilio/2010-04-01/...` | |
| 24 | +| `https://verify.twilio.com/v2/...` | `http://localhost:3000/emulate/twilio/verify/v2/...` | |
| 25 | +| `https://messaging.twilio.com/v1/...` | `http://localhost:3000/emulate/twilio/messaging/v1/...` | |
| 26 | + |
| 27 | +The base URL is set via `TWILIO_BASE_URL` in `next.config.ts`. |
| 28 | + |
| 29 | +## Getting started |
| 30 | + |
| 31 | +From the repository root: |
| 32 | + |
| 33 | +```bash |
| 34 | +pnpm install |
| 35 | +pnpm --filter twilio-sms-verification dev |
| 36 | +``` |
| 37 | + |
| 38 | +Open [http://localhost:3000](http://localhost:3000). |
| 39 | + |
| 40 | +## Inspecting verifications |
| 41 | + |
| 42 | +### Inspector UI |
| 43 | + |
| 44 | +Visit [http://localhost:3000/emulate/twilio/?tab=verify](http://localhost:3000/emulate/twilio/?tab=verify) to browse Verify services and verifications (including the issued code) in a web interface. |
| 45 | + |
| 46 | +### Fetching the code programmatically |
| 47 | + |
| 48 | +This is useful in tests or agent workflows where you need to complete the flow without a human reading the SMS: |
| 49 | + |
| 50 | +```bash |
| 51 | +# Start a verification through the example API route (sets the pending_verification cookie) |
| 52 | +curl -s -c cookies.txt -X POST http://localhost:3000/api/verification/start \ |
| 53 | + --data-urlencode "phone=+15555550123" |
| 54 | + |
| 55 | +# Fetch the latest local code for that number |
| 56 | +curl -s -G http://localhost:3000/emulate/twilio/_twilio/simulate/verification-code \ |
| 57 | + --data-urlencode "To=+15555550123" \ |
| 58 | + --data-urlencode "ServiceSid=VA00000000000000000000000000000000" \ |
| 59 | + -u "AC00000000000000000000000000000000:twilio_test_auth_token" | jq -r '.code' |
| 60 | +``` |
| 61 | + |
| 62 | +## Seeded defaults |
| 63 | + |
| 64 | +The Twilio emulator boots with a ready-to-use account and Verify Service: |
| 65 | + |
| 66 | +```text |
| 67 | +TWILIO_ACCOUNT_SID=AC00000000000000000000000000000000 |
| 68 | +TWILIO_AUTH_TOKEN=twilio_test_auth_token |
| 69 | +TWILIO_VERIFY_SERVICE_SID=VA00000000000000000000000000000000 |
| 70 | +Seeded Verify code=123456 |
| 71 | +``` |
| 72 | + |
| 73 | +## Project structure |
| 74 | + |
| 75 | +``` |
| 76 | +src/ |
| 77 | + app/ |
| 78 | + page.tsx Phone entry form |
| 79 | + phone-form.tsx Client component for phone input |
| 80 | + actions.ts Server actions (send code, check code, sign out) |
| 81 | + verify/ |
| 82 | + page.tsx Verification page (enter code) |
| 83 | + verify-form.tsx Client component for code input |
| 84 | + dashboard/ |
| 85 | + page.tsx Verified landing page |
| 86 | + api/ |
| 87 | + verification/start/ |
| 88 | + route.ts Programmatic send-code route for tests and agents |
| 89 | + emulate/ |
| 90 | + [...path]/route.ts Embedded emulator (Twilio) |
| 91 | + lib/ |
| 92 | + twilio.ts Twilio SDK client + request client that targets the emulator |
| 93 | + session.ts Cookie-based session helpers |
| 94 | + verification.ts Shared verification starter |
| 95 | +``` |
0 commit comments