CampaignIO is a full‑stack app that helps you discover relevant Instagram creators from a product idea or hashtag and manage outreach in one place. It streams recommendations in real‑time (so you don't wait for long scrapes), preserves your search history, and gives you a workspace with Timeline, Notes, Events, Tasks, Deals, Campaigns, Messages, History, and Todo.
I built this to feel fast and forgiving: searches start immediately, results show up incrementally, and you can click around without breaking a long‑running discovery job in the background.
- Real‑time, incremental influencer recommendations (no long blocking waits)
- Background discovery continues even if you navigate away
- Search History saved to both client cache and MongoDB for reliability
- Dynamic profile pages with quick links to social profiles
- Full CRUD on profile workspace tabs (Timeline, Notes, Events, Tasks, Deals, Campaigns, Messages, History, Todo)
- Modern dark/light themes tuned for low glare
- You enter a product idea and hashtags on the Home page.
- The app kicks off a background discovery job. A lightweight Node worker (using Puppeteer + stealth) extracts Instagram usernames from permalinks and feeds them back one by one.
- For each username found, the backend fetches public data and streams results to the frontend incrementally. You see the first suggestion almost immediately, while the rest keep coming in.
- Results are written to MongoDB and also cached client‑side. That means:
- If you reload or move around, you won't lose context.
- If you return later, your History is still there.
- The Profile workspace gives you a CRM‑like place to organize outreach: you can create, edit, and delete entries across Timeline, Notes, Events, Tasks, Deals, Campaigns, Messages, History, and Todo.
app/– Next.js 13+ frontend (App Router) with pages for Home and Profilebackend/– Flask backend with async discovery worker (spawns Node script)backend/node_username_extractor.js– Puppeteer worker that extracts IG usernames from permalinks (stealth)backend/database.py– Centralized MongoDB connection and helpersbackend/blueprints/history.py– Search history storage & accessapp/api/...– Next.js API routes that proxy to the backend for the frontendapp/home/user/profile/page.tsx– Workspace UI (Timeline/Notes/Events/...)app/profile/[username]/page.tsx– Dynamic influencer profilesglobals.css– Theme tokens for light/dark
- Frontend: Next.js (React), TypeScript
- Backend: Flask (Python)
- Worker: Node.js + Puppeteer (stealth plugin)
- Database: MongoDB Atlas
- Auth: Email/Password + Google OAuth (stored in MongoDB)
You do NOT need to paste any private keys into this README. Put them into the backend config.json (explained below). Here’s what to obtain and where:
-
MongoDB Atlas
- Create a free cluster (M0) at MongoDB Atlas.
- Create a database user (read/write).
- Allow network access for your deploy region or 0.0.0.0/0 for quick start.
- Copy your connection string (mongodb+srv://...)
-
Instagram/Meta (for reading public creator data)
- Use a long‑lived access token / system user token with appropriate permissions for the Instagram Graph API.
- Keep your
ig_user_idand long‑lived access token handy.
-
Google OAuth (optional login)
- Create a Web OAuth client in Google Cloud Console.
- Add authorized redirect URI pointing to your backend’s
/google-callbackpath. - Download the JSON and keep it ready.
All sensitive values live in backend/config.json (not committed). Example keys the app expects:
mongodb_uri– Your MongoDB Atlas connection stringmongodb_db– Database name (e.g., "CampaignIO_DB")app_secret_key– Any strong random string for Flask sessionsig_user_id– Instagram Business/Creator user idinstagram_access_token(orlong_access_token) – Long‑lived tokengoogle_client_config– The Google OAuth JSON payload (with correct redirect URIs)
In production (Render), add this as a Secret File at the path backend/config.json.
- Install frontend deps
cd "v0 integrated"
npm install- Backend Python deps
cd backend
pip install -r requirements.txt- Provide secrets
- Create
v0 integrated/backend/config.jsonwith your local credentials (see Configuration).
- Run locally
- Backend:
python app.py(default port 8000) - Frontend: from
v0 integrated/,npm run dev(default port 3000)
The frontend proxies through its Next.js API routes to talk to the backend. Discovery jobs run asynchronously in the backend and stream results as they’re processed.
This repo includes a top‑level Dockerfile and start script inside v0 integrated/ so Render can run both backend and frontend in one service.
Steps:
- Push to GitHub.
- In Render → New → Web Service → connect your repo.
- Set root directory to
v0 integratedand choose Docker (Render auto‑detects the Dockerfile). - Add a Secret File at
backend/config.jsonwith your production credentials. - Deploy.
Render provides the public URL for your app (frontend) and runs the Flask backend inside the same container. The backend listens on port 8000 internally; the Next.js server listens on $PORT (Render sets it).
- You search for a hashtag → frontend asks backend to start discovery.
- Backend launches the Node worker to extract usernames from permalinks (stealth Puppeteer).
- As usernames arrive, backend fetches creator info and updates the job state.
- Frontend polls job status via its API routes and renders incoming creators immediately.
- Results are saved to MongoDB and also cached client‑side (for snappy UX and resilience).
- You can navigate to profile pages or other tabs; the background job keeps running.
- Dark theme uses deep slate/indigo + cyan accents with clear, darkened container edges.
- Light theme is multi‑accent with low glare and stronger borders for definition.
- Layout remains unchanged; only tokens are tuned for readability.
- "It takes a while to show results": first result should pop in quickly as soon as a username is found. Cold starts (especially on free tiers) can add a few seconds.
- "History looks empty": ensure both client cache and MongoDB are accessible; check that the backend has valid credentials and can reach Atlas.
- "Auth failing locally": if you use Google OAuth, confirm the local redirect URI matches in Google Cloud and in your
config.json. - "Puppeteer errors on Render": the container installs Chromium dependencies. If sandbox issues appear, the worker already uses
--no-sandbox/stealth.
I intentionally haven’t listed internal API endpoints. You don’t need them to run the app or deploy it. The frontend already talks to the backend via proxy routes, and the backend exposes everything the UI needs.
If you want to explore or extend the APIs later, check the backend blueprints and the Next.js API route code.
- Add new tabs or fields in the Profile workspace as needed.
- Extend the discovery worker for other platforms (TikTok, YouTube) by following the same async pattern.
- Improve ranking/quality by plugging in your own heuristics or ML.
Private project. All rights reserved.
