Skip to main content

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

# Configure LLM (works with any OpenAI-compatible API)
os.environ["LLM_API_KEY"] = "your-api-key"
os.environ["LLM_BASE_URL"] = "https://openrouter.ai/api/v1"  # Optional
os.environ["LLM_MODEL"] = "qwen/qwen3-30b-a3b-instruct-2507"  # Optional

# 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)

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 Default
LLM_API_KEY API key Required
LLM_BASE_URL API endpoint https://api.openai.com/v1
LLM_MODEL Model name gpt-4o-mini

Supported Providers

Works with any OpenAI-compatible API:

# OpenAI (default)
export LLM_API_KEY="sk-..."
export LLM_MODEL="gpt-4o-mini"

# OpenRouter
export LLM_API_KEY="sk-or-..."
export LLM_BASE_URL="https://openrouter.ai/api/v1"
export LLM_MODEL="qwen/qwen3-30b-a3b-instruct-2507"

# vLLM (self-hosted)
export LLM_API_KEY="token"
export LLM_BASE_URL="http://localhost:8000/v1"
export LLM_MODEL="meta-llama/Llama-3-8b-instruct"

# Ollama
export LLM_API_KEY="ollama"
export LLM_BASE_URL="http://localhost:11434/v1"
export LLM_MODEL="llama3"

# Together AI
export LLM_API_KEY="..."
export LLM_BASE_URL="https://api.together.xyz/v1"
export LLM_MODEL="meta-llama/Llama-3-70b-chat-hf"

# Groq
export LLM_API_KEY="..."
export LLM_BASE_URL="https://api.groq.com/openai/v1"
export LLM_MODEL="llama3-70b-8192"

Recommended Models

For best results with structured JSON extraction:

  • qwen/qwen3-30b-a3b-instruct-2507 (91%+ accuracy)
  • 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

whatsapp_formatter-0.2.0.tar.gz (12.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

whatsapp_formatter-0.2.0-py3-none-any.whl (18.4 kB view details)

Uploaded Python 3

File details

Details for the file whatsapp_formatter-0.2.0.tar.gz.

File metadata

  • Download URL: whatsapp_formatter-0.2.0.tar.gz
  • Upload date:
  • Size: 12.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for whatsapp_formatter-0.2.0.tar.gz
Algorithm Hash digest
SHA256 9f917fba232907beee047122665e394efa72ca10877fd7c53b03554c997e8d17
MD5 26fb87645548723250e64cb392195a86
BLAKE2b-256 56157a744eff23956b9e7c1c828c98192ecd43cb3394d7aa5d4ebf1ca4bc09ae

See more details on using hashes here.

File details

Details for the file whatsapp_formatter-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for whatsapp_formatter-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 31c52d7cb154cafb5a7092d07e9d1467fbf71e19dbc4ef995367e46c768fd158
MD5 d953a647fa8b0da60872f8eef8ed87a3
BLAKE2b-256 9ac43ef26787f4904b65d5342028bd1a837019fb0712f58ad7906ff91e26955e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page