Skip to content

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

WhatsApp Calling - Frappe Custom App

A comprehensive Frappe v15 custom app that enables businesses to make and receive voice calls through WhatsApp Business API directly from their ERPNext CRM Lead forms.

License: MIT Frappe Version

🎯 Features

  • πŸ“ž WhatsApp Voice Calling: Make and receive calls via WhatsApp Business API
  • πŸ”— CRM Integration: Seamless integration with ERPNext Lead doctype
  • πŸŽ™οΈ WebRTC Audio: Browser-based calling using WebRTC technology
  • πŸ“Š Call Recording: Automatic recording of all calls with configurable retention
  • βœ… Permission Management: WhatsApp-compliant call permission system
  • πŸ’° Cost Tracking: Automatic calculation and tracking of call costs
  • πŸ‘₯ Multi-Tenancy: Support for multiple companies with separate phone numbers
  • πŸ“ˆ Call Analytics: Comprehensive call history and statistics
  • πŸ”” Real-time Notifications: Instant alerts for incoming calls

πŸ—οΈ Architecture

WhatsApp User ↔ Meta WhatsApp Cloud API ↔ Frappe App ↔ Janus Media Server ↔ Agent Browser (WebRTC)

Key Components

  1. Frappe Backend (Python): Handles webhooks, call management, permissions
  2. Janus Gateway (Media Server): Bridges WhatsApp audio ↔ Browser WebRTC
  3. Frontend (JavaScript): WebRTC client in Frappe UI
  4. Database: Frappe Doctypes for call records, numbers, permissions

πŸ“‹ Prerequisites

1. Frappe/ERPNext Setup

  • Frappe v15 or higher
  • ERPNext installed
  • Python 3.10+
  • MariaDB/PostgreSQL

2. Janus Gateway Media Server

⚠️ Important: For production deployment, see JANUS_PRODUCTION_SETUP.md for complete configuration guide following Meta's best practices.

Quick Docker Installation (Development Only)

docker pull canyan/janus-gateway:latest

docker run -d \
  --name janus-gateway \
  -p 8088:8088 \
  -p 8089:8089 \
  -p 8188:8188 \
  -p 8989:8989 \
  -p 20000-20100:20000-20100/udp \
  canyan/janus-gateway:latest

Verify Installation

curl http://localhost:8088/janus/info

Note: Docker setup above is for local development only. Production requires proper NAT configuration with public IP.

3. WhatsApp Business API

  • Meta Business Account
  • WhatsApp Business API access
  • Phone Number registered with Meta
  • Access Token and Webhook Verify Token

πŸš€ Installation

Step 1: Install the App

# Navigate to your frappe-bench
cd ~/frappe-bench

# Get the app from repository
bench get-app https://github.com/your-username/whatsapp-calling.git

# Install on your site
bench --site [your-site-name] install-app whatsapp_calling

# Migrate database
bench --site [your-site-name] migrate

# Build assets
bench build --app whatsapp_calling

# Restart bench
bench restart

Step 2: Configure WhatsApp Settings

  1. Navigate to: Setup > WhatsApp Calling > WhatsApp Settings

  2. Configure the following:

WhatsApp API Configuration:

  • Default Access Token: Your Meta WhatsApp Business API token
  • Webhook Verify Token: Token for webhook verification

Janus Media Server Configuration:

  • Janus HTTP API URL: http://localhost:8088/janus (dev) or https://janus.yourdomain.com/janus (prod)
  • Janus WebSocket URL: ws://localhost:8188 (dev) or wss://janus.yourdomain.com/janus-ws (prod)
  • Janus API Secret: (from your janus.jcfg file, optional)

NAT & WebRTC Configuration (Production):

  • Janus Public IP Address: Your server's public IP (e.g., 203.0.113.42)
  • Enable STUN Server: βœ“ (enabled by default)
  • STUN Server: stun.l.google.com (Meta recommended)
  • STUN Port: 19302
  • Enable TURN Server: Only if needed for strict firewalls

Note: For production, proper NAT configuration is critical. See JANUS_PRODUCTION_SETUP.md.

Call Recording Settings:

  • Enable Call Recording: βœ“
  • Recording Storage Path: /recordings
  • Recording Format: Opus
  • Retention Days: 90
  1. Click Save

Step 3: Add WhatsApp Business Number

  1. Navigate to: WhatsApp Calling > WhatsApp Number > New

  2. Fill in details:

  • Phone Number: +919876543210 (E.164 format)
  • Display Name: Your Business Name
  • Company: Select your company
  • Status: Active
  • Phone Number ID: (from Meta Business Manager)
  • Access Token: (optional, uses default if blank)
  1. Click Save

Step 4: Configure Meta Webhook

  1. Go to Meta for Developers
  2. Select your app
  3. Navigate to WhatsApp > Configuration
  4. Add Webhook URL: https://yoursite.com/api/method/whatsapp_calling.whatsapp_calling.api.webhook.whatsapp_webhook
  5. Add Verify Token: (same as in WhatsApp Settings)
  6. Subscribe to field: calls
  7. Save

