Blog/Tutorials

How to Integrate WhatsApp API with Salesforce CRM

Integrate WhatsApp messaging into Salesforce CRM using Rapiwa API and n8n. Send WhatsApp messages from Salesforce flows, log messages as activities, and automate lead follow-ups.

by Maya
How to Integrate WhatsApp API with Salesforce CRM

You can integrate WhatsApp messaging into Salesforce CRM by connecting Rapiwa API to Salesforce using Apex callouts, Salesforce Flow with External Services, or n8n as middleware. When a lead is created, a deal stage changes, or a Flow fires, Rapiwa sends a WhatsApp message to the contact's phone. Rapiwa costs $5/month flat with no per-message fees — a fraction of Salesforce's native messaging add-ons.

What You Can Automate

  • Lead follow-up: WhatsApp message to new leads within 5 minutes of form submission
  • Opportunity stage: Notify reps when a deal moves to "Negotiation" stage
  • Meeting reminders: WhatsApp reminder 1 hour before Salesforce-scheduled meetings
  • Contract sent: Message prospects immediately when a DocuSign contract is sent
  • Renewal alerts: WhatsApp reminders 30/7/1 days before subscription renewals

Prerequisites

  • Rapiwa account (free 3-day trial at rapiwa.com)
  • Salesforce org (Developer Edition or higher)
  • n8n (Cloud free tier or self-hosted) — recommended for no-code approach
  • Salesforce Connected App credentials (for API access)

Architecture Options

Option A (Recommended): Salesforce Flow → Webhook → n8n → Rapiwa

Salesforce Flow → Outbound Message/Webhook → n8n → Rapiwa API → WhatsApp

Best for: Non-developers, admins building without code

Option B: Apex Callout → Rapiwa

Salesforce Trigger (Apex) → HttpRequest → Rapiwa API → WhatsApp

Best for: Developers with Salesforce experience

Method 1: Using n8n as Middleware (No-Code)

Step 1: Create an n8n Webhook

  1. In n8n, create a new workflow
  2. Add a Webhook trigger node
  3. Copy the webhook URL (e.g. https://yourn8n.cloud/webhook/salesforce-whatsapp)

Step 2: Configure Salesforce Flow to Call Webhook

In Salesforce Setup → Flow Builder:

  1. Create a Record-Triggered Flow
  2. Trigger: When a record is created on Lead object
  3. Add action: HTTP Callout (requires Salesforce External Services setup)
  4. Or use: Apex Action (custom code) → calls n8n webhook URL

Simpler approach — Salesforce Outbound Messages:

  1. Setup → Workflow Rules → Create rule for Lead: Created
  2. Add action: Outbound Message → URL: https://yourn8n.cloud/webhook/salesforce-whatsapp
  3. Include fields: Lead.Phone, Lead.FirstName, Lead.LastName, Lead.Email

Step 3: n8n Processes the Salesforce Event

In n8n:

  1. Webhook node receives the Salesforce outbound message
  2. Set node extracts phone and builds message
  3. HTTP Request (Rapiwa) sends WhatsApp

HTTP Request configuration:

{
  "method": "POST",
  "url": "https://app.rapiwa.com/send-message",
  "headers": {
    "Authorization": "Bearer YOUR_API_KEY"
  },
  "body": {
    "number": "={{ $json.body.sObjects.sObject.Phone }}",
    "message": "Hi {{ $json.body.sObjects.sObject.FirstName }}! Thanks for your interest. I'm Alex from [Company] — when's a good time to chat this week?"
  }
}

Test cURL:

curl -X POST https://app.rapiwa.com/send-message \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "number": "8801234567890",
    "message": "Hi Sarah! Thanks for your inquiry. I would love to connect — would you have 15 minutes this week for a quick call?"
  }'

Expected response:

{
  "status": "success",
  "messageId": "msg_sf_abc123",
  "timestamp": "2026-07-01T10:30:00Z"
}

Method 2: Apex Callout (Developer Approach)

Step 1: Whitelist Rapiwa in Remote Site Settings

In Salesforce Setup → Security → Remote Site Settings:

  • Click New Remote Site
  • Remote Site Name: RapiwaAPI
  • Remote Site URL: https://app.rapiwa.com
  • Active: ✓

Step 2: Create an Apex Class for Rapiwa

// RapiwaService.cls
public class RapiwaService {
    
    private static final String API_URL = 'https://app.rapiwa.com/send-message';
    private static final String API_KEY = 'YOUR_API_KEY'; // Store in Custom Settings or Named Credentials in production
    
