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:
```bash
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
```python
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
```python
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
```python
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
```python
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
```python
# 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
```python
# 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
```python
# 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
```python
# 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
```python
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
```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
```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