Automates WhatsApp conversations for local businesses — handling replies, booking inquiries, lead capture, and intelligent follow-ups without requiring 24/7 human attention. Designed for gyms, restaurants, salons, clinics, and service-based businesses in South Africa.
| Requirement | Version/Detail |
|---|---|
| --- | --- |
| OpenClaw | v2.4+ |
| Node.js | v18+ |
| WhatsApp Business API (Meta) | Approved business account |
| Meta Developer App | With WhatsApp product configured |
| Python 3 | v3.10+ (for NLP pipeline) |
wacli CLI | Installed on host |
| ngrok or static IP | For webhook callback |
cp -r streams/01_ClawHub_Skills/01_WhatsApp_Business_AI_Assistant/* ~/.openclaw/skills/
cd ~/.openclaw/skills/whatsapp-business-ai
npm install
pip install -r requirements.txt
Create ~/.openclaw/skills/whatsapp-business-ai/.env:
WHATSAPP_PHONE_NUMBER_ID=your_phone_number_id
WHATSAPP_ACCESS_TOKEN=your_permanent_token
WHATSAPP_VERIFY_TOKEN=your_webhook_verify_token
WHATSAPP_BUSINESS_ACCOUNT_ID=your_business_account_id
BUSINESS_HOURS_TIMEZONE=Africa/Johannesburg
DEFAULT_LANGUAGE=en
NLP_MODEL_PATH=./models/za_intent_classifier
LEAD_DB_PATH=./data/leads.db
BOOKING_CALENDAR_ID=your_google_calendar_id
# Verify wacli is available
which wacli || brew install wacli
wacli --configure
# Start webhook receiver (uses ngrok for dev)
./scripts/start-webhook.sh
# Register webhook with Meta
curl -X POST "https://graph.facebook.com/v18.0/$WHATSAPP_PHONE_NUMBER_ID/subscriptions" \
-H "Authorization: Bearer $WHATSAPP_ACCESS_TOKEN" \
-d "object=whatsapp_business_account&callback_url=https://your-ngrok-url.ngrok.io/webhook&verify_token=$WHATSAPP_VERIFY_TOKEN"
# Production mode
openclaw skill run whatsapp-business-ai
# Development / dry-run
openclaw skill run whatsapp-business-ai --dry-run
The assistant runs as a persistent OpenClaw process that:
Incoming Message → Intent Classifier → Response Generator → Send Reply
↓
Booking Detected?
├── Yes → Check Calendar → Confirm Slot → Add Booking
└── No → Lead? → Log Lead → Schedule Follow-up
| Command | Description |
|---|---|
| --- | --- |
/status | Show assistant health, queue depth, message count today |
/leads | Export leads as CSV or JSON |
/analytics | Last 24h: sent/replied/followed-up counts |
/blacklist | Block a number |
/broadcast | Send bulk message to all leads (ask first) |
/pause | Stop accepting new messages (resume with /resume) |
Auto-reply templates are in ./templates/. Customise per business type:
templates/
├── auto_replies/
│ ├── booking_gym.yaml
│ ├── booking_restaurant.yaml
│ ├── booking_salon.yaml
│ ├── greeting_day.yaml
│ ├── greeting_night.yaml
│ ├── hours_inquiry.yaml
│ ├── pricing_inquiry.yaml
│ ├── complaint_acknowledgement.yaml
│ └── out_of_hours.yaml
├── follow_ups/
│ ├── no_reply_24h.yaml
│ ├── abandoned_booking.yaml
│ ├── post_service_feedback.yaml
│ └── promotion_blast.yaml
└── intents.yaml
Example: booking_gym.yaml
name: gym_booking
trigger:
intents: [booking, tour_inquiry, membership_inquiry]
confidence_threshold: 0.75
response:
template: |
Hi {{customer_name}}! 👋
Thanks for reaching out to {{business_name}}.
I can help you book:
🏋️ A free trial session
📋 A membership consultation
🎯 A personal training intro
What time works for you? Our hours are:
Mon–Fri: 5:00 AM – 9:00 PM
Sat: 6:00 AM – 6:00 PM
Sun: 7:00 AM – 2:00 PM
Just tell me your preferred day and time!
buttons:
- "Book Trial"
- "See Pricing"
- "Ask a Human"
Edit ./config/prompts.yaml:
classifier_prompt: |
Classify the incoming WhatsApp message into exactly one intent.
Intents: [booking, pricing_inquiry, hours, complaint, lead, general, spam]
Context: {business_type} in {location}
Message: {text}
Respond with only the intent name and confidence score.
response_prompt: |
You are {assistant_name}, the friendly AI assistant for {business_name}.
Location: {location}
Business type: {business_type}
Business hours: {hours}
Customer message: {text}
Detected intent: {intent}
Reply in a warm, professional tone. Be concise. If it's a booking,
ask for time and contact info. Never give away pricing you're unsure of.
Use South African English.
> "Hey Marvis, can you check on the gym assistant? How many unqualified leads are waiting?"
> "Set up a new WhatsApp assistant for 'Jozi Cuts Barbershop' in Randburg."
> "What's the reply rate on the restaurant assistant this week?"
> "Add a 'Student Discount' promotion template to the gym assistant's broadcast queue."
whatsapp-business-ai/
├── SKILL.md
├── README.md
├── config/
│ ├── business.yaml # Business profile (name, hours, location, type)
│ ├── prompts.yaml # LLM prompts for classification & reply
│ └── webhooks.yaml # Webhook routing rules
├── templates/
│ ├── auto_replies/ # Pre-written reply templates
│ ├── follow_ups/ # Scheduled follow-up templates
│ └── intents.yaml # Intent definitions & training data
├── scripts/
│ ├── start-webhook.sh # Start webhook listener with ngrok
│ ├── register-webhook.sh # Register with Meta APIs
│ └── export-leads.py # Export leads to CSV
├── workflows/
│ ├── booking.yaml # Booking: detect → confirm → create
│ ├── lead.yaml # Lead: capture → enrich → follow-up
│ └── complaint.yaml # Complaint: acknowledge → escalate → resolve
├── data/
│ ├── leads.db # SQLite lead database
│ └── conversation_logs/ # Raw conversation transcripts (rotated)
├── requirements.txt
└── package.json
| Symptom | Likely Cause | Fix |
|---|---|---|
| --- | --- | --- |
| Assistant not replying | Webhook not registered | Run register-webhook.sh |
| Replies go to wrong chat | Wrong phone_number_id in env | Check .env values |
| "Message not allowed" | Sender hasn't opted in | Send template message first |
| Low confidence on intent | Trained on wrong business type | Update config/business.yaml |
| Calendar sync fails | Missing Google Calendar scope | Re-auth with https://www.googleapis.com/auth/calendar scope |
| Leads not saving | SQLite path not writable | chmod 755 ./data/ |
| ngrok URL changed | Free ngrok rotates on restart | Use paid plan or static IP |
共 1 个版本