πŸ“– Usage

Making Outbound Calls from CRM Lead

  1. Open a Lead record
  2. Ensure mobile number is filled
  3. Click "πŸ“ž > WhatsApp Call" button
  4. Confirm the call
  5. Allow microphone access when prompted
  6. Call will be initiated

Request Call Permission (First Time)

  1. Open a Lead record
  2. Click "πŸ“ž > Request Call Permission"
  3. Customer receives WhatsApp template message
  4. Once customer grants permission, you can call

Answering Incoming Calls

  1. When a call comes in, you'll see a popup notification
  2. Click "Answer" to accept the call
  3. Click "Decline" to reject

Call Controls

During an active call:

  • Mute: Toggle microphone on/off
  • End Call: Terminate the call
  • Timer: Shows call duration

View Call History

  1. Navigate to: WhatsApp Calling > WhatsApp Call
  2. Filter by Lead, Company, Date, etc.
  3. Click on a call to view details
  4. Play recordings (if enabled)

πŸ”§ Configuration

Janus Configuration (Production)

⚠️ Critical: Production deployment requires proper NAT traversal configuration following Meta's best practices.

Complete Production Setup Guide: See JANUS_PRODUCTION_SETUP.md for:

  • NAT configuration (nat_1_1_mapping in janus.jcfg)
  • STUN server setup (Meta recommends Google STUN)
  • Firewall rules and port configuration
  • SSL/TLS certificates
  • Systemd service setup
  • Performance tuning
  • TURN server setup (optional)
  • Troubleshooting guide

Quick Production Checklist:

  • βœ“ Set nat_1_1_mapping to your public IP in janus.jcfg
  • βœ“ Start Janus with -S stun.l.google.com:19302
  • βœ“ Open firewall ports: TCP 8088, 8188 and UDP 10000-10200
  • βœ“ Configure public IP in WhatsApp Settings > NAT & WebRTC Configuration
  • βœ“ Enable SSL/TLS for production (HTTPS/WSS required)
  • βœ“ Test WebRTC connection before going live

WhatsApp Template (Call Permission Request)

Create a template in Meta Business Manager:

Template Name: call_permission_request

Content:

Hello! We'd like to call you to discuss your inquiry.
Do you give us permission to call you on WhatsApp?

[Button: Voice Call Request]

Scheduled Tasks

The app includes automated tasks:

  • Hourly: Cleanup old recordings, cleanup stale Janus rooms
  • Daily: Check expired permissions, reset daily counters, send summary email
  • Monthly: Reset monthly usage counters

Configure in hooks.py:

scheduler_events = {
    "hourly": [
        "whatsapp_calling.whatsapp_calling.tasks.cleanup_old_recordings",
        "whatsapp_calling.whatsapp_calling.tasks.cleanup_stale_janus_rooms"
    ],
    "daily": [
        "whatsapp_calling.whatsapp_calling.tasks.check_expired_permissions",
        "whatsapp_calling.whatsapp_calling.tasks.reset_daily_counters"
    ]
}

πŸ“ Project Structure

whatsapp_calling/
β”œβ”€β”€ whatsapp_calling/
β”‚   β”œβ”€β”€ whatsapp_calling/
β”‚   β”‚   β”œβ”€β”€ doctype/
β”‚   β”‚   β”‚   β”œβ”€β”€ whatsapp_call/          # Call records
β”‚   β”‚   β”‚   β”œβ”€β”€ whatsapp_number/        # Business numbers
β”‚   β”‚   β”‚   β”œβ”€β”€ whatsapp_settings/      # Global settings
β”‚   β”‚   β”‚   └── call_permission/        # Permission tracking
β”‚   β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”‚   β”œβ”€β”€ webhook.py              # WhatsApp webhook handler
β”‚   β”‚   β”‚   β”œβ”€β”€ call_control.py         # Call operations
β”‚   β”‚   β”‚   β”œβ”€β”€ permissions.py          # Permission management
β”‚   β”‚   β”‚   └── janus_client.py         # Janus integration
β”‚   β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   β”‚   β”œβ”€β”€ whatsapp_api.py         # WhatsApp API wrapper
β”‚   β”‚   β”‚   └── validators.py           # Validation utilities
β”‚   β”‚   └── tasks.py                    # Background jobs
β”‚   β”œβ”€β”€ public/
β”‚   β”‚   β”œβ”€β”€ js/
β”‚   β”‚   β”‚   β”œβ”€β”€ whatsapp_call_widget.js # WebRTC client
β”‚   β”‚   β”‚   └── lead_call_button.js     # CRM integration
β”‚   β”‚   └── css/
β”‚   β”‚       └── whatsapp_calling.css    # Styling
β”‚   └── hooks.py                        # App configuration
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ setup.py
└── README.md

