What You'll Need
- n8n Cloud or self-hosted n8n
- Hetzner VPS or Contabo VPS for self-hosting
- 360dialog account (free tier available)
- WhatsApp Business Account
- Basic understanding of webhooks and HTTP requests
Table of Contents
- Understanding the 360dialog Integration
- Setting Up Your 360dialog Account
- Creating Your First n8n Workflow
- Building a Customer Response Bot
- Handling Media and Rich Messages
- Getting Started
Understanding the 360dialog Integration
I've been automating customer communication for years, and WhatsApp Business integration has become one of the most requested features. Why? Because 90% of your customers probably use WhatsApp already, and reaching them there means higher engagement and faster response times.
360dialog is a WhatsApp Business Solution Provider that gives you API access to send and receive WhatsApp messages at scale. When you combine it with n8n, you can build powerful automations without touching a line of backend code.
Here's what you can do:
- Send automated messages when customers sign up
- Build intelligent chat flows that route to the right team
- Track conversation metadata and customer interactions
- Integrate with your CRM or database
- Create keyword-triggered responses
The beauty of this setup is that it works whether you run n8n Cloud or self-host on a VPS. Both approaches have trade-offs—Cloud is faster to deploy, but self-hosting gives you full control and lower costs at scale.
Setting Up Your 360dialog Account
First, sign up for 360dialog at their platform. You'll need:
- A WhatsApp Business Account (if you don't have one, WhatsApp will guide you through creation)
- A phone number that you control (360dialog will verify this)
- API access credentials (API token and Sender ID)
Once you're logged into 360dialog:
- Navigate to API Settings → Token Management
- Generate a new API token—this is what you'll use in n8n
- Copy your Sender ID (the phone number in international format without the + sign)
- Note your API Base URL (usually
https://waba.360dialog.io)
Keep these credentials safe. You'll paste them into n8n in the next section.
Creating Your First n8n Workflow
Let me walk you through building a simple workflow that sends a welcome message whenever a customer sends their first message to your WhatsApp Business number.
Open n8n and create a new workflow. We'll start with a webhook trigger to receive incoming messages from 360dialog.
Step 1: Add the Webhook Trigger
Click + → Search for Webhook → Select the Webhook node.
In the node settings:
- Leave Authentication as "None" (we'll secure this differently)
- Click the Listen button to activate the webhook
- Copy the webhook URL—you'll paste this into 360dialog
The webhook URL will look like:
https://your-n8n-instance.com/webhook/whatsapp-incoming
Step 2: Configure 360dialog Webhook
In your 360dialog dashboard:
- Go to Webhooks → Add Webhook
- Paste your n8n webhook URL
- Set the webhook events to receive:
-
messages(incoming messages) -
message_status(delivery receipts)
-
360dialog will send a verification request to your webhook. n8n handles this automatically.
Step 3: Parse the Incoming Message
Add a Function node to extract the message data. Click + → Search for Function.
Paste this code:
const message = $input.first().json;
const senderPhone = message.contacts[0].wa_id;
const messageText = message.messages[0].text.body;
const messageType = message.messages[0].type;
const messageId = message.messages[0].id;
return {
json: {
sender: senderPhone,
text: messageText,
type: messageType,
messageId: messageId,
timestamp: new Date().toISOString()
}
};
Step 4: Send a Welcome Response
Add an HTTP Request node to send the message back via 360dialog's API.
Configure it as follows:
- Method: POST
-
URL:
https://waba.360dialog.io/v1/messages - Authentication: Generic Credential Auth (you'll set this below)
-
Headers: Add a header
D360-API-TOKENwith your 360dialog API token
In the Body tab, set it to JSON and paste:
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "{{ $node[\"Function\"].json.sender }}",
"type": "text",
"text": {
"body": "Thanks for messaging us! We'll respond shortly."
}
}
Before you save, create a credential in n8n:
- Click the Credential dropdown in the HTTP Request node
- Select Create New → Generic Credential Auth
- Name it "360dialog API"
- Leave blank (we're using the custom header instead)
Connect your nodes: Webhook → Function → HTTP Request
Test it by sending a message to your WhatsApp Business number from your phone. You should see the welcome message come back immediately.
💡 Fast-Track Your Project: Don't want to configure this yourself? I build custom n8n pipelines and bots. Message me with code SYS3-DEVTO.
Building a Customer Response Bot
Now let's add intelligence. You'll create a workflow that routes messages based on keywords and stores conversation history.
Add Conditional Logic
After the Function node, insert a new IF node to check the message content.
-
Condition:
message_textcontains "pricing" - True branch: Send pricing information
- False branch: Send to a human queue
Here's how to set it up:
const text = $node["Function"].json.text.toLowerCase();
if (text.includes("pricing") || text.includes("price") || text.includes("cost")) {
return true;
} else if (text.includes("hours") || text.includes("support") || text.includes("help")) {
return true;
} else {
return false;
}
For the "Pricing" Branch
Add another HTTP Request node that sends your pricing info:
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "{{ $node[\"Function\"].json.sender }}",
"type": "text",
"text": {
"body": "Our plans start at $29/month. We offer:\n• Starter: $29\n• Pro: $79\n• Enterprise: Custom\n\nReply with 'demo' to schedule a call!"
}
}
For the Default Branch
Create a Database node (or use a Google Sheet) to log unhandled messages:
If you're using n8n self-hosted on a VPS, you can connect directly to a PostgreSQL database. Add a Postgres node:
- Query: INSERT mode
-
Table:
whatsapp_messages - Columns: sender, message_text, message_type, timestamp, status
INSERT INTO whatsapp_messages (sender, message_text, message_type, timestamp, status)
VALUES ($1, $2, $3, $4, 'pending_review')
Then send a Slack or Email notification to your team:
Add an Email node:
{
"to": "support@yourcompany.com",
"subject": "New WhatsApp message from {{ $node[\"Function\"].json.sender }}",
"html": "<p>Message: {{ $node[\"Function\"].json.text }}</p><p>Requires manual response</p>"
}
Handling Media and Rich Messages
WhatsApp messages can include images, documents, and location data. Let's handle those.
Modify your Function node to detect media:
const message = $input.first().json;
const senderPhone = message.contacts[0].wa_id;
const messageObj = message.messages[0];
const messageType = messageObj.type;
let mediaUrl = null;
let mediaType = null;
if (messageType === "image") {
mediaUrl = messageObj.image.link;
mediaType = "image";
} else if (messageType === "document") {
mediaUrl = messageObj.document.link;
mediaType = "document";
} else if (messageType === "audio") {
mediaUrl = messageObj.audio.link;
mediaType = "audio";
} else if (messageType === "location") {
return {
json: {
sender: senderPhone,
type: "location",
latitude: messageObj.location.latitude,
longitude: messageObj.location.longitude,
timestamp: new Date().toISOString()
}
};
}
return {
json: {
sender: senderPhone,
text: messageObj.text ? messageObj.text.body : null,
type: messageType,
mediaUrl: mediaUrl,
mediaType: mediaType,
messageId: messageObj.id,
timestamp: new Date().toISOString()
}
};
To send media in your response, use this HTTP Request body:
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "{{ $node[\"Function\"].json.sender }}",
"type": "image",
"image": {
"link": "https://example.com/product-image.jpg"
}
}
For documents:
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "{{ $node[\"Function\"].json.sender }}",
"type": "document",
"document": {
"link": "https://example.com/invoice.pdf",
"caption": "Your Invoice"
}
}
Bonus: Track Conversation Metadata
If you want to understand which conversations convert, add a Set node before each response to capture analytics:
const metadata = {
sender: $node["Function"].json.sender,
message_count: ($node["Get Message Count"].json.count || 0) + 1,
first_message_time: $node["Get First Message"].json.timestamp,
time_since_first: Math.round((new Date() - new Date($node["Get First Message"].json.timestamp)) / 1000),
last_response_type: "pricing_inquiry",
responded_at: new Date().toISOString()
};
return { json: metadata };
Store this in your database. Over time, you'll see patterns in which conversations lead to sales.
Getting Started
Here's how to launch this in production:
Decide on hosting: If you're running multiple workflows or expect high volume, self-hosting on Hetzner or Contabo will save you money. For simpler setups, n8n Cloud is plug-and-play.
**Set up your
Originally published on Automation Insider.
Top comments (0)