Transform LLM output to WhatsApp Business API JSON format
Project description
WhatsApp Formatter
Transform LLM output to WhatsApp Business API JSON format.
This library uses an LLM to parse free-form text (with options, headers, footers) and automatically converts it to valid WhatsApp message formats (plain text, quick reply buttons, or interactive lists).
Installation
pip install whatsapp-formatter
Quick Start
import os
from whatsapp_formatter import format_for_whatsapp
# Set your API key (OpenRouter or OpenAI)
os.environ["OPENROUTER_API_KEY"] = "your-api-key"
os.environ["OPENROUTER_BASE_URL"] = "https://openrouter.ai/api/v1"
# Format LLM output for WhatsApp
raw_text = """
I can help with your account. What would you like to do?
1. Check your balance
2. Transfer funds
3. View recent transactions
"""
result = format_for_whatsapp(raw_text)
print(result.whatsapp_json)
Output:
{
"type": "interactive",
"interactive": {
"type": "button",
"body": { "text": "I can help with your account. What would you like to do?" },
"action": {
"buttons": [
{ "type": "reply", "reply": { "id": "check_your_balance", "title": "Check your balance" } },
{ "type": "reply", "reply": { "id": "transfer_funds", "title": "Transfer funds" } },
{ "type": "reply", "reply": { "id": "view_recent_transac", "title": "View Transactions" } }
]
}
}
}
Features
-
Automatic format selection based on option count:
- 0 options → Plain text message
- 1-3 options → Quick reply buttons
- 4-10 options → Interactive list
- 11+ options → Plain text fallback with numbered list
-
Smart truncation to fit WhatsApp constraints:
- Button titles: max 20 characters
- List row titles: max 24 characters
- Body text: max 1024 characters (interactive) or 1600 (plain text)
-
Automatic deduplication of option titles with suffixes
-
Header/footer extraction from structured messages
-
Multiple option formats supported:
- Numbered lists (
1. Option) - Bullet points (
- Option,• Option) - Inline choices (
Yes, No, or Cancel)
- Numbered lists (
API Reference
format_for_whatsapp(text: str) -> TransformResult
The main entry point. Parses text and returns WhatsApp-ready JSON.
from whatsapp_formatter import format_for_whatsapp
result = format_for_whatsapp("Your balance is $500.")
print(result.format_used) # FormatType.PLAIN_TEXT
print(result.whatsapp_json) # {"type": "text", "text": {"body": "..."}}
print(result.fallback_used) # False
print(result.modifications) # List of any truncations applied
transform(llm_output: LLMOutput) -> TransformResult
Transform pre-parsed data to WhatsApp format (skip LLM parsing step).
from whatsapp_formatter import transform, LLMOutput, Option
llm_output = LLMOutput(
body="Choose an option:",
options=[
Option(title="Yes"),
Option(title="No"),
]
)
result = transform(llm_output)
parse(text: str) -> LLMOutput
Parse text using LLM (requires API key).
from whatsapp_formatter import parse
llm_output = parse("Select: 1. Apple 2. Banana 3. Cherry")
print(llm_output.body) # "Select:"
print(llm_output.options) # [Option(title="Apple"), ...]
Data Types
LLMOutput
class LLMOutput:
body: str # Main message text (required)
options: list[Option] | None # Flat list of options
sections: list[Section] | None # Grouped options (for list format)
header: str | None # Optional header text
footer: str | None # Optional footer text
TransformResult
class TransformResult:
success: bool # Always True unless error
whatsapp_json: dict # Ready-to-send WhatsApp payload
format_used: FormatType # PLAIN_TEXT, QUICK_REPLY, or LIST
fallback_used: bool # True if format was downgraded
fallback_reason: str | None # Reason for fallback
modifications: list[str] # Truncations/deduplications applied
FormatType
class FormatType(Enum):
PLAIN_TEXT = "plain_text"
QUICK_REPLY = "quick_reply"
LIST = "list"
Configuration
Environment Variables
| Variable | Description | Required |
|---|---|---|
OPENROUTER_API_KEY |
OpenRouter API key | Yes* |
OPENAI_API_KEY |
OpenAI API key | Yes* |
OPENROUTER_BASE_URL |
API base URL | No |
OPENROUTER_MODEL |
Model to use (default: openai/gpt-4o-mini) |
No |
*One of OPENROUTER_API_KEY or OPENAI_API_KEY is required.
Recommended Models
For best results with structured extraction:
qwen/qwen3-30b-a3b-instruct-2507(91%+ accuracy)openai/gpt-4o-mini(with JSON mode)
WhatsApp Constraints
The library automatically handles these WhatsApp Business API limits:
| Element | Max Length |
|---|---|
| Quick reply button title | 20 chars |
| Quick reply buttons | 3 max |
| List row title | 24 chars |
| List row description | 72 chars |
| List sections | 10 max |
| List rows total | 10 max |
| Interactive body | 1024 chars |
| Plain text body | 1600 chars |
| Header | 60 chars |
| Footer | 60 chars |
Examples
Plain Text (no options)
result = format_for_whatsapp("Your balance is $500.")
# → {"type": "text", "text": {"body": "Your balance is $500."}}
Quick Reply (1-3 options)
result = format_for_whatsapp("""
Was this transaction authorized?
1. Yes
2. No
""")
# → {"type": "interactive", "interactive": {"type": "button", ...}}
List (4-10 options)
result = format_for_whatsapp("""
Select a service:
1. Balance
2. Transfer
3. Cards
4. Loans
5. Support
""")
# → {"type": "interactive", "interactive": {"type": "list", ...}}
With Header and Footer
result = format_for_whatsapp("""
⚠️ Security Alert
We detected a login from a new device. Was this you?
1. Yes, it was me
2. No, secure my account
Reply within 24 hours.
""")
# Extracts header: "Security Alert"
# Extracts footer: "Reply within 24 hours."
Development
# Clone the repository
git clone https://github.com/dnivra26/whatsapp-formatter.git
cd whatsapp-formatter
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
License
MIT License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file whatsapp_formatter-0.1.0.tar.gz.
File metadata
- Download URL: whatsapp_formatter-0.1.0.tar.gz
- Upload date:
- Size: 12.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
527b1ee0d9ee2969dee8165fe3d2afcec55b9d13a88f2cecfa057c5042086f5c
|
|
| MD5 |
4c1245836624626cf48db944dd5c2055
|
|
| BLAKE2b-256 |
9c2d9bfa19f83867254c5ff759a637dc9adf0b13ef01905bd6eb7e9c5d753577
|
File details
Details for the file whatsapp_formatter-0.1.0-py3-none-any.whl.
File metadata
- Download URL: whatsapp_formatter-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3385712836be476f92932280106d8abaf4fc49b64f0e0cf28643e122cd1e4253
|
|
| MD5 |
c752e86137af7e44455ac858bfea6fd8
|
|
| BLAKE2b-256 |
68a2e7c091260c23fb938c00206510eb7872cb6af95a7e6473745bfcc8d2d8cb
|