πŸ” Security & Permissions

Call Permission System

WhatsApp requires explicit permission before making outbound calls:

  • Permission Request Limits:
    • 1 request per 24 hours
    • 2 requests per 7 days
  • Permission Validity: 7 days after grant
  • Call Limits: 5 calls per 24 hours after permission granted

User Permissions

Configure in Frappe:

System Manager: Full access to all doctypes Sales User: Can make calls, view their company's calls

πŸ’° Pricing & Costs

WhatsApp API Pricing (Approximate)

  • Inbound Calls: Free
  • Outbound Calls: ~$0.01 - $0.05 per minute (varies by country)

Cost Tracking

The app automatically calculates and tracks:

  • Per-call costs
  • Daily usage
  • Monthly budgets
  • Company-wise spending

πŸ› Troubleshooting

WebRTC Connection Failed / No Audio

Production NAT Issues (most common):

  • ❌ Symptoms: "Peer connection state: failed" or "No audio during call"
  • βœ“ Solution: See JANUS_PRODUCTION_SETUP.md Section 9 (Troubleshooting)

Common causes:

  1. nat_1_1_mapping not set to public IP in janus.jcfg
  2. Firewall blocking UDP ports (10000-10200)
  3. No STUN server configured
  4. Wrong public IP in WhatsApp Settings

Quick fix:

# 1. Verify Janus is running
curl http://localhost:8088/janus

# 2. Check browser console for ICE candidates
# Look for candidates with your public IP

# 3. Verify NAT configuration in janus.jcfg
grep nat_1_1_mapping /usr/share/janus/etc/janus/janus.jcfg

# 4. Check Janus logs
tail -f /var/log/janus.log | grep -i "dtls\|ice\|webrtc"

Janus Connection Failed

# Check if Janus is running
curl http://localhost:8088/janus

# Check Janus logs
docker logs janus-gateway  # if using Docker
tail -f /var/log/janus.log  # if native install

# Verify ports are open
netstat -tulpn | grep 8088

Webhook Not Receiving Events

  1. Verify webhook URL is accessible publicly
  2. Check Meta webhook configuration
  3. Verify webhook verify token matches
  4. Check Frappe error logs: bench --site [site] logs

Call Permission Not Working

  1. Verify WhatsApp template is approved in Meta
  2. Check template name matches exactly
  3. Verify business number is verified with Meta
  4. Check error logs for API errors

πŸ“Š API Reference

Make Call

frappe.call({
    method: 'whatsapp_calling.whatsapp_calling.api.call_control.make_call',
    args: {
        lead_name: 'LEAD-001',
        mobile_number: '+919876543210'
    }
})

Answer Call

frappe.call({
    method: 'whatsapp_calling.whatsapp_calling.api.call_control.answer_call',
    args: {
        call_id: 'wamid.xxxxx'
    }
})

End Call

frappe.call({
    method: 'whatsapp_calling.whatsapp_calling.api.call_control.end_call',
    args: {
        call_id: 'wamid.xxxxx'
    }
})

Request Permission

frappe.call({
    method: 'whatsapp_calling.whatsapp_calling.api.permissions.request_call_permission',
    args: {
        lead_name: 'LEAD-001',
        mobile_number: '+919876543210'
    }
})

πŸ§ͺ Testing

Test Janus Connection

curl -X POST http://localhost:8088/janus \
  -H "Content-Type: application/json" \
  -d '{"janus": "create", "transaction": "test123"}'

Test Webhook

curl -X GET "https://yoursite.com/api/method/whatsapp_calling.whatsapp_calling.api.webhook.whatsapp_webhook?hub.mode=subscribe&hub.verify_token=YOUR_TOKEN&hub.challenge=test"

Test WhatsApp API

curl -X POST "https://graph.facebook.com/v18.0/PHONE_NUMBER_ID/calls" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"to": "+919876543210", "type": "voice"}'

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature-name
  3. Commit your changes: git commit -am 'Add feature'
  4. Push to the branch: git push origin feature-name
  5. Submit a pull request

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Credits

πŸ“§ Support

For issues and questions:

πŸ—ΊοΈ Roadmap

Phase 1 (Current)

  • βœ… Basic calling from CRM Lead
  • βœ… Call recording
  • βœ… Permission management
  • βœ… Janus integration

Phase 2 (Planned)

  • Call queue management
  • IVR (Interactive Voice Response)
  • Call transfers
  • Conference calls
  • SMS integration

Phase 3 (Future)

  • AI-powered call insights
  • Automatic transcription
  • Sentiment analysis
  • Integration with other CRM modules

πŸ“ˆ Changelog

v0.0.1 (2024-11-07)

  • Initial release
  • Basic calling functionality
  • CRM Lead integration
  • Permission management
  • Call recording
  • Janus Gateway integration

Made with ❀️ for the Frappe/ERPNext community

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages