A comprehensive chatbot solution for Frappe WhatsApp integration. Supports keyword-based replies, multi-step conversation flows with dynamic scripting, and optional AI-powered responses.
Frappe WhatsApp Chatbot
A comprehensive chatbot solution for Frappe WhatsApp integration.
Supports keyword-based replies, multi-step conversation flows with dynamic scripting, and optional AI-powered responses.
## Features
- **Keyword-Based Replies**: Configure automatic responses based on keywords with multiple match types
- **Conversation Flows**: Multi-step decision trees with user input collection and validation
- **WhatsApp Flow Integration**: Send native WhatsApp Flows for rich form experiences
- **Dynamic Script Responses**: Execute Python scripts to generate dynamic responses (e.g., check order status from database)
- **Document Creation**: Automatically create Frappe documents from collected flow data
- **Agent Transfer**: Transfer conversations to human agents and pause chatbot
- **Optional AI Integration**: OpenAI, Anthropic, and Google AI support for intelligent responses
- **Session Management**: Track user conversations with automatic timeout handling
- **Business Hours**: Restrict bot responses to business hours
- **Flexible Configuration**: All settings managed via Frappe Desk UI
## Installation
### Prerequisites
- Frappe Framework >= 15.0.0
- [frappe_whatsapp](https://github.com/shridarpatil/frappe_whatsapp) app (must be installed first)
### Install the App
```bash
# Inside your Frappe bench
bench get-app https://github.com/shridarpatil/frappe_whatsapp_chatbot
bench --site your-site install-app frappe_whatsapp_chatbot
```
### Optional Dependencies (for AI features)
```bash
pip install openai # For OpenAI integration
pip install anthropic # For Anthropic Claude integration
```
## Quick Start
### 1. Enable Chatbot
Navigate to **WhatsApp Chatbot** (single DocType) and:
1. Check **Enabled**
2. Select the WhatsApp Account (or enable "Process All Accounts")
3. Set a default response message for unmatched messages
### 2. Create Your First Keyword Reply
Go to **WhatsApp Keyword Reply** list and create a new rule:
```
Title: Greeting
Keywords: hello, hi, hey
Match Type: Exact
Response Type: Text
Response Text: Hello! How can I help you today?
```
### 3. Test It
Send "hello" to your WhatsApp Business number and receive the automated reply!
---
## Configuration Guide
### WhatsApp Chatbot Settings
| Setting | Description |
|---------|-------------|
| Enabled | Master switch to enable/disable the chatbot |
| WhatsApp Account | Specific account to process (or use "Process All Accounts") |
| Default Response | Message sent when no keyword/flow matches |
| Session Timeout | Minutes before an inactive flow session expires (default: 30) |
| Business Hours Only | Only respond during specified hours |
| Enable AI | Use AI for fallback responses |
### Keyword Reply Configuration
| Field | Description |
|-------|-------------|
| Keywords | Comma-separated keywords (e.g., "hello, hi, hey") |
| Match Type | **Exact** - exact match, **Contains** - keyword anywhere in message, **Starts With** - message starts with keyword, **Regex** - regular expression |
| Case Sensitive | Enable for case-sensitive matching |
| Response Type | **Text** - plain text, **Template** - WhatsApp template, **Media** - image/video/document, **Flow** - trigger a conversation flow |
| Priority | Higher priority rules are matched first (default: 10) |
| Active From/Until | Optional date range for time-limited responses |
### Conversation Flows
Flows allow multi-step conversations to collect information from users.
#### Flow Settings
| Field | Description |
|-------|-------------|
| Flow Name | Unique identifier |
| Trigger Keywords | Comma-separated keywords that start this flow |
| Initial Message | First message sent when flow starts |
| Steps | Table of flow steps (see below) |
| Completion Message | Message sent when flow completes. Use `{variable_name}` for substitution |
| On Complete Action | **None**, **Create Document**, **Call API**, or **Run Script** |
| Cancel Keywords | Words that cancel the flow (default: cancel, stop, quit, exit) |
#### Flow Step Configuration
| Field | Description |
|-------|-------------|
| Step Name | Unique identifier for this step |
| Message | Message to send. Use `{variable_name}` for substitution |
| Message Type | **Text** - plain message, **Template** - WhatsApp template, **Script** - dynamic Python script |
| Input Type | Expected input: **None**, **Text**, **Number**, **Email**, **Phone**, **Date**, **Select**, **WhatsApp Flow** |
| Store As | Variable name to store user's input (e.g., `customer_email`) |
| Options | For Select type: pipe-separated options (e.g., `Option 1|Option 2|Option 3`) |
| Validation Regex | Custom regex pattern for input validation |
| Next Step | Explicit next step name (leave empty for sequential order) |
| Conditional Next | JSON mapping input to next step (see examples below) |
| Skip Condition | Python expression to skip this step |
---
## Examples
### Example 1: Simple FAQ Bot
Create keyword replies for common questions:
**Keyword Reply: Business Hours**
```
Keywords: hours, timing, open, close
Match Type: Contains
Response Type: Text
Response Text: We're open Monday-Friday, 9 AM to 6 PM IST.
```
**Keyword Reply: Location**
```
Keywords: address, location, where
Match Type: Contains
Response Type: Text
Response Text: We're located at 123 Main Street, Mumbai, India. Google Maps: https://maps.google.com/...
```
### Example 2: Lead Collection Flow
```
Flow Name: Contact Sales
Trigger Keywords: sales, contact, demo, pricing
Initial Message: Great! I'd be happy to connect you with our sales team.
Steps:
┌─────────────────────────────────────────────────────────────────┐
│ Step 1 │
│ Step Name: ask_name │
│ Message: What's your name? │
│ Input Type: Text │
│ Store As: customer_name │
├─────────────────────────────────────────────────────────────────┤
│ Step 2 │
│ Step Name: ask_email │
│ Message: Thanks {customer_name}! What's your email address? │
│ Input Type: Email │
│ Store As: customer_email │
├─────────────────────────────────────────────────────────────────┤
│ Step 3 │
│ Step Name: ask_company │
│ Message: And which company are you from? │
│ Input Type: Text │
│ Store As: company_name │
└─────────────────────────────────────────────────────────────────┘
Completion Message: Thank you {customer_name}! Our sales team will contact you at {customer_email} within 24 hours.
On Complete Action: Create Document
Create DocType: Lead
Field Mapping:
{
"lead_name": "customer_name",
"email_id": "customer_email",
"company_name": "company_name"
}
```
### Example 3: Order Status Check (Using Script)
This example shows how to use the **Script** message type to query the database dynamically.
```
Flow Name: Order Status
Trigger Keywords: order status, track order, my order
Steps:
┌─────────────────────────────────────────────────────────────────┐
│ Step 1 │
│ Step Name: ask_order_id │
│ Message: Please enter your Order ID (e.g., SAL-ORD-2024-00001) │
│ Input Type: Text │
│ Store As: order_id │
├─────────────────────────────────────────────────────────────────┤
│ Step 2 │
│ Step Name: show_status │
│ Message: (placeholder - script will generate response) │
│ Message Type: Script │
│ Input Type: None │
│ Response Script: │
│ │
│ order_id = data.get('order_id') │
│ try: │
│ order = frappe.get_doc('Sales Order', order_id) │
│ response = f"""Order Details: │
│ Order ID: {order.name} │
│ Status: {order.status} │
│ Total: {order.grand_total} │
│ Expected Delivery: {order.delivery_date or 'TBD'}""" │
│ except frappe.DoesNotExistError: │
│ response = f"Sorry, order '{order_id}' was not found." │
│ except Exception as e: │
│ response = "Sorry, unable to fetch order details." │
│ │
└─────────────────────────────────────────────────────────────────┘
Completion Message: Is there anything else I can help you with?
```
#### Script Variables Available
When using Message Type: Script, these variables are available:
| Variable | Description |
|----------|-------------|
| `data` | Dictionary of all collected session data (keyed by Store As names) |
| `frappe` | Frappe module for database queries |
| `json` | JSON module |
| `session` | Current session document |
| `phone_number` | User's WhatsApp phone number |
| `response` | **Set this variable** with the message to send |
### Example 4: Conditional Branching
Create different paths based on user input:
```
Flow Name: Support Request
Trigger Keywords: support, help, issue
Steps:
┌─────────────────────────────────────────────────────────────────┐
│ Step 1 │
│ Step Name: ask_issue_type │
│ Message: What type of issue are you facing? │
│ Input Type: Select │
│ Options: Billing|Technical|General │
│ Store As: issue_type │
│ Conditional Next: │
│ { │
│ "billing": "billing_step", │
│ "technical": "technical_step", │
│ "general": "general_step" │
│ } │
├─────────────────────────────────────────────────────────────────┤
│ Step 2a │
│ Step Name: billing_step │
│ Message: For billing issues, please email billing@company.com │
│ Input Type: None │
├─────────────────────────────────────────────────────────────────┤
│ Step 2b │
│ Step Name: technical_step │
│ Message: Please describe your technical issue in detail. │
│ Input Type: Text