For product context, see Product Overview.
This repository is a working Instagram automation product, not a starter template.
Today it includes:
- Google sign-in for operators through Convex Auth
- Workspace-scoped Instagram account connection through Meta OAuth
- Keyword DM automations
- Comment automations
- Story reply automations
- Contacts, conversations, logs, and tracked-link reporting
- Convex schedulers for retries, follow-ups, and delayed work
flowchart LR
O["Operator"] --> N["Next.js dashboard"]
N --> C["Convex queries / mutations / actions"]
I["Instagram user"] --> M["Meta webhooks / Graph API"]
M --> H["Convex HTTP webhook endpoint"]
H --> W["Webhook ingestion + persistence"]
W --> D["Convex tables"]
D --> A["Automation flows"]
A --> S["Delivery queue + Meta send helpers"]
A --> Q["Convex scheduler"]
S --> M
- Renders the operator dashboard under
app/dashboard/** - Handles account-connection callback routes under
app/api/meta/** - Uses Convex React hooks for authenticated reads and writes
- Keeps most UI logic in
components/dashboard/**andlib/*-ui.ts
- Stores all domain state in
convex/schema.ts - Owns workspace/auth/account permissions in
convex/lib/auth.ts - Exposes feature APIs from modules such as
accounts.ts,contacts.ts,dashboard.ts, andautomations/** - Handles webhook verification and ingestion through
convex/http.tsandconvex/meta/webhooks.ts - Schedules follow-ups, retries, and sequence steps
- OAuth token exchange and account sync live in
convex/meta/** - Webhooks are treated as the source of truth for inbound activity
- Outbound delivery uses shared send helpers plus delivery-attempt logging
The main tables in convex/schema.ts are:
| Table | Purpose |
|---|---|
users |
dashboard operators |
workspaces |
account grouping and ownership boundary |
instagramAccounts |
connected Instagram professional accounts |
contacts |
Instagram users who interact with an account |
conversations |
per-contact thread state and message-window timestamps |
messages |
normalized inbound and outbound message history |
automationRules |
keyword and legacy story-reply DM rules |
commentAutomations |
comment-triggered DM workflows |
storyAutomations |
story-reply workflows |
automationRuleSessions |
per-contact rule progression |
commentAutomationSessions |
per-contact comment automation progression |
storyAutomationSessions |
per-contact story automation progression |
deliveryAttempts |
outbound send attempts and Meta failures |
webhookEvents |
parsed inbound webhook items with dedupe keys |
webhookReceipts |
raw webhook POST receipts and parser outcome |
contactAutomationMemberships |
contact-to-automation history for read models |
contactEmails |
emails captured in automations |
sequenceDefinitions / sequenceEnrollments |
delayed follow-up sequences |
tags / contactTags |
automation-applied tagging |
convex/accounts.tsowns selected-account context, connection lifecycle, and workspace-scoped account reads.convex/lib/auth.tsis the main guardrail for workspace access checks.
convex/automations/rules.tsmanages CRUD for keyword DM automations.convex/automations/commentAutomations.tsmanages comment automation CRUD and serialization.convex/automations/storyAutomations.tsmanages story automation CRUD and serialization.convex/automations/*Flow.tsowns runtime session progression after a match occurs.convex/automations/sessionShared.tscontains the shared follow-gate, email extraction, tracked-link, and guardrail helpers used across rule, comment, and story flows.
convex/meta/webhooks.tsis the ingestion entry point.- The ingestion flow is split into:
- webhook receipt parsing and account matching
- contact/conversation persistence
- message recording
- active automation-session continuation
- trigger matching and side effects
- Outbound sends and policy-aware delivery live in
convex/meta/sendHelpers.ts,convex/meta/sendActions.ts, andconvex/meta/deliveryPolicy.ts.
convex/lib/readModels.tscentralizes higher-level contact/conversation serialization for the dashboard.convex/contacts.tsuses account-scoped read paths for the contacts view.convex/dashboard.tspowers the top-level dashboard overview and logs.
- Meta calls the Convex webhook endpoint.
convex/meta/webhooks.tsstores a raw receipt inwebhookReceipts.- Each messaging item is deduped into
webhookEvents. - The matching contact and conversation are upserted.
- The inbound message is recorded in
messages. - Any active automation session for that conversation is advanced first.
- If no active session consumes the interaction, live story automations or rules are matched.
- Matching automations may apply tags, start sessions, and optionally enroll sequences.
- Automation flows decide what message or button batch to send.
- Shared guardrail helpers enforce per-session and per-conversation limits.
- Send helpers enqueue delivery attempts and talk to Meta.
- Tracked links are stored before outbound buttons are rewritten to app redirect URLs.
- Follow-up jobs are scheduled only when a workflow is still eligible.
The automation editors follow the same general pattern:
- route page does account lookup, loading states, and submit/toggle actions
- shared dashboard component renders the form or detail UI
lib/*-ui.tscontains local normalization, validation, and summary helpers
This keeps the page files thin and makes contributor changes safer.
- All reads and writes are workspace-scoped through the selected Instagram account.
- Webhook deliveries must be idempotent.
- Automated sends must respect messaging-window and safety-guardrail rules.
- Public function names and schema shape are treated as stable unless a migration is planned.
app/
dashboard/
api/meta/
components/dashboard/
convex/
accounts.ts
contacts.ts
dashboard.ts
messages.ts
meta/
automations/
lib/
schema.ts
docs/
tests/
The repo uses Vitest for backend and UI helper coverage.
Key test areas today:
- rule, comment, and story automation session flows
- tracked-link routes
- dashboard/account scoping
- contacts inbox rendering and webhook persistence
- multi-account isolation
When changing automation behavior, contributors should verify both npm run lint and npm test.