Description
n8n-nodes-wafly


This is an n8n community node for the Wafly WhatsApp Bridge API. It lets you send WhatsApp messages, manage groups and configure webhooks directly from your n8n workflows.
source=npm&utmmedium=communitynode&utmcampaign=n8nintegration&utmcontent=readmetopcta”>Start a free 3-day trial β $20/month per connected WhatsApp number for international accounts.
π§© Ready-made workflow templates
Five workflows you can import and run, instead of starting from a blank canvas:
| Template | What it does |
|—|—|
| AI agent replies once | Buffers messages that arrive in a burst so your agent answers once instead of three times |
| Qualify inbound leads | Scores the conversation with AI and hands hot leads to a human |
| Moderate a group | Approves join requests, welcomes members and removes link spam |
| Send OTP with SMS fallback | Validates the number first, falls back to SMS when WhatsApp is unreachable |
| Alert on disconnect | Checks the connection on a schedule and alerts when the number drops |
Import the JSON, create the Wafly API credential and activate. All of them run on
self-hosted n8n, since community nodes are not available on n8n Cloud.
Portuguese versions of these flows are in examples/templates.
π Features
π± Instance
- Get the QR Code to connect
- Check the connection status
- Connect / disconnect the instance
- Restart the instance
- Get device information
- Check whether phone numbers exist on WhatsApp
- Message Buffer β group split messages so an AI agent answers once, not once per message
- Audio Transcription β received voice notes arrive transcribed in the webhook, using your own OpenAI key
- Full coverage of the published API: newsletters and channels, communities,
- Send text
- Send image
- Send video
- Send audio
- Send document
- Send location
- Send contact card
- Send polls
- Send links with preview
- Delete messages
- Create groups
- List groups (with optional pagination)
- Get group metadata
- Add / remove participants
- Approve / reject pending participants
- Promote / demote admins
- Leave a group
- Update name, description and photo
- Get and reset the invite link
- Update group settings
- Set the received-message webhook URL
- Read the stored received-message webhook URL
- Clear the received-message webhook URL
π‘ Newsletter / Channel, Community, Chat, Call
chat management and the calls beta. See Operation under each resource.
π¬ Messages
π₯ Groups
π Webhooks
Use an n8n Webhook node with method POST, activate the workflow, and copy
its Production URL into Webhook β Set Webhook. The Wafly node uses
PUT /update-webhook-received with { "value": "YOUR_URL" }. A successful
update returns HTTP 204, shown as one empty JSON item in n8n. Get Webhook reads
the stored URL as webhookUrl and value; Delete Webhook clears that callback.
These operations do not change connected, disconnected or delivery callbacks.
Incoming events are available under $json.body in the native Webhook node.
A received video keeps body.type = "ReceivedCallback"; its downloadable URL
is body.video.videoUrl. Receiving this event does not require a separate Wafly
trigger node.
Connecting a number
Use Instance β Get QR Code or Instance (More) β Get QR Code Image when
the customer is ready to connect. Read the response’s value; the image operation
returns base64 PNG (add data:image/png;base64, only if it has no data prefix).
QR codes expire: request a fresh one when reopening the pairing screen and keep
checking Get Status until connected is true.
For phone pairing, choose Instance (More) β Get Pairing Code (GET) or (POST)
and fill Phone with country code, such as 5511999999999. Both send the number
as ?phone=... and return code/message. The old POST operation identifier is
preserved, including support for saved JSON bodies containing phone.
π¦ Installation
Install from the n8n UI
1. Open your n8n instance
2. Go to Settings > Community Nodes
3. Click Install a community node
4. Enter: n8n-nodes-wafly
5. Click Install
Manual installation
If you run n8n locally, you can install the package via npm:
npm install n8n-nodes-wafly
If you run n8n via Docker, add it to your docker-compose.yml:
version: '3'
services:
n8n:
image: n8nio/n8n
ports:
- "5678:5678"
environment:
- N8NCOMMUNITYPACKAGES=n8n-nodes-wafly
volumes:
- ~/.n8n:/home/node/.n8n
π Credentials
Before using the node, create a credential of type Wafly API with the following fields:
https://wafly.com.br/api-bridge-whats (default; the same base URL serves accounts created on wafly.io, so keep it unchanged for international accounts)How to get your credentials
1.
Half of every WhatsApp conversation in Brazil is a voice note, and an LLM cannot The OpenAI key is yours β the cost lands on your own OpenAI account and Wafly Run it once per instance. After that, the audio webhook carries: If the provider refuses (wrong key, quota) or the monthly cap is reached, **the Leave the key field empty on later calls to keep the stored key and change only Nobody writes a paragraph on WhatsApp. People send Set Message Buffer groups those into a single webhook call: Run it once per instance β it is a setting, not a per-message step. What your webhook receives after that. Before: After: The payload keeps the exact same shape, so **an existing workflow keeps working | Field | Default | What it does | > Media, reactions and button replies are never grouped. If text is still waiting Use Get Message Buffer to read the current setting and **Disable Message This workflow sends an automatic message every day at 9am: For more information about the available endpoints and their parameters, see the full API documentation:Example 2: Create a group and add participants
{
"nodes": [
{
"parameters": {
"resource": "group",
"operation": "createGroup",
"groupName": "My Automated Group",
"phones": "5511999999999,5511888888888"
},
"name": "Create Group",
"type": "n8n-nodes-wafly.wafly",
"typeVersion": 1,
"position": [250, 300],
"credentials": {
"waflyApi": "Wafly API"
}
}
]
}
Example 3: Check the instance status
{
"nodes": [
{
"parameters": {
"resource": "instance",
"operation": "getStatus"
},
"name": "Check Status",
"type": "n8n-nodes-wafly.wafly",
"typeVersion": 1,
"position": [250, 300],
"credentials": {
"waflyApi": "Wafly API"
}
}
]
}
Example 4: Let your AI agent understand voice notes
listen. Set Audio Transcription makes the transcript arrive in the webhook,
so you skip building download + speech-to-text.
charges nothing for it. It is stored encrypted and never returned by the API.{
"nodes": [
{
"parameters": {
"resource": "instance",
"operation": "setTranscription",
"transcriptionApiKey": "sk-proj-...",
"transcriptionMaxAudioSeconds": 300,
"transcriptionMonthlyCap": 500
},
"name": "Transcribe Voice Notes",
"type": "n8n-nodes-wafly.wafly",
"typeVersion": 1,
"position": [250, 300],
"credentials": { "waflyApi": "Wafly API" }
}
]
}
{
"audio": { "audioUrl": "https://...", "seconds": 4 },
"transcription": { "status": "ok", "text": "oi, queria saber o preΓ§o", "latency_ms": 1180 }
}
message still arrives** β only with transcription.status = "error" and the
reason. Nothing is lost.
the limits.Example 4: Stop your AI agent from answering three times
hi, then you there?, then
how much is it? β three separate webhooks, so an AI agent replies three times,
and the first two replies were written without knowing what the person was still
about to type.{
"nodes": [
{
"parameters": {
"resource": "instance",
"operation": "setMessageBuffer",
"bufferWindowSeconds": 8,
"bufferMaxWaitSeconds": 30,
"bufferMaxMessages": 10,
"bufferMode": "concat",
"bufferIncludeGroups": false
},
"name": "Group Split Messages",
"type": "n8n-nodes-wafly.wafly",
"typeVersion": 1,
"position": [250, 300],
"credentials": {
"waflyApi": "Wafly API"
}
}
]
}
POST /your-webhook { "text": { "message": "hi" } }
POST /your-webhook { "text": { "message": "you there?" } }
POST /your-webhook { "text": { "message": "how much is it?" } }
{
"phone": "5511999999999",
"text": { "message": "hinyou there?nhow much is it?" },
"buffered": { "count": 3, "messageIds": ["...", "...", "..."], "waitedMs": 8012 }
}
without edits** β your AI Agent node just receives the whole thought at once.
When a single message arrives, the payload is identical to before, without the
extra buffered field.
|—|—|—|
| Window (seconds) | 8 | Silence window. Restarts on every new message, so delivery happens when the person stops typing. Max 20. |
| Max Wait (seconds) | 30 | Hard ceiling from the first message, so someone typing non-stop cannot postpone delivery forever. Max 30. |
| Max Messages | 10 | Deliver immediately once this many pile up. Max 50. |
| Mode | concat | concat keeps the usual payload shape. batch adds a bufferedMessages array and changes it. |
| Include Groups | false | Grouping in group chats is per participant β different people never get merged. |
> in the window when an audio arrives, the pending text is delivered first, so
> the conversation never reaches your agent out of order.
Buffer** to go back to one webhook call per message.Example 4: Full workflow β daily message
{
"name": "Daily WhatsApp Message",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 *"
}
]
}
},
"name": "Cron - 9am Every Day",
"type": "n8n-nodes-base.cron",
"typeVersion": 1,
"position": [250, 300]
},
{
"parameters": {
"resource": "message",
"operation": "sendText",
"phone": "5511999999999",
"message": "Good morning! Automatic 9am reminder."
},
"name": "Send Message",
"type": "n8n-nodes-wafly.wafly",
"typeVersion": 1,
"position": [450, 300],
"credentials": {
"waflyApi": "Wafly API"
}
}
],
"connections": {
"Cron - 9am Every Day": {
"main": [
[
{
"node": "Send Message",
"type": "main",
"index": 0
}
]
]
}
}
}
π API documentation
π License
MIT License β see the LICENSE file for details.
π€ Contributing
Contributions are welcome! Please:
1. Fork the project
2. Create a feature branch (git checkout -b feature/MyFeature)
3. Commit your changes (git commit -m 'Add new feature')
4. Push to the branch (git push origin feature/MyFeature)
5. Open a Pull Request
π¬ Support
π Acknowledgements
—