A local Meta Graph API simulator for development. Currently covers Instagram DMs (text + audio), with a structure ready to expand to Messenger and WhatsApp. It replaces graph.instagram.com and api.instagram.com in your dev environment, so you can build and test Instagram DM flows end-to-end without a real Meta app, real IG accounts, or a public webhook URL.
Developing against the real Instagram Messaging API is painful: app review, test users, webhook tunneling, rate limits. This simulator gives you the full loop locally — OAuth, message sending, signed webhooks, echo events — with a UI where you play the role of the end user.
- Fake Graph API endpoints:
/oauth/access_token,/access_token(short→long lived),/me,/v21.0/me/messages(text + audio) - OAuth consent screen at
/oauth/authorize→ redirects withcode/statelike the real flow - Inbox UI (
/inbox/[accountId]): impersonate the end user and send DMs (text + audio via theMediaRecorderAPI) — delivered to your backend as HMAC-SHA256 signed webhooks - Echo events: when your backend sends a DM through
/v21.0/me/messages, the simulator POSTs anis_echo: truewebhook, mirroring real Meta behavior - Admin UI: manage fake IG accounts,
app_id/app_secret, webhook URL and verify token - Zero native deps: JSON file storage
pnpm install
cp .env.example .env.local
pnpm seed # seeds a demo business account
pnpm dev # http://localhost:4000-
Create an account in the admin UI (
http://localhost:4000) with:- the same
app_id/app_secretyour backend uses in dev - your backend's webhook URL (e.g.
http://localhost:8000/instagram-webhook) - your webhook
verify_token
- the same
-
Point your backend's Graph API base URLs at the simulator (e.g.
http://localhost:4000) instead ofhttps://graph.instagram.com. -
Connect an account: your backend's OAuth flow returns an authorization URL pointing at the simulator; the user authorizes on the consent screen and gets redirected back with
?code=...&state=.... -
Open the Inbox (
/inbox/<accountId>), send a message as the end user, and watch it arrive at your backend as a signed webhook. Replies sent by your backend show up in the thread, and echo webhooks are emitted automatically.
- Audio is recorded with the
MediaRecorderAPI (webm) — pipe it to your transcription provider of choice. - Messages sent by the backend (
POST /v21.0/me/messages) are visible in the thread. is_echo: trueis set when the sender is the account itself (mirrors Meta behavior).
Next.js 15 · TypeScript · Tailwind · JSON storage
MIT