    /**
     * Send a WhatsApp message via Rapiwa API.
     * Uses @future for async execution to avoid DML + callout order issues.
     */
    @future(callout=true)
    public static void sendWhatsAppAsync(String phone, String message) {
        HttpRequest req = new HttpRequest();
        req.setEndpoint(API_URL);
        req.setMethod('POST');
        req.setHeader('Authorization', 'Bearer ' + API_KEY);
        req.setHeader('Content-Type', 'application/json');
        req.setTimeout(15000); // 15 second timeout
        
        // Build JSON body
        Map<String, String> body = new Map<String, String>{
            'number' => phone,
            'message' => message
        };
        req.setBody(JSON.serialize(body));
        
        try {
            Http http = new Http();
            HttpResponse res = http.send(req);
            
            Map<String, Object> responseBody = 
                (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
            
            String status = (String) responseBody.get('status');
            
            if (res.getStatusCode() == 200 && 'success'.equals(status)) {
                System.debug('WhatsApp sent to ' + phone + ': ' + responseBody.get('messageId'));
            } else {
                System.debug('Rapiwa error: ' + res.getBody());
            }
            
        } catch (CalloutException e) {
            System.debug('Callout failed: ' + e.getMessage());
        }
    }
    
    /**
     * Convenience method: send order confirmation
     */
    public static void sendOrderConfirmation(String phone, String customerName, String orderId, Decimal orderTotal) {
        String message = 'Hi ' + customerName + '! ✅\n\n'
            + 'Your order #' + orderId + ' is confirmed.\n'
            + 'Total: $' + orderTotal.setScale(2).toPlainString() + '\n\n'
            + 'We will be in touch shortly!';
        
        sendWhatsAppAsync(phone, message);
    }
}

Step 3: Create an Apex Trigger

// LeadTrigger.trigger
trigger LeadTrigger on Lead (after insert) {
    for (Lead lead : Trigger.new) {
        if (lead.Phone != null) {
            // Format phone: remove +, spaces, dashes
            String phone = lead.Phone.replaceAll('[^0-9]', '');
            
            String message = 'Hi ' + lead.FirstName + '! 👋\n\n'
                + 'Thanks for reaching out to us. I am '
                + UserInfo.getName()
                + ' from [Company Name].\n\n'
                + 'Would you have 15 minutes for a quick call this week? '
                + 'Reply YES and I will send you a calendar link!';
            
            RapiwaService.sendWhatsAppAsync(phone, message);
        }
    }
}

Step 4: Store API Key Securely (Named Credentials)

Instead of hardcoding the API key, use Salesforce Named Credentials:

  1. Setup → Security → Named Credentials
  2. New Named Credential:
    • Label: Rapiwa API
    • URL: https://app.rapiwa.com
    • Identity Type: Named Principal
    • Authentication Protocol: Password Authentication
    • Username: api (any value)
    • Password: YOUR_API_KEY
  3. In Apex, use:
req.setEndpoint('callout:RapiwaAPI/send-message');
req.setHeader('Authorization', 'Bearer ' + 
    [SELECT Value__c FROM Rapiwa_Settings__c LIMIT 1].Value__c);

Log WhatsApp Messages as Salesforce Activities

After sending a WhatsApp message, create a Task in Salesforce to log it:

// In your Apex class (after callout succeeds)
Task task = new Task(
    Subject = 'WhatsApp Message Sent',
    Description = 'Message: ' + message,
    WhoId = lead.Id,
    ActivityDate = Date.today(),
    Status = 'Completed',
    Type = 'WhatsApp'
);
insert task;

Common Errors and Fixes

  • System.CalloutException: You have uncommitted work pending: You can't make a callout after a DML operation in the same transaction. Use @future(callout=true) to run the callout asynchronously.
  • CALLOUT_FAILURE: The endpoint URL is not in Remote Site Settings. Add https://app.rapiwa.com to Remote Site Settings.
  • 401 Unauthorized: API key is wrong. Store it in a Custom Setting or Named Credential and reference it from there.
  • Phone number format issues: Salesforce may store numbers with +, spaces, or dashes. Strip them: phone.replaceAll('[^0-9]', '')

FAQ

Does Salesforce have a native WhatsApp integration? Salesforce offers WhatsApp through Salesforce Messaging (part of Service Cloud) using Meta's official WhatsApp Business Platform. This requires Meta business verification and has per-conversation fees. Rapiwa provides an alternative at $5/month flat without official verification.

Can I use Rapiwa with Salesforce Einstein AI flows? Yes. Einstein Bots and Salesforce Flow can both trigger Apex actions or HTTP callouts that send data to Rapiwa's API.

Does Rapiwa charge per WhatsApp message from Salesforce? No. Rapiwa charges $5/month flat with no per-message fees — send unlimited CRM-triggered messages.

Can I receive WhatsApp replies back into Salesforce? Yes. Set up a Rapiwa webhook pointing to a public endpoint that creates Salesforce records (via the Salesforce REST API). This closes the loop — incoming replies become Salesforce Tasks.

What is the Salesforce governor limit for HTTP callouts? Salesforce allows 100 HTTP callout statements per Apex transaction. For bulk operations (many leads at once), use @future or Queueable Apex to stay within limits.