The open-source alternative to ManyChat for Instagram β on a hosted Next.js + Convex stack.
Automate comment replies, story-reply funnels, and keyword DMs from a dashboard you own. Deploy your own in minutes, no SaaS fees.
Nudgra is an open alternative to ManyChat for Instagram. It focuses on the automations most operators actually use: connect Instagram accounts, receive messages and comments through Meta webhooks, send replies and follow-up sequences, and manage everything from a clean dashboard.
This repository is the Cloud build β it runs on Next.js for the dashboard and Convex Cloud for backend state, auth, scheduling, and Meta webhooks. You deploy it to your own Vercel + Convex project, so there's no Postgres, no webhook server, and no background-job runner to operate yourself.
Want to run the database and backend yourself? Use Nudgra OSS instead β a separate fully self-hosted TanStack Start + Postgres build of the same product.
π Prefer a friendlier, step-by-step walkthrough? The hosted docs at docs.nudgra.com mirror this guide in a more readable format.
π‘ You can also hand this README to a coding agent β Claude Code, Codex, Cursor, or similar β and ask it to walk you through setup. That works especially well for Convex environment variables, Google OAuth, Meta dashboard setup, and reading deployment logs.
Questions or stuck? DM @Maikoke5.
| π¬ Comment automations | Auto-reply to comments on any post, specific posts/reels, or your next post when a comment matches your keywords β then send a DM with tracked link buttons. |
| π Story-reply funnels | Turn replies (or reactions) to any story, or one specific story, into the entry point of a follow-up sequence. |
| β‘ Keyword DM rules | Respond automatically when someone DMs a keyword. Set the rule once and Nudgra handles the rest. |
| π Follow-up sequences | Multi-step, delayed DM sequences delivered reliably on Convex scheduled functions. |
| π₯ Unified inbox | Read and reply to Instagram conversations from one dashboard. |
| π₯ Contacts & tags | A lightweight contact record per person who engages, with automation-applied tags. |
| π Tracked links & CTR | Per-button click tracking so you can see which automations convert. |
| πͺͺ Multi-account | Connect and switch between multiple Instagram professional accounts. |
| π Logs & analytics | Run counts, CTR, and delivery logs for every automation. |
| π‘οΈ Safety guardrails | Automations respect messaging-window and per-conversation limits, so you stay within Meta's rules. |
- Connect an Instagram professional account through Meta's Instagram Business Login β Nudgra runs the OAuth flow and stores account tokens in Convex itself.
- Build comment, story-reply, or keyword-DM automations in the dashboard.
- React β Meta webhooks hit your Convex HTTP endpoint, Nudgra matches triggers, and sends replies, DMs, and link buttons.
- Follow up β delayed sequences, token refreshes, and retries run on the Convex scheduler.
- Measure β watch runs, CTR, conversations, and logs from your dashboard.
- Nudgra automates Instagram professional accounts (business or creator) only.
- New-follower welcome automations are not possible. Instagram exposes no public new-follower webhook trigger, so welcome-DM-on-follow cannot be set live. Use a comment, story-reply, or keyword-DM automation instead.
- Your Meta app must be published for webhooks to work, and each Instagram account must accept its tester invite (see Meta / Instagram setup).
- Meta webhooks point to the Convex site URL, not the Next.js app URL. In this repo the webhook route is defined in
convex/http.tsat/meta/webhooks.
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (React 19) |
| Backend & data | Convex |
| Auth | Convex Auth (Google sign-in) |
| Scheduling & jobs | Convex scheduled functions |
| Webhooks | Convex HTTP Actions |
| Styling | Tailwind CSS v4 + shadcn/ui |
- What you need
- Important URLs
- Environment variables
- π» Local development
- π Production deployment (Vercel + Convex)
- Google OAuth setup
- π· Meta / Instagram setup
- Updating a deployment
- Backup & data
- Troubleshooting
- Useful commands
- Project docs
- Contributing, security & license
The setup has a few moving parts because Google OAuth, Instagram OAuth, Meta webhooks, and Convex all need to agree with each other. Expect about 15 minutes if you already have a Convex project and an app domain ready.
- A Google account for dashboard sign-in.
- A Convex account for the backend deployment.
- A Meta Developer account.
- An Instagram professional account (business or creator) that you want to automate.
- For production: Vercel and a public domain or subdomain for the Next.js app.
- For local development: Node.js 24 or newer, Git, and optionally a public tunnel URL for Meta callback testing.
Replace https://your-app-domain.com with your real app domain, for example https://cloud.nudgra.example.com.
Replace https://your-convex-site.convex.site with the Convex HTTP Actions URL for your deployment. In Convex, the site URL usually ends in .convex.site.
| Purpose | URL |
|---|---|
| App | https://your-app-domain.com |
| Google OAuth redirect URI | https://your-convex-site.convex.site/api/auth/callback/google |
| Meta / Instagram OAuth redirect URI | https://your-app-domain.com/api/meta/callback |
| Meta webhook callback URL | https://your-convex-site.convex.site/meta/webhooks |
| Convex dashboard | npx convex dashboard |
β οΈ Two URLs commonly trip people up: the Google OAuth redirect and the Meta webhook callback must both point to the Convex site URL (.convex.site), not the Next.js app URL. The Meta OAuth redirect is the one exception β it points to the app domain.
Copy .env.example to .env.local for local work:
cp .env.example .env.localIn Windows PowerShell:
Copy-Item .env.example .env.localLocal values usually look like this:
NEXT_PUBLIC_CONVEX_URL=
NEXT_PUBLIC_CONVEX_SITE_URL=
SITE_URL=http://localhost:3000
CONVEX_DEPLOY_KEY=
AUTH_GOOGLE_ID=
AUTH_GOOGLE_SECRET=
NUDGRA_ALLOWED_EMAILS=you@example.com
META_APP_ID=
META_APP_SECRET=
META_VERIFY_TOKEN=Production values are split between your Next.js host (Vercel) and Convex.
Set these on Vercel:
| Variable | Purpose |
|---|---|
CONVEX_DEPLOY_KEY |
Lets npx convex deploy --cmd "npm run build" deploy the Convex backend during hosted builds |
SITE_URL |
Public app origin used by Next.js routes, Meta OAuth callbacks, and tracked links |
META_APP_ID |
Meta app ID used by the Next.js connect route |
META_APP_SECRET |
Meta app secret used by the Next.js Meta routes |
META_VERIFY_TOKEN |
Verify-token presence check for the Meta connect flow |
Set these on the Convex production deployment:
| Variable | Purpose |
|---|---|
AUTH_GOOGLE_ID |
Google sign-in client ID |
AUTH_GOOGLE_SECRET |
Google sign-in client secret |
NUDGRA_ALLOWED_EMAILS |
Comma-separated Google emails allowed to access this private deployment |
META_APP_ID |
Meta app ID |
META_APP_SECRET |
Meta app secret |
META_VERIFY_TOKEN |
Meta webhook verification token |
SITE_URL |
Public app origin used by tracked links and callback-aware backend flows |
JWT_PRIVATE_KEY |
Convex Auth signing key |
JWKS |
Convex Auth JWKS document |
Generate random tokens with OpenSSL:
openssl rand -hex 32Or generate one with Node:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Use a generated value for META_VERIFY_TOKEN.
Important
JWT_PRIVATE_KEYandJWKSare required by Convex Auth. Generate them withnpx @convex-dev/auth --prodβ do not handcraft them unless you are following the Convex Auth manual setup docs.NEXT_PUBLIC_CONVEX_URLandNEXT_PUBLIC_CONVEX_SITE_URLare written bynpx convex devlocally and injected bynpx convex deploy --cmd "npm run build"during production builds.NUDGRA_ALLOWED_EMAILSis required. If your Google email is not in the allowlist, sign-in is rejected.- Keep
SITE_URLexact. If your app is deployed athttps://cloud.example.com, do not use a different Vercel preview URL or localhost value in production.
This path is best for dashboard development and UI testing. For a complete Instagram webhook flow, use a deployed Convex site URL and a public app domain or tunnel, because Meta cannot call localhost.
Install:
- Git
- Node.js 24 or newer
- A Convex account
In a Unix shell (macOS, Linux, or Git Bash):
git clone https://github.com/MaikoCode/nudgra-cloud.git nudgra-cloud
cd nudgra-cloud
npm install
cp .env.example .env.localIn Windows PowerShell:
git clone https://github.com/MaikoCode/nudgra-cloud.git nudgra-cloud
cd nudgra-cloud
npm install
Copy-Item .env.example .env.localAt minimum, set:
SITE_URL=http://localhost:3000
NUDGRA_ALLOWED_EMAILS=your-google-email@gmail.comGoogle OAuth is required for normal sign-in. Create Google OAuth credentials using the Google section below, then set:
AUTH_GOOGLE_ID=your-google-client-id
AUTH_GOOGLE_SECRET=your-google-client-secretFor local Google OAuth, use your local Convex site URL as the redirect URI, not the Next.js app URL. npx convex dev will print or write the Convex values:
NEXT_PUBLIC_CONVEX_URL=https://your-dev-deployment.convex.cloud
NEXT_PUBLIC_CONVEX_SITE_URL=https://your-dev-deployment.convex.siteThen configure Google with:
Authorized JavaScript origin:
http://localhost:3000
Authorized redirect URI:
https://your-dev-deployment.convex.site/api/auth/callback/google
For local Meta OAuth or tracked links, set SITE_URL to a public tunnel URL instead of http://localhost:3000, for example:
SITE_URL=https://your-tunnel.example.comnpm run devOpen http://localhost:3000.
Notes:
- The
predevflow initializes Convex, runs the Convex Auth setup helper once, and opens the Convex dashboard. npm run devruns Next.js andconvex devtogether.- If the Convex Auth setup helper prompts for
SITE_URL, use the local or tunnel URL you configured.
Useful local commands:
npm run lint
npm test
npx convex dashboard
npx convex env listThis is the recommended hosted setup:
- Next.js app on Vercel.
- Convex backend on Convex Cloud.
- Google OAuth for sign-in.
- A Meta app for Instagram OAuth and webhooks.
Want the database and backend fully self-hosted instead? Use Nudgra OSS.
Pick the final public URL for the Next.js app, for example https://your-app-domain.com, and use that exact value everywhere:
- Next.js host
SITE_URL - Convex production
SITE_URL - Meta OAuth redirect URI
- Google authorized JavaScript origin
- Any tracked-link testing
If the domain changes later, update all platform settings and redeploy.
- Create or open your Convex project.
- Create a production deployment in the Convex dashboard.
- Generate a production deploy key from the Convex dashboard.
- Keep the production deployment's
.convex.siteURL handy β you'll need it for Google and Meta.
You can also open the dashboard from the project root:
npx convex dashboardRun this from the project root:
npx @convex-dev/auth --prodWhen prompted:
- set
SITE_URLto your public app domain, for examplehttps://your-app-domain.com - let the tool generate and store
JWT_PRIVATE_KEYandJWKS
This prepares the production Convex deployment for Google sign-in and redirects back to your app after auth.
Set the email allowlist and public app origin:
npx convex env set --prod NUDGRA_ALLOWED_EMAILS your-google-email@gmail.com
npx convex env set --prod SITE_URL https://your-app-domain.comAfter Google and Meta are configured, also set:
npx convex env set --prod AUTH_GOOGLE_ID your-google-client-id
npx convex env set --prod AUTH_GOOGLE_SECRET your-google-client-secret
npx convex env set --prod META_APP_ID your-instagram-app-id
npx convex env set --prod META_APP_SECRET your-instagram-app-secret
npx convex env set --prod META_VERIFY_TOKEN your-random-verify-tokenYou can set the same values in the Convex dashboard instead of the CLI.
-
Import this repository into Vercel.
-
Set the install command to
npm install. -
Set the build command to:
npx convex deploy --cmd "npm run build" -
Set these Vercel environment variables:
CONVEX_DEPLOY_KEY=your-convex-production-deploy-key SITE_URL=https://your-app-domain.com META_APP_ID=your-instagram-app-id META_APP_SECRET=your-instagram-app-secret META_VERIFY_TOKEN=your-random-verify-token
-
Attach your production domain in Vercel.
-
Redeploy after the domain and environment variables are final.
Why the build command matters β it:
- deploys the Convex backend during the build
- typechecks and bundles Convex functions
- injects the correct Convex deployment URLs into the Next.js build
After the first deployment:
- Open
https://your-app-domain.com. - Sign in with a Google account listed in
NUDGRA_ALLOWED_EMAILS. - Open
/dashboard/accountand connect an Instagram professional account. - Confirm the account appears as connected.
- Send a real test DM, comment, or story reply.
- Verify that contacts, conversations, automations, and logs update in the dashboard.
- Verify that tracked links resolve through your app domain.
- Verify that webhook activity appears in logs.
Go to the Google Cloud Console and create OAuth credentials for a web application.
For production, set:
Authorized JavaScript origin:
https://your-app-domain.com
Authorized redirect URI:
https://your-convex-site.convex.site/api/auth/callback/google
For local development, set:
Authorized JavaScript origin:
http://localhost:3000
Authorized redirect URI:
https://your-dev-deployment.convex.site/api/auth/callback/google
The redirect URI uses the Convex site URL, not the app domain. This repo uses Convex Auth routes hosted on the Convex site.
If Google asks for an authorized domain, use the root domain, for example example.com.
Copy the client ID and secret into Convex:
npx convex env set --prod AUTH_GOOGLE_ID your-google-client-id
npx convex env set --prod AUTH_GOOGLE_SECRET your-google-client-secretFor local development, put the same values in .env.local or set them on your Convex dev deployment:
AUTH_GOOGLE_ID=your-google-client-id
AUTH_GOOGLE_SECRET=your-google-client-secretRestart local development after changing auth values:
npm run devRedeploy production after changing hosted values:
npx convex deploy --cmd "npm run build"Meta's dashboard changes often, so labels may move slightly. The important pieces stay the same: create a Meta app, add Instagram testers, publish the app, configure webhooks, configure Instagram business login, copy the Instagram app credentials into Convex and your Next.js host, and connect the account from Nudgra.
Go to https://developers.facebook.com/apps/, sign up if needed, then click Create App.
During setup:
- Give the app a name.
- For the use case, select Manage messaging & content on Instagram.
- Finish the app creation flow.
Inside your Meta app dashboard:
- Go to App roles.
- Click Roles (not Test users).
- Click Add People.
- In the modal, choose Instagram Tester.
- Add the Instagram accounts you want to automate with Nudgra.
Then each Instagram account must accept the invite:
- Open Instagram in a desktop browser.
- Go to Settings β Website permissions β Apps and Websites β Test invites.
- Accept the invite.
The Website permissions area may not appear on mobile, so use Instagram on a computer.
In the Meta app dashboard:
- Go to Use cases.
- Open the Instagram use case.
- Go to API setup with Instagram login.
- In Add required messaging permissions, add the permissions Nudgra needs:
instagram_business_basic
instagram_business_manage_messages
instagram_business_manage_comments
You do not need to manually generate access tokens in Meta. Nudgra performs the Instagram login flow and stores account tokens in Convex.
Webhooks require the app to be published for real delivery. For testing your own connected Instagram accounts, you can publish with basic app details.
- Go to Publish.
- Add a privacy policy URL.
- Fill any required basic fields.
- Publish the app.
For testing, a simple public privacy policy page is enough β for example, a published Notion page.
Return to your app at https://developers.facebook.com/apps/, then:
- Go to Use cases.
- Click Customize or open the Instagram use case.
- Open API setup with Instagram login.
- Find and copy the Instagram app ID.
- Reveal and copy the Instagram app secret.
Put them on the Convex production deployment:
npx convex env set --prod META_APP_ID your-instagram-app-id
npx convex env set --prod META_APP_SECRET your-instagram-app-secret
npx convex env set --prod META_VERIFY_TOKEN your-random-webhook-verify-tokenPut the same values on the Next.js host (Vercel):
META_APP_ID=your-instagram-app-id
META_APP_SECRET=your-instagram-app-secret
META_VERIFY_TOKEN=your-random-webhook-verify-tokenGenerate a verify token yourself β any strong random string works:
openssl rand -hex 32
# or
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Redeploy or restart after editing environment variables.
In API setup with Instagram login, open Configure webhooks and set:
Callback URL: https://your-convex-site.convex.site/meta/webhooks
Verify token: same value as META_VERIFY_TOKEN
Click Verify and save, then subscribe to these webhook fields:
messages
messaging_postbacks
comments
The webhook callback must point to the Convex site URL, not the Next.js app URL. The app expects Instagram webhook events through the Convex HTTP endpoint.
In API setup with Instagram login, open Set up Instagram business login and set:
Redirect URL: https://your-app-domain.com/api/meta/callback
Save the redirect URL.
Open your deployment at https://your-app-domain.com and sign in with the Google account in NUDGRA_ALLOWED_EMAILS. Then:
- Go to Dashboard β Account.
- Click Add account.
- Complete the Instagram permission screen.
- Allow profile/media access, comment access, and message access.
- Confirm the account appears as connected and active.
For Vercel, push to the branch connected to the project and let the build run. The build command redeploys the Convex backend at the same time:
npx convex deploy --cmd "npm run build"Nudgra Cloud stores app data in Convex. Use the Convex dashboard and Convex CLI for data inspection, exports, and operational recovery.
Keep a private copy of production environment variables β you'll need them if you recreate the deployment or move the app domain.
Important secrets:
JWT_PRIVATE_KEYJWKSAUTH_GOOGLE_SECRETMETA_APP_SECRETMETA_VERIFY_TOKENCONVEX_DEPLOY_KEY
Google sign-in says the account is not allowed
Check that the exact Google email is listed in Convex:
npx convex env list --prodSet or update the allowlist:
npx convex env set --prod NUDGRA_ALLOWED_EMAILS you@example.com,backup@example.comFor local development, also check .env.local.
Google login redirects to the wrong URL
Check:
SITE_URL=https://your-app-domain.comVerify that the Google OAuth redirect URI uses the Convex site URL:
https://your-convex-site.convex.site/api/auth/callback/google
Do not use https://your-app-domain.com/api/auth/callback/google. This repo uses Convex Auth routes on the Convex site URL.
Meta webhook verification fails
Check that:
META_VERIFY_TOKENin Convex exactly matches the token entered in Meta.https://your-convex-site.convex.site/meta/webhooksis reachable publicly.- Convex has been redeployed after code changes.
- The Meta app is published when testing real delivery.
- The subscribed webhook fields are
messages,messaging_postbacks, andcomments.
npx convex logs --prod
npx convex env list --prodA plain browser request to the webhook URL may return 403 because it is missing Meta's verification query parameters. That still proves the route is reachable β Meta's Verify and save button is the real webhook verification.
Meta webhooks are verified but no events appear
Check that:
- The Meta webhook callback points to the Convex URL, not the app URL.
- The connected Instagram account accepted the tester invite during development.
- The app has the required Instagram permissions.
- The app is in Live mode for real users.
- The Instagram account is professional (business or creator).
- The connected account still appears active in
/dashboard/account.
Instagram account does not appear during connection
Check that:
- The Instagram account accepted the tester invite.
- The invite was accepted from Instagram on desktop.
- The app has the required Instagram permissions.
- The Instagram account is professional (business or creator).
- You are logged into the correct Instagram account when authorizing.
SITE_URLmatches the Meta redirect URL exactly.
The connect button returns a Meta config warning
Set these values on both Convex production and the Next.js host, then redeploy or restart:
META_APP_ID=your-instagram-app-id
META_APP_SECRET=your-instagram-app-secret
META_VERIFY_TOKEN=your-random-webhook-verify-tokenTracked links use the wrong host
Check Convex production:
npx convex env get --prod SITE_URLSet it to the public app domain and redeploy:
npx convex env set --prod SITE_URL https://your-app-domain.comnpm run dev # Next.js + convex dev together
npm run build
npm run start
npm run lint
npm test
npx convex dev
npx convex deploy --cmd "npm run build"
npx convex dashboard
npx convex logs --prod
npx convex env list --prod
npx @convex-dev/auth --prod- Design
- Product Overview
- Technical Architecture
- Meta Setup Notes
- Contributing
- Security Policy
- Trademark Policy
- Contributing β see CONTRIBUTING.md. Bug fixes, tests, docs, and UI polish are all welcome.
- Security β please report vulnerabilities privately. See SECURITY.md.
- License β MIT. The MIT license does not grant rights to the
Nudgraname, logo, or branding. If you fork or reuse the code for your own product, rename it and replace the branding; see TRADEMARKS.md.
- Convex hosting docs
- Convex CLI deploy docs
- Convex Auth manual setup
- Convex Auth Google OAuth setup
- Google OAuth client rules
If Nudgra is useful to you, consider starring the repo β β it genuinely helps.
Built with Next.js Β· Convex Β· Convex Auth Β· Tailwind CSS Β· shadcn/ui