swiftops-backend / docs /dev /wasender /WASENDER_INTEGRATION.md
kamau1's picture
chore: migrate to useast organize the docs, delete redundant migrations
c4f7e3e

WASender WhatsApp Integration Guide

Overview

WASender provides WhatsApp messaging for field agents and customers. It's our immediate SMS alternative since most field agents have WhatsApp.

Environment Variable

Add this to your Hugging Face Spaces secrets:

WASENDER_API_KEY=your_wasender_api_key_here

Startup Health Check

On application startup, you'll see:

External Services Check:
  WASender (WhatsApp): Connected
    WhatsApp: connected
    Note: WhatsApp is connected and ready

Possible Statuses

  • Connected - WhatsApp is ready to send messages
  • Connecting - WhatsApp is connecting (wait a moment)
  • Disconnected - WhatsApp is disconnected (check WASender dashboard)
  • Need Scan - QR code scan required (scan in WASender dashboard)
  • Logged Out - WhatsApp session logged out (re-login required)
  • Expired - WhatsApp session expired (re-authenticate)

Usage Examples

1. Send Simple Message

from app.integrations import send_whatsapp_message

# Send message to field agent
result = send_whatsapp_message(
    to="+254799456976",
    text="Your ticket #1234 has been assigned. Please check the app."
)

# Response:
# {
#     "success": true,
#     "data": {
#         "msgId": 11462202,
#         "jid": "+254799456976",
#         "status": "in_progress"
#     }
# }

2. Send OTP

from app.integrations import send_whatsapp_otp

# Send OTP for verification
result = send_whatsapp_otp(
    to="+254799456976",
    otp_code="123456"
)

# Message sent:
# "Your SwiftOps verification code is: 123456
#  This code will expire in 10 minutes."

3. Send Message with Image

from app.integrations import send_whatsapp_message

# Send message with image
result = send_whatsapp_message(
    to="+254799456976",
    text="Installation completed! See photo:",
    media_url="https://example.com/installation-photo.jpg"
)

4. Using the Client Directly

from app.integrations import get_wasender_client

# Get client
client = get_wasender_client()

# Check status
status = client.get_status()
print(status)  # {"status": "connected"}

# Send message
result = client.send_message(
    to="+254799456976",
    text="Hello from SwiftOps!"
)

# Send OTP with custom template
result = client.send_otp(
    to="+254799456976",
    otp_code="123456",
    message_template="Your code: {otp}. Valid for 10 minutes."
)

Use Cases

1. Ticket Assignment Notification

# When ticket is assigned to field agent
send_whatsapp_message(
    to=agent.phone,
    text=f"New ticket assigned: {ticket.title}\n"
         f"Customer: {customer.name}\n"
         f"Location: {ticket.location}\n"
         f"Priority: {ticket.priority}\n\n"
         f"Open app to view details."
)

2. Customer Installation Confirmation

# After successful installation
send_whatsapp_message(
    to=customer.phone,
    text=f"Dear {customer.name},\n\n"
         f"Your {service_type} installation is complete!\n"
         f"Service ID: {subscription.id}\n"
         f"Package: {subscription.package_name}\n\n"
         f"Thank you for choosing us!"
)

3. OTP Verification

# For user registration/login
otp_code = generate_otp()  # Your OTP generation logic
send_whatsapp_otp(
    to=user.phone,
    otp_code=otp_code
)

4. Expense Approval Notification

# When expense is approved
send_whatsapp_message(
    to=agent.phone,
    text=f"Expense approved!\n"
         f"Amount: KES {expense.amount}\n"
         f"Category: {expense.category}\n"
         f"Payment will be processed shortly."
)

Phone Number Format

Always use international format:

  • +254799456976 (Kenya)
  • +254712345678 (Kenya)
  • 0799456976 (Missing country code)
  • 254799456976 (Missing + sign)

Rate Limits

WASender has rate limits (check your plan):

  • Free tier: ~256 messages per minute
  • Check headers: x-ratelimit-remaining

Error Handling

from app.integrations import send_whatsapp_message
import logging

logger = logging.getLogger(__name__)

try:
    result = send_whatsapp_message(
        to=user.phone,
        text="Your message"
    )
    
    if result.get("success"):
        logger.info(f"WhatsApp sent: {result['data']['msgId']}")
    else:
        logger.error(f"WhatsApp failed: {result}")
        
except Exception as e:
    logger.error(f"WhatsApp error: {e}")
    # Fallback to SMS or email

Testing

Test in PowerShell

$env:WASENDER_API_KEY = "your_key_here"

Invoke-WebRequest `
    -Uri "https://www.wasenderapi.com/api/send-message" `
    -Method POST `
    -Headers @{
        "Authorization" = "Bearer $env:WASENDER_API_KEY"
        "Content-Type"  = "application/json"
    } `
    -Body '{"to": "+254799456976", "text": "Test message"}'

Test in Python

from app.integrations import send_whatsapp_message

# Send test message
result = send_whatsapp_message(
    to="+254799456976",
    text="Test message from SwiftOps"
)

print(result)

Monitoring

Check WASender dashboard for:

  • Message delivery status
  • Failed messages
  • WhatsApp connection status
  • Usage statistics

Best Practices

  1. Always validate phone numbers before sending
  2. Use templates for common messages (faster, cheaper)
  3. Handle errors gracefully - fallback to SMS/email
  4. Don't spam - respect user preferences
  5. Log all messages - for audit trail
  6. Check rate limits - avoid hitting limits

Troubleshooting

"WhatsApp: need_scan"

  • Go to WASender dashboard
  • Scan QR code with your WhatsApp
  • Wait for "connected" status

"Connection failed"

  • Check API key is correct
  • Check internet connectivity
  • Check WASender service status

"Message not delivered"

  • Verify phone number format (+254...)
  • Check recipient has WhatsApp
  • Check WASender dashboard for details

Next Steps

  1. Set WASENDER_API_KEY in HF Spaces secrets
  2. Deploy application
  3. Check startup logs for "Connected" status
  4. Test sending a message
  5. Integrate into ticket assignment workflow