An autonomous, multi-agent AI marketing campaign assistant with competitor ad scraping — deployed on Cloudflare's global edge network.
🌐 Live: main.ads-dashboard-4ce.pages.dev
Paste your product description and a competitor keyword. The system will:
- Scrape competitor ads from Meta Ads Library
- Generate 4 specialized AI agent reports in parallel:
- ✍️ Copywriter — Ad copy variations using AIDA/PAS frameworks
- 📊 Analyst — Budget scenarios with CPM, CPC, CTR estimates
- 🎯 Strategist — Buyer personas and creative briefs
- 🔍 Auditor — Competitor gap analysis and counter-offers
- Display results in a clean, expandable dashboard
Total time: ~40 seconds per campaign.
Browser (Cloudflare Pages)
│
│ POST /api/run-campaign
▼
Cloudflare Workers (Hono)
│
├── Apify API ──────────► Meta Ads Library scraping
│
├── Cloudflare Workers AI (Llama 3.1 8B)
│ ├── Copywriter agent
│ ├── Analyst agent
│ ├── Strategist agent
│ └── Auditor agent
│
└── Cloudflare KV ──────► Campaign storage
| Layer | Technology |
|---|---|
| Frontend | React 19, TypeScript, Vite 8, Tailwind CSS v4 |
| Backend | Cloudflare Workers, Hono framework |
| AI | Cloudflare Workers AI (Llama 3.1 8B) |
| Storage | Cloudflare KV |
| Scraping | Apify (Meta Ads Library) |
| Hosting | Cloudflare Pages + Workers |
Open main.ads-dashboard-4ce.pages.dev — no setup needed.
Prerequisites: Node.js v18+, Wrangler CLI
# Clone
git clone https://github.com/ridloabelian/ads-autonomous-cli.git
cd ads-autonomous-cli/ads-autonomous-cli
# Install dependencies
npm install
# Create local env file
echo "APIFY_API_KEY=mock" > .dev.vars
# Start local Worker (backend)
wrangler dev
# In another terminal — start frontend
npm run devOpen http://localhost:5173
Base URL: https://ads-autonomous-api.ridloabelian.workers.dev
GET /api/health
{ "status": "ok", "message": "Ads Autonomous API is running" }POST /api/run-campaign
Content-Type: application/json
{
"productDescription": "Your product or service description",
"competitorKeyword": "competitor keyword for Meta Ads scraping"
}
{
"campaignId": "uuid",
"status": "completed",
"data": {
"results": {
"copywriter": "...",
"analyst": "...",
"strategist": "...",
"auditor": "..."
}
}
}GET /api/campaign-data/:id
GET /api/campaigns
ads-autonomous-cli/
├── src/
│ ├── components/ # React UI components
│ │ ├── CampaignForm.tsx # Input form
│ │ ├── CampaignCard.tsx # Expandable result card
│ │ ├── EmptyState.tsx
│ │ ├── LoadingState.tsx
│ │ └── ErrorState.tsx
│ ├── pages/
│ │ └── Dashboard.tsx # Main dashboard page
│ ├── hooks/
│ │ └── useCampaign.ts # Campaign state management
│ ├── services/
│ │ └── api.ts # API client
│ ├── types/
│ │ └── campaign.ts # TypeScript interfaces
│ ├── utils/
│ │ └── markdown.ts # Markdown parser
│ ├── worker/ # Cloudflare Workers backend
│ │ ├── index.ts # Worker entry point (Hono)
│ │ └── services/
│ │ ├── ai.ts # Cloudflare Workers AI client
│ │ ├── scraper.ts # Apify scraper client
│ │ └── campaign.ts # Campaign orchestrator
│ └── styles/
│ └── globals.css # Tailwind CSS v4
├── prompts/ # AI agent system prompts
│ ├── copywriter.md
│ ├── analyst.md
│ ├── strategist.md
│ └── auditor.md
├── wrangler.toml # Cloudflare Workers config
├── vite.config.ts # Vite build config
└── package.json
# Set secrets
wrangler secret put APIFY_API_KEY
# Deploy
wrangler deploy# Build
npm run build
# Deploy
npx wrangler pages deploy public --project-name=ads-dashboardRunning entirely on free tiers:
| Service | Usage | Cost |
|---|---|---|
| Cloudflare Pages | Unlimited bandwidth | Free |
| Cloudflare Workers | 100k req/day | Free |
| Cloudflare KV | 100k reads/day | Free |
| Cloudflare Workers AI | 10k neurons/day | Free |
| Apify | 5k results/month | Free |
| Total | $0/month |
- CLI pipeline (Playwright + Gemini)
- React web dashboard
- Cloudflare Workers backend
- Cloudflare Workers AI integration
- Deploy to Cloudflare (Pages + Workers)
- Real-time progress tracking (WebSocket)
- Campaign history UI
- Authentication (Cloudflare Access)
- Custom domain
- Apify real scraping integration
- Export to PDF
- Public SaaS launch
ISC License — see package.json for details.