DEV Community

Cover image for Automate WhatsApp Business Messages with n8n and 360dialog
Raizan
Raizan

Posted on • Originally published at chasebot.online

Automate WhatsApp Business Messages with n8n and 360dialog

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

  1. Understanding the 360dialog Integration
  2. Setting Up Your 360dialog Account
  3. Creating Your First n8n Workflow
  4. Building a Customer Response Bot
  5. Handling Media and Rich Messages
  6. 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:

  1. A WhatsApp Business Account (if you don't have one, WhatsApp will guide you through creation)
  2. A phone number that you control (360dialog will verify this)
  3. API access credentials (API token and Sender ID)

Once you're logged into 360dialog:

  • Navigate to API SettingsToken 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
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure 360dialog Webhook

In your 360dialog dashboard:

  • Go to WebhooksAdd 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()
  }
};
Enter fullscreen mode Exit fullscreen mode

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-TOKEN with 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."
  }
}
Enter fullscreen mode Exit fullscreen mode

Before you save, create a credential in n8n:

  • Click the Credential dropdown in the HTTP Request node
  • Select Create NewGeneric Credential Auth
  • Name it "360dialog API"
  • Leave blank (we're using the custom header instead)

Connect your nodes: WebhookFunctionHTTP 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_text contains "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;
}
Enter fullscreen mode Exit fullscreen mode

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!"
  }
}
Enter fullscreen mode Exit fullscreen mode

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')
Enter fullscreen mode Exit fullscreen mode

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>"
}
Enter fullscreen mode Exit fullscreen mode

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()
  }
};
Enter fullscreen mode Exit fullscreen mode

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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 };
Enter fullscreen mode Exit fullscreen mode

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:

  1. 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.

  2. **Set up your


Originally published on Automation Insider.

Top comments (0)