Skip to main content
Like AOF? Give us a star!
If you find AOF useful, please star us on GitHub. It helps us reach more developers and grow the community.

Tutorial: Build a WhatsApp Ops Bot with AOF

Build a mobile-first WhatsApp bot for DevOps operations using AOF. Ideal for on-call engineers who need AI-powered infrastructure access from their phone.

What you'll learn:

  • Set up Meta Business and WhatsApp Cloud API
  • Configure AOF with WhatsApp integration
  • Create agents optimized for mobile
  • Use interactive buttons and lists
  • Handle button and list responses

Time: 20 minutes

Quick Start

# Set environment variables
export WHATSAPP_PHONE_NUMBER_ID=123456789012345
export WHATSAPP_ACCESS_TOKEN=EAAxxxxxxxxxxxxxxxxxxxxxxx
export WHATSAPP_VERIFY_TOKEN=my-secret-verify-token
export WHATSAPP_APP_SECRET=abcdef1234567890
export GOOGLE_API_KEY=xxxxx

# Start AOF server
aofctl serve \
--config examples/configs/whatsapp-bot.yaml \
--agents-dir examples/agents

# Expose with ngrok
ngrok http 3000
# Configure webhook URL in Meta Developer Console

Prerequisites

  • AOF installed (curl -sSL https://docs.aof.sh/install.sh | bash)
  • Meta Business Account (free at business.facebook.com)
  • Google AI API key (or Anthropic)
  • Phone number for WhatsApp Business

Step 1: Set Up Meta Business

Create Meta Business Account

  1. Go to business.facebook.com
  2. Click Create Account
  3. Follow the setup wizard
  4. Verify your business (optional for testing)

Create WhatsApp Business App

  1. Go to developers.facebook.com
  2. Click My AppsCreate App
  3. Select Business type
  4. Choose your Meta Business Account
  5. Name your app (e.g., "AOF Ops Bot")

Add WhatsApp Product

  1. In your app dashboard, click Add Product
  2. Find WhatsApp and click Set Up
  3. This creates a test phone number for development

Get Credentials

From WhatsAppAPI Setup:

Phone Number ID: 123456789012345
Access Token: EAAxxxxxxxx... (click Generate for permanent token)

From App SettingsBasic:

App Secret: abcdef1234567890

Create your own verify token (any random string):

Verify Token: my-secret-verify-token-2024

Step 2: Create Agent Configuration

Create agents/whatsapp-ops.yaml:

apiVersion: aof.dev/v1alpha1
kind: Agent
metadata:
name: whatsapp-ops
labels:
platform: whatsapp
capability: devops

spec:
model: google:gemini-2.5-flash
temperature: 0
max_tokens: 1024

description: "Mobile DevOps assistant for WhatsApp"

tools:
- kubectl
- docker

system_prompt: |
You are a DevOps assistant on WhatsApp mobile.

## Response Guidelines
- Be EXTREMELY concise (small mobile screens)
- Use emoji for status: ✅ ⚠️ ❌ 🔍
- Max 3-4 lines per response when possible
- Use code blocks sparingly (hard to read on mobile)
- Offer buttons for common follow-up actions

## Action Buttons
When appropriate, suggest up to 3 actions:
- view_logs: View Logs
- describe_pod: Describe Pod
- check_events: Check Events
- list_pods: List Pods
- check_nodes: Check Nodes

## Safety
This is a read-only platform. For write operations,
suggest using Slack or CLI instead.

Step 3: Create Daemon Configuration

Create config/whatsapp-bot.yaml:

apiVersion: aof.dev/v1
kind: DaemonConfig
metadata:
name: whatsapp-ops-bot

spec:
server:
port: 3000
host: "0.0.0.0"

platforms:
whatsapp:
enabled: true
phone_number_id_env: WHATSAPP_PHONE_NUMBER_ID
access_token_env: WHATSAPP_ACCESS_TOKEN
verify_token_env: WHATSAPP_VERIFY_TOKEN
app_secret_env: WHATSAPP_APP_SECRET

agents:
directory: "./agents"

runtime:
default_agent: whatsapp-ops
max_concurrent_tasks: 5
task_timeout_secs: 60

Step 4: Start the Server

# Set environment variables
export WHATSAPP_PHONE_NUMBER_ID="123456789012345"
export WHATSAPP_ACCESS_TOKEN="EAAxxxxxxxxxxxxxxxxxxxxxxx"
export WHATSAPP_VERIFY_TOKEN="my-secret-verify-token"
export WHATSAPP_APP_SECRET="abcdef1234567890"
export GOOGLE_API_KEY="your-google-api-key"

# Start server
aofctl serve \
--config config/whatsapp-bot.yaml \
--agents-dir agents/

# In another terminal, start ngrok
ngrok http 3000
# Note the HTTPS URL: https://abc123.ngrok.io

Step 5: Configure Webhook

In Meta Developer Console:

  1. Go to WhatsAppConfiguration
  2. Click Edit on Webhook
  3. Set Callback URL: https://abc123.ngrok.io/webhook/whatsapp
  4. Set Verify Token: my-secret-verify-token (same as env var)
  5. Click Verify and Save
  6. Under Webhook Fields, subscribe to messages

Step 6: Add Test Phone Number

  1. Go to WhatsAppAPI Setup
  2. Under Send and receive messages, add your phone number
  3. You'll receive a verification code via WhatsApp
  4. Enter the code to verify

Step 7: Test the Bot

Send a message to the test phone number from WhatsApp:

Basic Query

You: show pods
Bot: 🔍 Pods in default namespace:

api-server-abc12 ✅ Running
worker-xyz98 ✅ Running
db-primary-qrs45 ✅ Running

[List All] [Check Nodes] [View Events]

Interactive Buttons

Tap a button to trigger follow-up action:

You: *taps [Check Nodes]*
Bot: 🖥️ Cluster Nodes:

node-1 Ready 8 CPU 32GB
node-2 Ready 8 CPU 32GB
node-3 Ready 8 CPU 32GB

✅ All nodes healthy

Agent Switching

You: /agent
Bot: Select an agent:

📋 View Agents

[Tap to open list]

List shows:

  • ☸️ K8s Agent - Kubernetes operations
  • 🐳 Docker Agent - Container management
  • 🔧 DevOps Agent - Full-stack DevOps

Interactive Message Examples

Reply Buttons

When agent suggests actions:

TriggerResponse {
text: "Pod api-server is in CrashLoopBackOff",
status: ResponseStatus::Warning,
actions: vec![
Action { id: "view_logs", label: "View Logs" },
Action { id: "describe_pod", label: "Describe" },
Action { id: "restart_pod", label: "Restart" },
],
}

User sees:

⚠️ Pod api-server is in CrashLoopBackOff

[View Logs] [Describe] [Restart]

List Messages

For agent selection:

# Message with list
Header: "Select Agent"
Body: "Choose an agent for your task"
Button: "View Agents"

Sections:
- title: "DevOps"
items:
- K8s Agent: "Kubernetes operations"
- Docker Agent: "Container management"
- title: "Monitoring"
items:
- Prometheus Agent: "Metrics and alerts"
- Loki Agent: "Log analysis"

Handling Button Responses

When user taps a button, AOF receives:

Text: button:view_logs

Configure agent to handle:

system_prompt: |
## Button Handling
When you receive a message starting with "button:",
it's a button tap. Handle these:

- button:view_logs → Show recent logs
- button:describe_pod → Show pod details
- button:restart_pod → Explain this requires Slack/CLI

Available Commands

CommandDescription
/helpShow help and current agent
/agentList agents with interactive list
/agent <name>Switch to specific agent
/fleetList fleets with interactive list
/fleet <name>Switch to specific fleet
/statusCheck service status

Built-in Agents

AgentToolsUse Case
k8s-opskubectl, helmKubernetes operations
docker-opsdocker, shellContainer management
devopskubectl, docker, terraform, gitFull-stack DevOps

Safety: Read-Only Mode

Like Telegram, WhatsApp is read-only by default:

  • ✅ Read operations work: kubectl get, docker ps
  • ❌ Write operations blocked: kubectl delete, docker rm

This protects against accidental commands from mobile.

Production Setup

1. Verify Business

For production use:

  1. Go to Meta Business Suite
  2. Complete business verification
  3. Submit WhatsApp display name for approval
  4. Wait for Meta review (1-3 business days)

2. Phone Number Whitelist

Restrict access in config:

platforms:
whatsapp:
enabled: true
phone_number_id_env: WHATSAPP_PHONE_NUMBER_ID
access_token_env: WHATSAPP_ACCESS_TOKEN
verify_token_env: WHATSAPP_VERIFY_TOKEN
app_secret_env: WHATSAPP_APP_SECRET

# Only allow these phone numbers
allowed_numbers:
- "14155551234" # On-call lead
- "14155555678" # Team member

3. Use Permanent Token

Test tokens expire. For production:

  1. Go to WhatsAppAPI Setup
  2. Click Add system user in Business Settings
  3. Generate permanent token for system user
  4. Use this token in production

4. Run as Service

# systemd service
sudo tee /etc/systemd/system/aof-whatsapp.service << 'EOF'
[Unit]
Description=AOF WhatsApp Bot
After=network.target

[Service]
Type=simple
User=aof
Environment=WHATSAPP_PHONE_NUMBER_ID=xxx
Environment=WHATSAPP_ACCESS_TOKEN=xxx
Environment=WHATSAPP_VERIFY_TOKEN=xxx
Environment=WHATSAPP_APP_SECRET=xxx
Environment=GOOGLE_API_KEY=xxx
ExecStart=/usr/local/bin/aofctl serve --config /etc/aof/whatsapp-bot.yaml
Restart=always

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable --now aof-whatsapp

5. Use Cloudflare Tunnel

Free alternative to ngrok for production:

brew install cloudflared

# Create tunnel
cloudflared tunnel create aof-whatsapp
cloudflared tunnel route dns aof-whatsapp whatsapp-bot.yourdomain.com

# Run tunnel
cloudflared tunnel run aof-whatsapp

WhatsApp Limits

Keep these in mind when building agents:

LimitValue
Message body4096 characters
Reply buttons3 maximum
Button text20 characters
List sections10 maximum
Items per section10 maximum

Troubleshooting

Webhook not verifying

# Check server is running
curl http://localhost:3000/health

# Check ngrok is forwarding
curl https://your-ngrok-url.ngrok.io/health

# Verify token matches
echo $WHATSAPP_VERIFY_TOKEN

Messages not arriving

  1. Check webhook subscribed to messages field
  2. Verify phone number is added and verified
  3. Check server logs for signature errors
RUST_LOG=debug aofctl serve --config config/whatsapp-bot.yaml

Invalid signature errors

# Verify app secret is correct
echo $WHATSAPP_APP_SECRET

# Check signature header in logs
# Should be: X-Hub-Signature-256: sha256=...

Buttons not showing

  • Max 3 buttons allowed
  • Button titles max 20 characters
  • Check response has actions array

Cost Considerations

WhatsApp Business API has per-conversation pricing:

Conversation TypeCost (approximate)
User-initiated$0.005 - $0.08
Business-initiated$0.01 - $0.15

First 1,000 user-initiated conversations/month are free.

Next Steps