@vishalgojha/waba-agent
v0.1.0
Published
CLI + agent toolkit for WhatsApp Business Cloud API automation (India SMB focused).
Maintainers
Readme
waba-agent
Production-focused CLI for WhatsApp Business Cloud API automation (India SMB use cases), plus a safe "agent mode" that only executes registered tools (no shell/code exec).
What This Solves (India SMB)
- Webhook setup + local verify server (
hub.challenge+ optional signature check) - Inbound handling: text, images (vision describe), voice notes (Whisper-style transcription)
- Templates: list + send approved templates
- Lead qualification: classify intent, extract fields, draft next reply (EN/HI)
- Outbound scheduling: locally stored schedules +
schedule run - Sellable delivery: per-client config + append-only memory store
Install
From npm (recommended for users):
npm i -g @vishalgojha/waba-agentIf PowerShell blocks npm (execution policy), use:
npm.cmd i -g @vishalgojha/waba-agentFrom source (recommended for contributors):
git clone https://github.com/vishalgojha/waba-agent.git
cd waba-agent
npm.cmd i
npm.cmd linkYou now have waba and waba-agent on your PATH.
Meta permissions you typically need on the token/app:
whatsapp_business_messagingwhatsapp_business_management
Quick Start
- Save auth (token + IDs)
waba auth login --token "<PERMANENT_TOKEN>" --phone-id "<PHONE_NUMBER_ID>" --business-id "<WABA_ID>"- Generate verify token + setup values for Meta
waba webhook setup --url "https://YOUR_PUBLIC_URL"- Run local webhook server (dev)
waba webhook start --port 3000- Simulate an inbound webhook POST
waba webhook test --target "http://localhost:3000/webhook" --text "Hi, price please"- List templates
waba template list- Send a pre-approved template (high risk: outbound costs)
waba send template 9198XXXXXX --template-name "my_template" --language en --params "[\"Vishal\",\"Tomorrow 10 AM\"]"- Agent mode (plan -> confirm -> execute tools)
waba agent run "handle leads for real estate client" --client "acme-realty" --webhook-url "https://YOUR_PUBLIC_URL"CLI Commands (Core)
waba auth login|status|logoutwaba webhook setup|start|serve|validate|testwaba template listwaba template create|preview|submit-for-approval|status|wait|analytics|drafts|sync-draftswaba send template|textwaba agent runwaba memory list|show|forgetwaba schedule add-text|add-template|list|cancel|runwaba clients add|list|switch|billingwaba analytics startwaba metrics --client acme --days 30waba integrate google-sheetswaba integrate status|webhook|hubspot|zohowaba sync leads --to sheetswaba cost estimate|actualwaba optout add|list|check|removewaba campaign create|import|schedule|run|status|stop|listwaba onboard --client acme --wizardwaba report weekly --client acme --email [email protected]waba flow create|add-step|show|list|testwaba payments enable|status|send-link|webhook-handlerwaba deploy render dockerwaba logs tailwaba leads missedwaba export leadswaba export summarywaba autopilot daily
Global flags:
--no-memory: disables writes to~/.waba/context(useful for privacy-sensitive deployments)--debug: verbose logs--json: JSON output where supported
Project Structure
waba-agent/
bin/waba.js
src/index.js
src/commands/
agent.js
auth.js
analytics.js
autopilot.js
campaign.js
clients.js
cost.js
integrate.js
memory.js
onboard.js
optout.js
report.js
schedule.js
send.js
sync.js
template.js
webhook.js
src/lib/
agent/ (planner + executor)
ai/openai.js
analytics.js
campaign-runner.js
campaign-store.js
client-config.js
clients.js
config.js
doctor.js
email.js
graph-error.js
http.js
logger.js
memory.js
duration.js
followup.js
message-parser.js
multimodal-stubs.js
optout-store.js
paths.js
prompt.js
redact.js
report.js
summary.js
schedule-store.js
template-drafts.js
tools.js
tools/ (registry + builtins)
webhook/ (server + signature + parse + payloads)
whatsapp.js
src/server/
analytics.js
webhook.jsAuth + Security Notes
- Token storage:
- By default
waba auth loginstores token in~/.waba/config.json. - For stricter security, prefer environment variables:
WABA_TOKEN,WABA_PHONE_ID,WABA_BUSINESS_ID. - Optional: set
WABA_APP_SECRETto verifyX-Hub-Signature-256on webhook POSTs.
- By default
- Logging:
- No silent failures. Errors are printed with Graph error hints when possible.
- Do not paste customer PII into public issue trackers.
- Privacy:
- Memory is append-only JSONL under
~/.waba/context/<client>/memory.jsonl. - Add your own retention policy per client and local regulations.
- To use a different home directory, set
WABA_HOME.
- Memory is append-only JSONL under
Running The Webhook Server (Recommended)
Local receiver (Express):
waba webhook start --port 3000With ngrok tunnel (for Meta callback testing):
waba webhook start --port 3000 --ngrok --verboseNgrok note: set NGROK_AUTHTOKEN in your environment if required by your ngrok account/plan.
If you have OPENAI_API_KEY set, you can enable smarter lead classification + suggested replies:
waba webhook start --port 3000 --ngrok --verbose --llmSafety defaults:
- No outbound replies unless you pass
--allow-outbound. - Even with
--allow-outbound, outbound steps require terminal confirmation (high-risk). - For production non-interactive servers, add
--allow-high-risk(only after testing).
Client Onboarding Wizard (Sellable)
Fast setup for a new client: writes per-client defaults, creates the lead-qualification flow, and can generate local template drafts.
waba onboard --client acme --wizard --industry real-estateStart webhook server as part of onboarding (blocks; use Ctrl+C to stop):
waba onboard --client acme --wizard --start-webhook --ngrok --verboseDeploy (Docker)
Generate a self-contained Docker deploy folder:
waba deploy render docker --client acme --out deploy-acme --port 3000
cd deploy-acme
copy .env.example .env
docker compose up -d --buildLogs (Support)
Tail memory logs (redacted by default):
waba logs tail --client acme --lines 200
waba logs tail --client acme --follow
waba logs tail --client acme --type inbound_message --followMissed Leads (Ops)
Find leads who messaged but did not get a reply yet (from local memory logs):
waba leads missed --client acme --since 24h --min-age 5mExport (Sales Demo)
Export unique leads to CSV (from local memory + flow state):
waba export leads --client acme --since 7d --out leads.csvExport and push to Google Sheets (requires integrate google-sheets):
waba export leads --client acme --since 7d --to sheetsExport a one-page summary (HTML):
waba export summary --client acme --since 7d --out summary.htmlExport summary as JSON (for automations):
waba --json export summary --client acme --since 7dFollow-Ups (Compliant)
Plan follow-ups (no sends):
waba leads followup --client acme --mode plan --since 7d --min-age 10mSend now (within 24h uses text, outside 24h uses template if provided):
waba leads followup --client acme --mode send --template-name "acme_followup" --template-language en --yesAuto-fill template params from fields (default keys: ["name","client"]):
templates.followup.paramsFromFields(example):["name","client","location","budget"]businessName(optional): if set inclient.json, it will be used for theclientparam
Schedule for later (then run waba schedule run via cron):
waba leads followup --client acme --mode schedule --template-name "acme_followup" --schedule-delay 10m --yesAutopilot (Daily Ops)
One-shot ops runner for small teams: generate a summary HTML + compute missed leads + optionally schedule follow-ups.
Plan-only (safe):
waba autopilot daily --client acme --since 24h --min-age 10mSchedule follow-ups (high risk: outbound billed; will prompt):
waba autopilot daily --client acme --since 24h --min-age 10m --schedule-delay 0m --yesNotes:
- Within 24h window: schedules TEXT follow-ups.
- Outside 24h window: schedules TEMPLATE follow-ups only if
templates.followup.nameis configured (or you pass--template-name). - Run due items with
waba schedule run(cron it).
Google Sheets Sync (Fastest CRM Upsell)
- Print Apps Script template:
waba integrate google-sheets --print-apps-scriptDeploy it as a Web App and copy the URL.
Configure + test:
waba integrate google-sheets --client acme --apps-script-url "<WEB_APP_URL>" --test- Sync leads:
waba sync leads --to sheets --client acme --days 30CRM Integrations (Major Upsell)
Generic webhook sink:
waba integrate webhook --client acme --url "https://your-crm.example.com/waba" --testHubSpot:
waba integrate hubspot --client acme --token "<HUBSPOT_PRIVATE_APP_TOKEN>" --test
waba sync leads --to hubspot --client acme --days 30Zoho (India DC default):
waba integrate zoho --client acme --token "<ZOHO_ACCESS_TOKEN>" --dc in --module Leads --test
waba sync leads --to zoho --client acme --days 30Auto-push from webhook:
- By default, if any CRM integration is configured, the webhook server pushes
lead_qualifiedwhen a flow reachesend. - Control via
~/.waba/context/<client>/client.json:integrations.autoPush.enabled(default: auto if integrations exist)integrations.autoPush.mode:flow_endorevery_inbound
Opt-Out Compliance (Required)
waba optout add 919812345678 --reason "user-request" --client acme
waba optout check 919812345678 --client acme
waba optout list --client acmeOutbound sends and campaigns will refuse to message opted-out numbers.
Broadcast Campaigns (Revenue Feature)
Create + import audience + run (template-only):
waba campaign create "summer-sale" --template sale_offer --language en --client acme
waba campaign import --id <CAMPAIGN_ID> --csv leads.csv
waba campaign run --id <CAMPAIGN_ID> --throttle-ms 400Stop automatically if opt-out rate is too high:
waba campaign run --id <CAMPAIGN_ID> --stop-optout-rate 0.05Weekly Reports (Sales Enabler)
Generate + save HTML report:
waba report weekly --client acmeSend via SMTP (set env vars):
setx WABA_SMTP_HOST "smtp.gmail.com"
setx WABA_SMTP_PORT "587"
setx WABA_SMTP_USER "[email protected]"
setx WABA_SMTP_PASS "app-password"
setx WABA_SMTP_FROM "Reports <[email protected]>"
waba report weekly --client acme --email [email protected]Template Management (Business Critical)
Create a template (submits to Meta for approval):
waba template create --name "followup_1" --category MARKETING --language en_US --body "Hi {{1}}, quick follow up: are you still interested?"Preview (local render of {{1}}, {{2}} placeholders):
waba template preview --name "followup_1" --params "[\"John\"]"Local drafts (for fast client customization):
waba template create --name "followup_1" --category MARKETING --language en_US --body "Hi {{1}}..." --save-draft
waba template draftsCheck status + wait for approval:
waba template status --name "followup_1"
waba template wait --name "followup_1" --timeout 30m --interval 20sCompare local drafts vs remote templates:
waba template sync-drafts --client acmePayments (India) - Razorpay
Enable:
waba payments enable razorpay --client acme --key "<KEY_ID>" --secret "<KEY_SECRET>" --webhook-secret "<WEBHOOK_SECRET>"
waba payments status --client acmeSend a payment link (high risk: outbound):
waba payments send-link --client acme --to 919812345678 --amount 5000 --desc "Consultation fee" Webhook handler (for payment events):
waba payments webhook-handler start --client acme --port 3002Flow Builder (Premium Feature)
Create a lead qualification flow (preset):
waba flow create lead-qualification --client acmeAdd a custom question:
waba flow add-step --client acme --flow lead-qualification --type question --field preferred_time --text "What time works best for you?"Add a condition + handoff (example):
waba flow add-step --client acme --flow lead-qualification --type condition --if "budget >= 10L" --then-step 8 --else-step 9
waba flow add-step --client acme --flow lead-qualification --type handoff --reason high_budget --text "Thanks. Our senior advisor will contact you shortly."Test locally (no WhatsApp send):
waba flow test --client acme --flow lead-qualification --from 919812345678 --text "Hi"Webhook integration:
client.jsonincludesflows.activeandflows.intentMap- When enabled, incoming messages advance the flow and the webhook server proposes the next outbound question/reply.
- Staff notifications: set
handoff.notifyNumberinclient.json. The webhook server can notify staff onflow_end,handoff,unknown_intent, orcall_request.
Security notes:
- This server binds to
127.0.0.1by default. It is not public unless you run--ngrokor bind to0.0.0.0/ deploy it on a server. - Do not expose your webhook endpoint publicly without signature verification (
WABA_APP_SECRET) and basic network controls. - Follow Meta/WhatsApp policies: outbound marketing must use approved templates and consent/opt-outs.
Rate Limits (Reality Check)
Meta enforces rate limits (example: ~200 calls/hour per user). waba-agent retries on 429 + 5xx with exponential backoff, but you should still batch calls and avoid polling.
AI (Optional)
Enable lead classification, image describe, and voice transcription:
setx OPENAI_API_KEY "..."
setx WABA_OPENAI_MODEL "gpt-4o-mini"
setx WABA_OPENAI_VISION_MODEL "gpt-4o-mini"
setx WABA_OPENAI_TRANSCRIBE_MODEL "gpt-4o-mini-transcribe"OpenAI-compatible providers (Groq/OpenRouter) can work by setting:
setx OPENAI_BASE_URL "https://api.groq.com/openai/v1"How To Sell This As A Service (INR 25k-125k setup + retainer)
Deliverable clients understand:
- 1 WhatsApp number connected to Cloud API
- Webhook server on their VPS (or your managed hosting)
- Lead auto-replies + human handoff rules
- Templates prepared and tracked for approval
- Daily "missed lead" follow-up schedule
- Weekly report: leads, response time, conversion stages
Fiverr/Upwork gig positioning:
- "WhatsApp Business API automation for Indian SMBs (leads, follow-ups, appointment booking)"
- "Meta WhatsApp Cloud API setup + webhooks + AI agent replies"
Upsells:
- CRM webhook integration (Sheets, Zoho, HubSpot, custom)
- Multilingual replies (EN/HI/MR/TA)
- Message scheduling campaigns (template-only, compliant)
- Analytics dashboard (Looker / CSV exports)
Compliance + Costs (Read This)
- Outbound marketing requires pre-approved templates.
- WhatsApp Cloud API is per-message billed (India rates change; rough ballpark: utility ~INR 0.11, marketing ~INR 0.78). This toolkit warns about costs but does not calculate pricing.
- Follow Meta platform policies and WhatsApp commerce/messaging rules. Add client-specific disclaimers and opt-outs.
Scheduling (Safe)
Text schedules will only send if the recipient is inside the 24-hour customer-service window; otherwise they fail closed. For follow-ups outside 24h, schedule a template.
waba schedule add-text 919812345678 --at "2026-02-16T10:00:00+05:30" --body "Hi, checking in..."
waba schedule add-template 919812345678 --at "2026-02-16T10:00:00+05:30" --template-name "acme_followup" --language en --params "[\"Vishal\",\"ACME\"]"
waba schedule run