Skip to main content
Skip to article

#n8n: Auto-Reply to WhatsApp Groups Intelligently

Two hundred members. Same questions daily. "What are your hours?" "Where's the address?" "How do I register?"

Pinned messages? Nobody reads them. Manual replies? Full-time job. Auto-replies with n8n webhooks and MoltFlow group monitoring? Instant answers. Zero effort.

The workflow: MoltFlow watches your group, detects keywords via webhook events, routes to the correct FAQ response via n8n Switch logic, rate-limits duplicate answers (don't spam the group), escalates "help"/"problem" keywords to Slack/email, logs everything for analytics.

One-hour setup. Runs forever. Works with 500+ n8n integrations for CRM updates, payment processing, booking systems—all triggered by WhatsApp group messages.

Why Auto-Reply to Groups?

WhatsApp groups are chaos. Hundreds of messages per day, most of them repeating the same questions or concerns.

The problem? If you don't respond fast, people assume you're ignoring them. They leave the group. They complain. They tell others your support sucks.

But you can't realistically monitor a group 24/7. You've got other work.

Auto-replies solve this. They acknowledge messages instantly, provide answers to common questions, and escalate complex issues to your team. Everyone feels heard. You're not glued to your phone.

Here's what you can automate:

  • FAQ responses: Keywords like "hours", "location", "pricing" trigger instant answers
  • Registration/signup flows: Detect "register" or "join", send link to form
  • Support escalation: Keywords like "problem", "broken", "help" notify your support team
  • Event reminders: Someone asks "when is the event?", workflow sends details
  • Order status: "Where's my order?" triggers lookup and response with tracking info

The key is smart routing. Not every message needs a response. Not every response should be automated. You build rules for when to reply, when to stay silent, and when to escalate.

Prerequisites

Before building the workflow, make sure you have:

  • MoltFlow account with group monitoring enabled (sign up here)
  • n8n instance (self-hosted or n8n.cloud) — installation guide
  • WhatsApp group you want to monitor (you must be admin or owner)
  • Group ID from MoltFlow dashboard

If you're new to MoltFlow + n8n, start here: Connect MoltFlow to n8n: WhatsApp Automation Without Code

How Group Monitoring Works

MoltFlow can monitor specific WhatsApp groups and forward messages to your webhook in real-time.

Here's the flow:

  1. Someone sends message to your WhatsApp group
  2. MoltFlow receives the message (because group monitoring is enabled)
  3. MoltFlow POSTs message data to your n8n webhook
  4. n8n workflow processes the message and decides: respond, escalate, or ignore
  5. If responding, n8n calls MoltFlow API to send reply back to group

The entire round trip takes under 2 seconds. Fast enough that it feels instant to users.

Step 1: Enable Group Monitoring in MoltFlow

First, tell MoltFlow which group to monitor.

Get Your Group ID

In MoltFlow Dashboard, go to GroupsMonitored Groups. You'll see a list of all groups your WhatsApp session is part of.

Find the group you want to monitor. Copy its Group ID — it looks like this:

That @g.us suffix indicates it's a group (individual chats use @c.us).

Create Group Monitor

Click "Monitor New Group" and select your group from the dropdown.

Settings:

  • Monitor incoming messages: Enabled
  • Forward to webhook: We'll configure this in the next step
  • Filter keywords (optional): Leave blank for now — we'll handle filtering in n8n

Save the configuration.

Step 2: Create n8n Webhook

Your n8n workflow needs a webhook endpoint to receive group messages from MoltFlow.

Add Webhook Node

In n8n, create a new workflow. Add a Webhook node at the start.

Configuration:

  • HTTP Method: POST
  • Path: whatsapp-group-messages
  • Response Mode: Last Node
  • Response Code: 200

Activate the workflow (even though it's incomplete). n8n generates your webhook URL:

text
https://your-n8n.com/webhook/whatsapp-group-messages

Copy this URL.

Configure MoltFlow Webhook

Back in MoltFlow Dashboard → WebhooksCreate Webhook:

URL: Paste your n8n webhook URL

Events:

  • message (incoming messages only)

Sessions: Select your WhatsApp session

Groups: Select the group you're monitoring

Save the webhook. Now every message in that group gets forwarded to your n8n workflow.

Step 3: Parse Group Message

When MoltFlow sends a group message to your webhook, the payload looks like this:

json
{
  "event": "message",
  "session": "my-session",
  "payload": {
    "id": "msg_abc123",
    "from": "[email protected]",
    "fromName": "John Doe",
    "chatId": "[email protected]",
    "body": "What are your office hours?",
    "timestamp": "2026-02-01T10:15:00Z",
    "type": "chat",
    "isGroupMessage": true
  }
}

Key fields:

  • from: Who sent the message (individual user ID)
  • fromName: Display name of the sender
  • chatId: The group ID (this is where replies go)
  • body: The actual message text
  • isGroupMessage: Always true for group messages

Add Set Node to Extract Fields

After the Webhook node, add a Set node named "Parse Group Message".

Fields to extract:

Field NameExpressionPurpose
sender={{ $json.payload.fromName }}Who asked the question
senderPhone={{ $json.payload.from }}Sender's phone ID
groupId={{ $json.payload.chatId }}Where to send reply
message={{ $json.payload.body.toLowerCase() }}Normalize for keyword matching
originalMessage={{ $json.payload.body }}Keep original for logging
timestamp={{ $json.payload.timestamp }}When message arrived
session={{ $json.session }}Which WhatsApp session

Lowercasing the message (toLowerCase()) makes keyword matching easier — "HOURS" and "hours" both match "hours".

Step 4: Build Reply Logic with Switch Node

Now comes the interesting part: routing messages based on keywords.

Add a Switch node after the Set node. This routes the message to different responses depending on content.

Mode: Rules

Configure Rules

Each rule checks for specific keywords and routes to a different response.

Rule 1: Hours/Schedule

Condition:

javascript
{{ $json.message.match(/\b(hours|schedule|open|close|timing)\b/gi) }}

Output: Route to "Send Hours Info" node

Rule 2: Location/Address

Condition:

javascript
{{ $json.message.match(/\b(address|location|where|directions|map)\b/gi) }}

Output: Route to "Send Location Info" node

Rule 3: Pricing

Condition:

javascript
{{ $json.message.match(/\b(price|pricing|cost|how much|fees)\b/gi) }}

Output: Route to "Send Pricing Info" node

Rule 4: Registration/Signup

Condition:

javascript
{{ $json.message.match(/\b(register|sign up|signup|join|enroll)\b/gi) }}

Output: Route to "Send Registration Link" node

Rule 5: Support/Problems

Condition:

javascript
{{ $json.message.match(/\b(problem|issue|help|broken|error|bug)\b/gi) }}

Output: Route to "Escalate to Support" node

Default (no match):

  • Route to "Log Message" node (don't respond, just log for analytics)

The \b in regex ensures whole-word matching. "price" matches but "appreciated" doesn't (even though it contains "price").

Step 5: Create Response Nodes

For each Switch rule output, create an HTTP Request node that sends a reply via MoltFlow API.

HTTP Request Node Template

All response nodes use the same basic structure:

Authentication: Header Auth

  • Name: X-API-Key
  • Value: Your MoltFlow API key

Method: POST

URL: https://apiv2.waiflow.app/api/v2/sessions/{{ $json.session }}/messages

Body (JSON):

json
{
  "chatId": "={{ $json.groupId }}",
  "text": "Your response text here"
}

Example: Send Hours Info Node

Body:

json
{
  "chatId": "={{ $json.groupId }}",
  "text": "📍 Our office hours:\n\nMonday-Friday: 9am - 6pm EST\nSaturday: 10am - 4pm EST\nSunday: Closed\n\nNeed help outside these hours? Email [email protected]"
}

Example: Send Pricing Info Node

Body:

json
{
  "chatId": "={{ $json.groupId }}",
  "text": "💵 Pricing:\n\nBasic Plan: $29/month\nPro Plan: $99/month\nEnterprise: Custom pricing\n\nFull details: https://yoursite.com/pricing\n\nQuestions? Reply with 'pricing question' and our team will help!"
}

Example: Send Registration Link Node

Body:

json
{
  "chatId": "={{ $json.groupId }}",
  "text": "✅ Register here: https://yoursite.com/register\n\nTakes 2 minutes. You'll get confirmation email immediately.\n\nProblems registering? Let us know!"
}

Example: Escalate to Support Node

This one sends TWO messages: one to the group (acknowledgment) and one to your support team (notification).

Group Reply:

json
{
  "chatId": "={{ $json.groupId }}",
  "text": "🔧 Thanks for reporting that, {{ $json.sender }}. Our support team has been notified and will investigate ASAP.\n\nUrgent? Email [email protected] directly."
}

Then add a Slack or Email node after this to notify your team:

Slack Message:

text
🚨 Support Request from Group

*From:* {{ $json.sender }} ({{ $json.senderPhone }})
*Group:* {{ $json.groupId }}
*Message:* {{ $json.originalMessage }}
*Time:* {{ $json.timestamp }}

Acknowledgment sent to group. Please follow up!

Step 6: Add Rate Limiting

Here's the thing: you don't want to spam the group with auto-replies.

If 10 people ask "what are your hours?" within 5 minutes, you don't want 10 identical responses. That looks robotic and annoys everyone.

Solution: rate limiting with n8n's built-in memory.

Add Code Node Before Sending Reply

Insert a Code node between the Switch and HTTP Request nodes. This checks if you've recently sent this type of response.

javascript
const replyType = $input.first().json.replyType; // e.g., "hours", "pricing"
const groupId = $input.first().json.groupId;

// Check last response time from workflow static data
const lastSent = $getWorkflowStaticData('node')[`${groupId}_${replyType}`] || 0;
const now = Date.now();

// Rate limit: only send same reply once every 30 minutes
const cooldown = 30 * 60 * 1000; // 30 minutes in milliseconds

if (now - lastSent < cooldown) {
  // Too soon, skip this reply
  return { skip: true };
}

// Update last sent timestamp
$getWorkflowStaticData('node')[`${groupId}_${replyType}`] = now;

return { skip: false };

Then add an If node after this Code node:

Condition: {{ !$json.skip }}

Only the true path goes to the HTTP Request node. The false path logs to a spreadsheet for analytics but doesn't send a reply.

Complete n8n Workflow JSON

Here's the full workflow you can import:

json
{
  "name": "WhatsApp Group Auto-Reply - MoltFlow",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "whatsapp-group-messages",
        "responseMode": "lastNode"
      },
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [250, 400]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "sender",
              "value": "={{ $json.payload.fromName }}"
            },
            {
              "name": "senderPhone",
              "value": "={{ $json.payload.from }}"
            },
            {
              "name": "groupId",
              "value": "={{ $json.payload.chatId }}"
            },
            {
              "name": "message",
              "value": "={{ $json.payload.body.toLowerCase() }}"
            },
            {
              "name": "originalMessage",
              "value": "={{ $json.payload.body }}"
            },
            {
              "name": "timestamp",
              "value": "={{ $json.payload.timestamp }}"
            },
            {
              "name": "session",
              "value": "={{ $json.session }}"
            }
          ]
        }
      },
      "name": "Parse Group Message",
      "type": "n8n-nodes-base.set",
      "position": [450, 400]
    },
    {
      "parameters": {
        "rules": {
          "rules": [
            {
              "conditions": {
                "string": [
                  {
                    "value1": "={{ $json.message }}",
                    "operation": "regex",
                    "value2": "\\b(hours|schedule|open|close|timing)\\b"
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "hours"
            },
            {
              "conditions": {
                "string": [
                  {
                    "value1": "={{ $json.message }}",
                    "operation": "regex",
                    "value2": "\\b(address|location|where|directions|map)\\b"
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "location"
            },
            {
              "conditions": {
                "string": [
                  {
                    "value1": "={{ $json.message }}",
                    "operation": "regex",
                    "value2": "\\b(price|pricing|cost|how much|fees)\\b"
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "pricing"
            },
            {
              "conditions": {
                "string": [
                  {
                    "value1": "={{ $json.message }}",
                    "operation": "regex",
                    "value2": "\\b(register|sign up|signup|join|enroll)\\b"
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "registration"
            },
            {
              "conditions": {
                "string": [
                  {
                    "value1": "={{ $json.message }}",
                    "operation": "regex",
                    "value2": "\\b(problem|issue|help|broken|error|bug)\\b"
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "support"
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "name": "Route by Keyword",
      "type": "n8n-nodes-base.switch",
      "position": [650, 400]
    },
    {
      "parameters": {
        "authentication": "headerAuth",
        "url": "https://apiv2.waiflow.app/api/v2/sessions/={{ $json.session }}/messages",
        "options": {
          "bodyContentType": "json"
        },
        "bodyParametersJson": "={\n  \"chatId\": \"{{ $json.groupId }}\",\n  \"text\": \"📍 Our office hours:\\n\\nMonday-Friday: 9am - 6pm EST\\nSaturday: 10am - 4pm EST\\nSunday: Closed\\n\\nNeed help outside these hours? Email [email protected]\"\n}"
      },
      "name": "Send Hours Info",
      "type": "n8n-nodes-base.httpRequest",
      "position": [850, 200],
      "credentials": {
        "httpHeaderAuth": {
          "name": "MoltFlow API"
        }
      }
    },
    {
      "parameters": {
        "authentication": "headerAuth",
        "url": "https://apiv2.waiflow.app/api/v2/sessions/={{ $json.session }}/messages",
        "options": {
          "bodyContentType": "json"
        },
        "bodyParametersJson": "={\n  \"chatId\": \"{{ $json.groupId }}\",\n  \"text\": \"📍 We're located at:\\n\\n123 Main Street\\nSan Francisco, CA 94102\\n\\nGoogle Maps: https://maps.google.com/?q=123+Main+Street+SF\\n\\nParking available on-site!\"\n}"
      },
      "name": "Send Location Info",
      "type": "n8n-nodes-base.httpRequest",
      "position": [850, 300],
      "credentials": {
        "httpHeaderAuth": {
          "name": "MoltFlow API"
        }
      }
    },
    {
      "parameters": {
        "authentication": "headerAuth",
        "url": "https://apiv2.waiflow.app/api/v2/sessions/={{ $json.session }}/messages",
        "options": {
          "bodyContentType": "json"
        },
        "bodyParametersJson": "={\n  \"chatId\": \"{{ $json.groupId }}\",\n  \"text\": \"💵 Pricing:\\n\\nBasic Plan: $29/month\\nPro Plan: $99/month\\nEnterprise: Custom pricing\\n\\nFull details: https://yoursite.com/pricing\\n\\nQuestions? Reply with 'pricing question' and our team will help!\"\n}"
      },
      "name": "Send Pricing Info",
      "type": "n8n-nodes-base.httpRequest",
      "position": [850, 400],
      "credentials": {
        "httpHeaderAuth": {
          "name": "MoltFlow API"
        }
      }
    },
    {
      "parameters": {
        "authentication": "headerAuth",
        "url": "https://apiv2.waiflow.app/api/v2/sessions/={{ $json.session }}/messages",
        "options": {
          "bodyContentType": "json"
        },
        "bodyParametersJson": "={\n  \"chatId\": \"{{ $json.groupId }}\",\n  \"text\": \"✅ Register here: https://yoursite.com/register\\n\\nTakes 2 minutes. You'll get confirmation email immediately.\\n\\nProblems registering? Let us know!\"\n}"
      },
      "name": "Send Registration Link",
      "type": "n8n-nodes-base.httpRequest",
      "position": [850, 500],
      "credentials": {
        "httpHeaderAuth": {
          "name": "MoltFlow API"
        }
      }
    },
    {
      "parameters": {
        "authentication": "headerAuth",
        "url": "https://apiv2.waiflow.app/api/v2/sessions/={{ $json.session }}/messages",
        "options": {
          "bodyContentType": "json"
        },
        "bodyParametersJson": "={\n  \"chatId\": \"{{ $json.groupId }}\",\n  \"text\": \"🔧 Thanks for reporting that, {{ $json.sender }}. Our support team has been notified and will investigate ASAP.\\n\\nUrgent? Email [email protected] directly.\"\n}"
      },
      "name": "Escalate to Support",
      "type": "n8n-nodes-base.httpRequest",
      "position": [850, 600],
      "credentials": {
        "httpHeaderAuth": {
          "name": "MoltFlow API"
        }
      }
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Parse Group Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Group Message": {
      "main": [
        [
          {
            "node": "Route by Keyword",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Keyword": {
      "main": [
        [
          {
            "node": "Send Hours Info",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Location Info",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Pricing Info",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Registration Link",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Escalate to Support",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Before importing:

  • Replace example text in reply nodes with your actual info
  • Update URLs (pricing, registration, maps)
  • Configure MoltFlow API credentials in n8n

Tips for Better Auto-Replies

1. Personalize with Sender Name

Use {{ $json.sender }} in replies to address users by name. It feels less robotic:

text
"Thanks for asking, {{ $json.sender }}! Our hours are..."

2. Keep Responses Short

Groups are noisy. Long messages get ignored. Aim for 2-3 lines max, with links for more info.

3. Add Emojis Strategically

Emojis help responses stand out in a busy group. But don't overdo it:

✅ One emoji at start: "📍 Our location is..." ❌ Emoji spam: "🎉🎊✨ Register now!!! 🚀💯🔥"

4. Include Escape Hatch for Humans

Always mention how to reach a real person:

text
"Questions? Reply 'speak to human' and we'll connect you with our team."

Then add another Switch rule for "speak to human" that notifies your support staff.

5. Log Everything

Even messages you don't auto-reply to should be logged. Add a Google Sheets node at the end of the workflow (connected to all paths) that logs:

  • Timestamp
  • Sender
  • Message
  • Action taken (replied, escalated, ignored)

This data helps you improve your auto-reply rules over time.

6. Test in a Separate Group First

Don't test auto-replies in your production group with 500 members. Create a test group with just you and a colleague, enable monitoring, and test all the keyword paths.

Once it's working smoothly, switch it to your real group.

Advanced: Context-Aware Replies

Basic keyword matching is powerful. But you can go further with context awareness.

Use Previous Message History

Store conversation context in workflow static data. If someone asks "What's your address?" followed by "Is there parking?", you can detect that parking question relates to location:

javascript
// In Code node
const message = $input.first().json.message;
const sender = $input.first().json.senderPhone;
const staticData = $getWorkflowStaticData('node');

// Get sender's last message topic
const lastTopic = staticData[`${sender}_topic`] || 'none';

// Detect context-dependent questions
if (message.includes('parking') && lastTopic === 'location') {
  return { reply: 'Yes! Free parking available on-site.' };
}

// Store current topic for next message
if (message.match(/location|address/)) {
  staticData[`${sender}_topic`] = 'location';
}

return { reply: null };

Multi-Language Support

Detect language and respond accordingly:

javascript
const message = $input.first().json.message;

// Simple language detection (could use API for accuracy)
const isSpanish = message.match(/horario|dirección|precio|ayuda/i);
const isFrench = message.match(/horaires|adresse|prix|aide/i);

if (isSpanish) {
  return {
    language: 'es',
    hoursReply: '📍 Horario:\n\nLunes-Viernes: 9am - 6pm EST...'
  };
} else if (isFrench) {
  return {
    language: 'fr',
    hoursReply: '📍 Horaires:\n\nLundi-Vendredi: 9h - 18h EST...'
  };
} else {
  return {
    language: 'en',
    hoursReply: '📍 Our office hours:\n\nMonday-Friday: 9am - 6pm EST...'
  };
}

Troubleshooting

Auto-Replies Not Sending

Check:

  • Webhook is active in MoltFlow Dashboard
  • Group monitoring is enabled for the correct group
  • MoltFlow API key is valid in n8n credentials
  • n8n workflow is activated (not just saved)

Debug: Check MoltFlow Dashboard → Webhooks → Deliveries. You'll see HTTP status for each webhook call.

Replies Going to Wrong Group

Problem: Using hardcoded chatId instead of dynamic groupId from message.

Solution: Make sure your HTTP Request body uses {{ $json.groupId }} not a hardcoded group ID.

Replies Too Slow

Problem: Multiple HTTP requests in sequence cause delays.

Solution: Use n8n's parallel execution. Connect multiple reply nodes to the Switch node outputs simultaneously rather than chaining them.

Keyword Matches Too Broad

Problem: "appreciated" matches "price" because it contains those letters.

Solution: Use word boundary regex \b to match whole words only:

javascript
\b(price|pricing)\b

This matches "price" and "pricing" but not "appreciated".

What's Next

You've built an intelligent group auto-reply system. But this is just the start.

Connect MoltFlow to n8n first, then set up webhooks for group monitoring, and use this guide's workflow template for keyword-based routing. Extend with REST API calls for custom integrations.

Ready to implement this? Follow our step-by-step guide: Connect MoltFlow to n8n for the foundational webhook setup, then use this guide's workflow template for group auto-replies.

Related workflows:

Advanced features to add:

  • AI-powered sentiment analysis to detect angry messages and prioritize escalation
  • Automatic translation for multi-language groups
  • Voting/polling system triggered by keywords like "vote" or "poll"
  • Member onboarding flow when new members join the group

MoltFlow features:

Ready to automate your WhatsApp groups? Start your free MoltFlow trial and import this workflow in 5 minutes.

Conclusion

Group management doesn't have to consume your day.

With n8n + MoltFlow, you set up the rules once. The workflow runs forever. Your group members get instant answers. Your support team focuses on complex issues that actually need human judgment.

Start simple. Pick the top 5 questions your group asks repeatedly. Build auto-replies for those. Add more rules as you discover patterns.

Within a week, your group will run itself.

Questions? Join the MoltFlow Discord or check out the full documentation.

Now go automate your group.

> Try MoltFlow Free — 100 messages/month

$ curl https://molt.waiflow.app/pricing

bash-5.2$ echo "End of post."_