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 🙂🤖