Tutorial
WhatsApp CRM Integration: Connect Salesforce, HubSpot & Pipedrive
Integrate WhatsApp with your CRM to capture leads, automate follow-ups, and close deals faster. Full code examples for Salesforce, HubSpot, and Pipedrive.
WhatsApp CRM Integration: Connect Salesforce, HubSpot & Pipedrive in 30 Minutes
Meta Description: Integrate WhatsApp with your CRM (Salesforce, HubSpot, Pipedrive) to capture leads, automate follow-ups, and close deals faster. Full code examples, webhook setup, and pipeline automation included.Introduction
Your sales team is losing deals because they're too slow to respond.
The brutal truth about lead response time:- ⏰ 78% of buyers purchase from the company that responds first
- 📉 Response after 5 minutes = 80% drop in lead qualification
- 💀 Response after 30 minutes = lead is practically dead
- 📱 90% of leads prefer messaging over phone calls
WhatsApp CRM integration delivers:
- ⚡ Instant lead capture — new WhatsApp messages auto-create CRM contacts
- 🤖 Automated follow-ups — trigger WhatsApp messages from CRM workflows
- 📊 Full conversation history — every WhatsApp chat logged in the CRM timeline
- 🎯 Pipeline automation — move deals forward based on WhatsApp replies
- 📱 Mobile-first sales — your team responds from WhatsApp, CRM stays updated
- SaaS company: 3x faster lead response time, 40% more demos booked
- Real estate agency: 60% of deals now close via WhatsApp conversations
- E-commerce brand: 25% increase in repeat purchases with WhatsApp follow-ups
- ✅ Connect WhatsApp to Salesforce, HubSpot, or Pipedrive
- ✅ Auto-create CRM contacts from WhatsApp messages
- ✅ Send WhatsApp messages triggered by CRM events
- ✅ Log all conversations in the CRM timeline
- ✅ Build automated sales pipelines with WhatsApp touchpoints
- ✅ Track WhatsApp messaging ROI in your CRM dashboard
Let's turn WhatsApp conversations into closed deals.
Why WhatsApp + CRM Is a Game Changer
The Communication Gap
Most CRM systems were built for email and phone. But your customers are on WhatsApp:
| Channel | Open Rate | Response Time | Customer Preference | |---------|-----------|---------------|-------------------| | Email | 20% | 24-48 hours | Declining | | Phone | N/A | Often ignored | Low (especially Gen Z) | | SMS | 90% | 5 minutes | Medium | | WhatsApp | 98% | < 5 minutes | High (2.7B users) |
The problem: When a lead messages you on WhatsApp, your CRM doesn't know about it. Sales reps juggle between WhatsApp and their CRM, losing context and dropping follow-ups.The solution: Connect WhatsApp to your CRM via webhooks so every conversation is captured, tracked, and actionable.Architecture Overview
Here's how the integration works:
WhatsApp User → WhatsApp API → Webhook → Your Server → CRM API
↑ ↓
└────────── WhatsApp API ←── Your Server ←┘Flow:
1. Customer sends WhatsApp message
2. WhatsApp API forwards message to your webhook
3. Your server processes the message and creates/updates CRM contact
4. CRM triggers automation (e.g., assign to sales rep)
5. Sales rep responds → your server sends response via WhatsApp APIPrerequisites
1. RapidAPI Account — Sign up free 2. Active WhatsApp session — Follow our Getting Started guide 3. CRM account — Salesforce, HubSpot, or Pipedrive (free tiers work) 4. Node.js 18+ or Python 3.9+ 5. Public webhook URL — Use ngrok for development
Setup: WhatsApp Webhook Receiver
First, let's build the webhook server that receives WhatsApp messages:
javascript
// server.js — WhatsApp webhook receiver
const express = require('express');
const app = express();
app.use(express.json());const RAPIDAPI_KEY = process.env.RAPIDAPI_KEY;
const RAPIDAPI_HOST = 'whatsapp-messaging-bot.p.rapidapi.com';
// Store for conversation context
const conversations = new Map();
app.post('/webhook/whatsapp', async (req, res) => {
const { event, payload } = req.body;
console.log(📩 Received event: ${event});
if (event === 'message') {
const { from, body, timestamp } = payload;
const phoneNumber = from.replace('@c.us', '');
console.log(💬 Message from ${phoneNumber}: ${body});
// Route to CRM integration
await handleIncomingMessage(phoneNumber, body, timestamp);
}
res.status(200).json({ status: 'ok' });
});
async function handleIncomingMessage(phone, message, timestamp) {
// Step 1: Check if contact exists in CRM
let contact = await findCRMContact(phone);
// Step 2: Create contact if new
if (!contact) {
contact = await createCRMContact(phone, message);
console.log(✅ New CRM contact created: ${phone});
}
// Step 3: Log the message in CRM
await logMessageInCRM(contact.id, message, 'inbound', timestamp);
// Step 4: Trigger CRM automation
await triggerCRMAutomation(contact, message);
}
app.listen(3000, () => console.log('🚀 Webhook server running on port 3000'));
Integration 1: HubSpot
HubSpot is popular with startups and SMBs. Here's how to connect it:
Create/Find Contacts
javascript
// hubspot-integration.js
const HUBSPOT_TOKEN = process.env.HUBSPOT_ACCESS_TOKEN;async function findHubSpotContact(phone) {
const response = await fetch(
https://api.hubapi.com/crm/v3/objects/contacts/search,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: Bearer ${HUBSPOT_TOKEN},
},
body: JSON.stringify({
filterGroups: [{
filters: [{
propertyName: 'phone',
operator: 'EQ',
value: phone,
}],
}],
}),
}
);
const data = await response.json();
return data.total > 0 ? data.results[0] : null;
}
async function createHubSpotContact(phone, firstMessage) {
const response = await fetch(
'https://api.hubapi.com/crm/v3/objects/contacts',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: Bearer ${HUBSPOT_TOKEN},
},
body: JSON.stringify({
properties: {
phone: phone,
firstname: 'WhatsApp Lead',
lifecyclestage: 'lead',
hs_lead_status: 'NEW',
// Custom property for WhatsApp
whatsapp_first_message: firstMessage,
whatsapp_opted_in: 'true',
},
}),
}
);
return await response.json();
}
Log Messages as Notes
javascript
async function logHubSpotNote(contactId, message, direction, timestamp) {
const noteBody = direction === 'inbound'
? 📥 WhatsApp message received:\n\n"${message}"
: 📤 WhatsApp message sent:\n\n"${message}";
await fetch(
'https://api.hubapi.com/crm/v3/objects/notes',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: Bearer ${HUBSPOT_TOKEN},
},
body: JSON.stringify({
properties: {
hs_note_body: noteBody,
hs_timestamp: new Date(timestamp).toISOString(),
},
associations: [{
to: { id: contactId },
types: [{ associationCategory: 'HUBSPOT_DEFINED', associationTypeId: 202 }],
}],
}),
}
);
}Create Deals from WhatsApp
javascript
async function createHubSpotDeal(contactId, dealName, amount) {
const deal = await fetch(
'https://api.hubapi.com/crm/v3/objects/deals',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: Bearer ${HUBSPOT_TOKEN},
},
body: JSON.stringify({
properties: {
dealname: dealName,
amount: amount,
dealstage: 'appointmentscheduled',
pipeline: 'default',
whatsapp_source: 'true',
},
associations: [{
to: { id: contactId },
types: [{ associationCategory: 'HUBSPOT_DEFINED', associationTypeId: 3 }],
}],
}),
}
);
return await deal.json();
}Integration 2: Salesforce
For enterprise teams using Salesforce:
Setup Salesforce Connected App
javascript
// salesforce-integration.js
const SF_INSTANCE_URL = process.env.SF_INSTANCE_URL;
const SF_ACCESS_TOKEN = process.env.SF_ACCESS_TOKEN;async function sfQuery(soql) {
const response = await fetch(
${SF_INSTANCE_URL}/services/data/v59.0/query?q=${encodeURIComponent(soql)},
{
headers: { Authorization: Bearer ${SF_ACCESS_TOKEN} },
}
);
return await response.json();
}
async function findSalesforceContact(phone) {
// Search by phone number across Contacts and Leads
const result = await sfQuery(
SELECT Id, Name, Phone, Email FROM Contact WHERE Phone = '${phone}' LIMIT 1
);
if (result.totalSize > 0) return result.records[0];
// Check Leads too
const leadResult = await sfQuery(
SELECT Id, Name, Phone, Email FROM Lead WHERE Phone = '${phone}' LIMIT 1
);
return leadResult.totalSize > 0 ? leadResult.records[0] : null;
}
async function createSalesforceLead(phone, message) {
const response = await fetch(
${SF_INSTANCE_URL}/services/data/v59.0/sobjects/Lead,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: Bearer ${SF_ACCESS_TOKEN},
},
body: JSON.stringify({
LastName: WhatsApp Lead (${phone}),
Phone: phone,
LeadSource: 'WhatsApp',
Status: 'New',
Description: First message: ${message},
}),
}
);
return await response.json();
}
async function logSalesforceTask(contactId, message, direction) {
await fetch(
${SF_INSTANCE_URL}/services/data/v59.0/sobjects/Task,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: Bearer ${SF_ACCESS_TOKEN},
},
body: JSON.stringify({
WhoId: contactId,
Subject: WhatsApp ${direction === 'inbound' ? 'Received' : 'Sent'},
Description: message,
Status: 'Completed',
Priority: 'Normal',
Type: 'WhatsApp',
}),
}
);
}
Integration 3: Pipedrive
For sales-focused teams:
javascript
// pipedrive-integration.js
const PIPEDRIVE_TOKEN = process.env.PIPEDRIVE_API_TOKEN;
const PIPEDRIVE_URL = https://api.pipedrive.com/v1;async function findPipedriveContact(phone) {
const response = await fetch(
${PIPEDRIVE_URL}/persons/search?term=${phone}&api_token=${PIPEDRIVE_TOKEN}
);
const data = await response.json();
return data.data?.items?.[0]?.item || null;
}
async function createPipedriveContact(phone, message) {
const response = await fetch(
${PIPEDRIVE_URL}/persons?api_token=${PIPEDRIVE_TOKEN},
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: WhatsApp Lead (${phone}),
phone: [{ value: phone, primary: true }],
// Add to "WhatsApp Leads" label
label: 1,
}),
}
);
return await response.json();
}
async function createPipedriveDeal(personId, title) {
await fetch(
${PIPEDRIVE_URL}/deals?api_token=${PIPEDRIVE_TOKEN},
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: title,
person_id: personId,
stage_id: 1, // First stage of pipeline
}),
}
);
}
async function logPipedriveNote(personId, message, direction) {
const emoji = direction === 'inbound' ? '📥' : '📤';
await fetch(
${PIPEDRIVE_URL}/notes?api_token=${PIPEDRIVE_TOKEN},
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
content: ${emoji} WhatsApp ${direction}
${message},
person_id: personId,
}),
}
);
}
Sending WhatsApp Messages from Your CRM
When a sales rep wants to respond, trigger a WhatsApp message from the CRM:
javascript
// send-whatsapp.js
async function sendWhatsAppMessage(phone, text) {
const response = await fetch(
'https://whatsapp-messaging-bot.p.rapidapi.com/api/v1/messages/sendText',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-RapidAPI-Key': process.env.RAPIDAPI_KEY,
'X-RapidAPI-Host': 'whatsapp-messaging-bot.p.rapidapi.com',
},
body: JSON.stringify({
session: 'default',
to: phone,
text: text,
}),
}
);
const result = await response.json();
console.log(📤 Message sent to ${phone});
return result;
}// Automated follow-up sequences
async function sendFollowUpSequence(contact) {
const sequences = {
new_lead: [
{ delay: 0, message: Hi ${contact.name}! Thanks for reaching out. How can we help you today? },
{ delay: 24 * 60, message: Hi ${contact.name}, just following up. Did you have a chance to look at our offerings? Happy to answer any questions! },
{ delay: 72 * 60, message: Hi ${contact.name}, I noticed you showed interest in our product. Would you like to schedule a quick demo? It takes just 15 minutes. },
],
demo_booked: [
{ delay: 0, message: Great! Your demo is confirmed for ${contact.demoDate}. Looking forward to it! 📅 },
{ delay: -60, message: Reminder: Your demo starts in 1 hour. Here's the meeting link: ${contact.meetingLink} },
],
};
const sequence = sequences[contact.stage] || sequences.new_lead;
for (const step of sequence) {
if (step.delay === 0) {
await sendWhatsAppMessage(contact.phone, step.message);
} else {
// Schedule for later (use your preferred scheduler)
scheduleMessage(contact.phone, step.message, step.delay);
}
}
}
Automated Pipeline Workflows
Lead Qualification via WhatsApp
javascript
// qualification-bot.js
const qualificationQuestions = [
{ key: 'budget', question: "What's your approximate monthly budget for this solution?", options: ['Under $100', '$100-$500', '$500-$2000', '$2000+'] },
{ key: 'timeline', question: 'When are you looking to implement?', options: ['This week', 'This month', 'Next quarter', 'Just researching'] },
{ key: 'team_size', question: 'How large is your team?', options: ['Just me', '2-10', '11-50', '50+'] },
];async function handleQualification(contact, message) {
const state = conversations.get(contact.phone) || { step: 0, answers: {} };
if (state.step < qualificationQuestions.length) {
const currentQ = qualificationQuestions[state.step];
// Save answer
state.answers[currentQ.key] = message;
state.step++;
if (state.step < qualificationQuestions.length) {
// Ask next question
const nextQ = qualificationQuestions[state.step];
const optionsList = nextQ.options.map((o, i) => ${i + 1}. ${o}).join('\n');
await sendWhatsAppMessage(
contact.phone,
${nextQ.question}\n\n${optionsList}\n\nReply with the number of your choice.
);
} else {
// Qualification complete — update CRM
await updateCRMQualification(contact, state.answers);
await sendWhatsAppMessage(
contact.phone,
Thanks for the info! I'm connecting you with a specialist who can help. They'll reach out shortly. 🚀
);
}
conversations.set(contact.phone, state);
}
}
async function updateCRMQualification(contact, answers) {
// Calculate lead score
const scoreMap = {
budget: { 'Under $100': 1, '$100-$500': 2, '$500-$2000': 3, '$2000+': 4 },
timeline: { 'This week': 4, 'This month': 3, 'Next quarter': 2, 'Just researching': 1 },
team_size: { 'Just me': 1, '2-10': 2, '11-50': 3, '50+': 4 },
};
let score = 0;
for (const [key, value] of Object.entries(answers)) {
score += scoreMap[key]?.[value] || 0;
}
// Update HubSpot (or your CRM)
await fetch(
https://api.hubapi.com/crm/v3/objects/contacts/${contact.id},
{
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
Authorization: Bearer ${process.env.HUBSPOT_ACCESS_TOKEN},
},
body: JSON.stringify({
properties: {
hs_lead_status: score >= 8 ? 'QUALIFIED' : 'IN_PROGRESS',
whatsapp_lead_score: String(score),
whatsapp_budget: answers.budget,
whatsapp_timeline: answers.timeline,
whatsapp_team_size: answers.team_size,
},
}),
}
);
}
Production Deployment
Docker Setup
dockerfile
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]Environment Variables
env
WhatsApp API
RAPIDAPI_KEY=your_key
RAPIDAPI_HOST=whatsapp-messaging-bot.p.rapidapi.com
WHATSAPP_SESSION=crm-botCRM (choose one)
HUBSPOT_ACCESS_TOKEN=pat-xxx
SF_INSTANCE_URL=https://yourorg.my.salesforce.com
SF_ACCESS_TOKEN=xxx
PIPEDRIVE_API_TOKEN=xxx
Server
PORT=3000
WEBHOOK_SECRET=your_webhook_secretMeasuring ROI
Track these metrics in your CRM dashboard:
| Metric | Before WhatsApp | After WhatsApp | Improvement | |--------|----------------|----------------|-------------| | Lead response time | 2-4 hours | < 5 minutes | 48x faster | | Lead-to-demo rate | 8% | 22% | +175% | | Demo-to-close rate | 25% | 35% | +40% | | Customer satisfaction | 3.2/5 | 4.6/5 | +44% | | Follow-up completion | 40% | 95% | +138% |
Next Steps
1. Start simple: Connect WhatsApp webhooks to your CRM → auto-create contacts 2. Add logging: Log all WhatsApp messages as CRM notes/activities 3. Automate responses: Build a simple qualification bot 4. Scale up: Add follow-up sequences and pipeline automation 5. Measure: Track conversion rates from WhatsApp leads vs. other channels
Related Resources
- How to Send WhatsApp Messages from Node.js
- Build a WhatsApp Chatbot with Python
- WhatsApp Customer Support Bot Guide
- WhatsApp API Documentation
- Free WhatsApp Message Template Builder
Ready to connect WhatsApp to your CRM? Get your free API key on RapidAPI and start building in 5 minutes. No approval process, no waiting — scan a QR code and go.
Ready to Get Started?
Try the WhatsApp API free on RapidAPI with no credit card required.
Try Free on RapidAPI