WhatsApp ChatBot Engine
Core template engine
The core purpose of the library is to provide a template-driven WhatsApp ChatBot Engine
Setup
Let's checkout an example conversation flow using YAML files
Your typical folder structure might be
chatbot-project-name/
│
├── .env
├── .gitignore
├── config.py
├── main.py # FastAPI entry point
├── requirements.txt
│
├── templates/ # YAML template files
│ ├── template1.yaml
│ ├── template2.yaml
│ └── ...
│
├── triggers/ # Trigger-related YAML
│ └── trigger.yaml
│
└── services/
│
└── hooks/
|
└── venv/
Typical .env
configs
# as before
START_STAGE=MAIN_MENU
TEMPLATES_DIR=templates
TRIGGERS_DIR=triggers
Templates
Templates are the engine's first-class citizens. They are defined in any format or storage you prefer (yaml
and or json
are supported by default) and you can store them in any location you prefer
# template1.yaml
"MAIN_MENU":
kind: button
message:
body: |
Hi, I am WCE 🤖, your ERP System booking assistant.
What would you like to do today?"
buttons:
- Book a demo
- Help
routes:
"book a demo": "BOOK_STAGE"
"help": "HELP_MENU"
"BOOK_STAGE":
kind: button
message:
body: "Start your system demo booking request by clicking the start button"
footer: ERP Demo
buttons:
- Start
- Return
routes:
"start": "START_BOOKING"
"return": "MAIN_MENU"
# .. more templates
Internally, the engine understand EngineTemplate
model.
If you define your own IStorageManager
you need to make sure you map your template data into this model class
Webhook Handler
I prefer processing webhook data in background using Fastapi background tasks. You can use a similar approach for your framework or implementation.
# ~imports
from .config import whatsapp, engine
# ... same as before in Standalone section
async def task(payload: dict, headers: dict) -> None:
await engine.process_webhook(webhook_data=payload, webhook_headers=headers)
@app.post("/chatbot/webhook")
async def handler(request: Request, background_tasks: BackgroundTasks):
"""Handle incoming webhook events from WhatsApp and process them in the background."""
payload_bytes = await request.body()
payload = whatsapp.util.bytes_to_dict(payload_bytes)
# Add processing task to background
background_tasks.add_task(task, payload, dict(request.headers))
# quickly return response to WhatsApp to avoid retries
return "ack"
This is all that is needed to setup your chatbot with pywce. Remember, chatbot business logic is found in your template hooks.
Happy chatbot development 🙂🤖