@jazario/n8n-nodes-bailey
v0.1.2
Published
n8n community nodes for Baileys (WhiskeySockets) WhatsApp Web API
Maintainers
Readme
n8n-nodes-bailey
n8n community nodes for the WhiskeySockets Baileys WhatsApp Web API.
Connects n8n workflows directly to WhatsApp — no cloud gateway, no third-party service, no per-message fee. Runs entirely through a standard WhatsApp Linked Device session on your own server.
Table of Contents
- Requirements
- Installation
- Authentication
- Nodes
- Resources & Operations
- Connection Pooling
- E2E Tests
- Contributing
- License
Requirements
- n8n ≥ 1.0.0
- Node.js ≥ 18
- A WhatsApp account that can register a Linked Device
Installation
n8n Community Nodes UI
- In n8n, go to Settings → Community Nodes.
- Click Install.
- Enter
@jazario/n8n-nodes-baileyand click Install.
Manual (self-hosted)
npm install @jazario/n8n-nodes-baileyRestart n8n after installation.
Authentication
Credential fields
Create a Bailey (WhatsApp) API credential. All fields:
| Field | Default | Description |
|---|---|---|
| Session ID | default | Unique name for this WhatsApp session. Shared between Trigger and Action nodes. |
| Phone Number | — | International format, no + or spaces (e.g. 12025551234). |
| Auth Method | pairingCode | pairingCode (recommended) or qrCode. |
| Auth Data Path | ~/.n8n/baileys | Directory where session files (creds.json, signal keys) are stored. |
| Sync Full History | false | Request full message history on first connect (slow, usually not needed). |
| Mark Online on Connect | true | Show the account as online when the socket connects. |
| Browser Name | n8n | Label shown in WhatsApp → Linked Devices. |
| Message Cache Size | 1000 | In-memory LRU cache size. Used for poll vote decryption and message retries (100–10 000). |
| Idle Timeout (Seconds) | 30 | Seconds before an idle action-node connection auto-closes. 0 to disable. |
| Proxy URL | — | Optional HTTP/SOCKS proxy for the WebSocket connection (e.g. http://proxy:3128). |
Pairing Code (recommended)
- Add a Bailey Trigger node to your workflow and open it.
- Select (or create) your credential with Auth Method = Pairing Code.
- Click Listen for event (test mode) — the node logs an 8-digit code.
- On your phone: WhatsApp → Linked Devices → Link a Device → Link with Phone Number.
- Enter the 8-digit code. The session authenticates and
creds.jsonis saved automatically.
QR Code
Set Auth Method = QR Code, then check the n8n process logs for the QR code printed in your terminal. Scan it from your phone via WhatsApp → Linked Devices → Link a Device.
Persistence — session files are stored under
Auth Data Path/<Session ID>/. Back up this directory or mount it as a persistent volume when running n8n in Docker/Kubernetes.
Nodes
Bailey Trigger
Starts a persistent Baileys WebSocket and emits workflow executions whenever a selected WhatsApp event fires.
Configuration:
| Parameter | Description |
|---|---|
| Credential | The Bailey API credential to use. |
| Events | One or more events to listen for (or * for all events). |
Available events (31 + wildcard):
| Display Name | Event Key | Description |
|---|---|---|
| Message Received | messages.upsert | New or appended messages |
| Message Updated | messages.update | Status updates, poll votes, edits |
| Message Deleted | messages.delete | Messages deleted |
| Message Reaction | messages.reaction | Emoji reactions |
| Message Receipt | message-receipt.update | Read/delivery receipts |
| Media Updated | messages.media-update | Media re-upload results |
| Chat Created | chats.upsert | New chats |
| Chat Updated | chats.update | Chat metadata updates |
| Chat Deleted | chats.delete | Chats deleted |
| Chat Locked | chats.lock | Chat lock/unlock state |
| Contact Created | contacts.upsert | New contacts |
| Contact Updated | contacts.update | Contact updates |
| Presence Updated | presence.update | Online/offline/typing status |
| Group Created | groups.upsert | New groups joined |
| Group Updated | groups.update | Group metadata changes |
| Group Participants | group-participants.update | Members added/removed/promoted |
| Group Join Request | group.join-request | Join approval requests |
| Connection Updated | connection.update | WebSocket connection state |
| Call Received | call | Incoming call events |
| Credentials Updated | creds.update | Auth credentials changed (auto-saved) |
| History Sync | messaging-history.set | Full history sync data |
| Blocklist Set | blocklist.set | Full blocked contacts list |
| Blocklist Updated | blocklist.update | Contact blocked/unblocked |
| Label Edited | labels.edit | Business label created/edited |
| Label Association | labels.association | Label assigned/removed |
| Newsletter Reaction | newsletter.reaction | Newsletter message reaction |
| Newsletter View | newsletter.view | Newsletter view count update |
| Newsletter Participants | newsletter-participants.update | Newsletter admin changes |
| Newsletter Settings | newsletter-settings.update | Newsletter settings changed |
| Settings Updated | settings.update | App settings sync |
| LID Mapping | lid-mapping.update | Linked identity mapping update |
| * (all) | — | Every event above |
The trigger also registers its socket in the connection pool so subsequent Bailey Action nodes in the same workflow share the same authenticated session without re-connecting.
Bailey (Action)
Executes WhatsApp operations on demand. Supports continueOnFail. Can be used as a Tool in n8n AI Agent workflows (usableAsTool: true).
Resources & Operations
JIDs (WhatsApp IDs) follow these formats:
- Individual:
[email protected] - Group:
[email protected] - Newsletter:
1234567890@newsletter
Message
| Operation | Description |
|---|---|
| sendText | Send a plain text message, optionally with @mentions |
| sendImage | Send an image from a URL or binary data, with optional caption |
| sendVideo | Send a video from a URL or binary data, with optional caption |
| sendAudio | Send an audio file; set ptt: true for voice notes |
| sendDocument | Send a file with a filename and MIME type |
| sendSticker | Send a WebP sticker |
| sendGif | Send a looping GIF video |
| sendLocation | Send a GPS location with optional name and address |
| sendContact | Send a vCard contact |
| sendPoll | Send a poll with up to 12 options |
| sendReaction | React to a message with an emoji |
| sendProduct | Send a WhatsApp Business product card |
| sendEvent | Send a WhatsApp event invitation |
| sendViewOnce | Send a view-once image |
| sendVideoNote | Send a circular video note (PTV) |
| sharePhoneNumber | Share your phone number with a contact |
| pinMessage | Pin or unpin a message in a chat |
| forward | Forward a message to another JID |
| edit | Edit a previously sent message |
| deleteForEveryone | Delete a message for all participants |
| deleteForMe | Remove a message from your view only |
Chat
| Operation | Description |
|---|---|
| archive | Archive a chat |
| unarchive | Unarchive a chat |
| mute | Mute a chat for a specified duration |
| unmute | Unmute a chat |
| markRead | Mark a chat as read |
| markUnread | Mark a chat as unread |
| pin | Pin a chat |
| unpin | Unpin a chat |
| deleteChat | Delete a chat |
| clearChat | Clear all messages in a chat |
Group
| Operation | Description |
|---|---|
| create | Create a new group |
| getMetadata | Fetch group metadata (name, description, participants) |
| getAllParticipating | List all groups the session belongs to |
| updateSubject | Rename the group |
| updateDescription | Update the group description |
| updateSettings | Set announcement / locked mode |
| addParticipants | Add participants |
| removeParticipants | Remove participants |
| promoteParticipants | Promote participants to admin |
| demoteParticipants | Demote admins to regular members |
| leave | Leave the group |
| getInviteCode | Get the current invite link code |
| revokeInvite | Revoke and regenerate the invite code |
| acceptInvite | Join a group by invite code |
| getInviteInfo | Get group info from an invite code without joining |
| toggleEphemeral | Enable/disable disappearing messages |
| setMemberAddMode | Control whether members or only admins can add members |
| setJoinApprovalMode | Require admin approval for join requests |
Community
| Operation | Description |
|---|---|
| create | Create a new community |
| getMetadata | Fetch community metadata |
| createGroup | Create a sub-group inside the community |
| linkGroup | Link an existing group to the community |
| unlinkGroup | Unlink a group from the community |
| fetchLinkedGroups | List all groups linked to the community |
| updateSubject | Rename the community |
| updateDescription | Update the community description |
| updateSettings | Update community settings |
| addParticipants | Add participants to the community |
| removeParticipants | Remove participants |
| leave | Leave the community |
| getInviteCode | Get the community invite code |
| toggleEphemeral | Enable/disable disappearing messages |
| setJoinApprovalMode | Require approval for join requests |
| getAllParticipating | List all communities the session belongs to |
Contact
| Operation | Description |
|---|---|
| addOrEdit | Add or update a contact in the address book |
| remove | Remove a contact |
| requestPhoneNumber | Request a contact to share their phone number |
User
| Operation | Description |
|---|---|
| checkExists | Check if a phone number is on WhatsApp |
| getStatus | Get a user's status text |
| getProfilePicture | Get a user's profile picture URL |
| getBusinessProfile | Fetch WhatsApp Business profile details |
| subscribePresence | Subscribe to online/typing presence updates |
| sendPresence | Broadcast your own presence to a JID |
| fetchDisappearingDuration | Get the default disappearing message duration |
| fetchMessageHistory | Request older message history for a chat |
Profile
| Operation | Description |
|---|---|
| updateStatus | Update your status text |
| updateName | Update your display name |
| updatePicture | Upload a new profile picture |
| removePicture | Remove your profile picture |
| setDisappearing | Set the global disappearing message default |
Privacy
| Operation | Description |
|---|---|
| getSettings | Get current privacy settings |
| getBlocklist | List all blocked contacts |
| block | Block a contact |
| unblock | Unblock a contact |
| updateLastSeen | Control who can see your last seen |
| updateOnline | Control who can see your online status |
| updateProfilePicture | Control who can see your profile picture |
| updateReadReceipts | Enable/disable read receipts |
| updateCallPrivacy | Control who can call you |
| updateGroupsAdd | Control who can add you to groups |
Media
| Operation | Description |
|---|---|
| download | Download media from a message to n8n binary data |
| reupload | Re-upload expired media so it can be sent again |
Newsletter
| Operation | Description |
|---|---|
| create | Create a new newsletter |
| getMetadata | Fetch newsletter metadata |
| follow | Follow a newsletter |
| unfollow | Unfollow a newsletter |
| mute | Mute a newsletter |
| unmute | Unmute a newsletter |
| updateName | Update the newsletter name |
| updateDescription | Update the newsletter description |
| updatePicture | Upload a newsletter picture |
| removePicture | Remove the newsletter picture |
| reactMessage | React to a newsletter message |
| fetchMessages | Fetch newsletter messages |
| getSubscribers | Get the subscriber list |
| delete | Delete the newsletter |
Business
| Operation | Description |
|---|---|
| getCatalog | Fetch the product catalog |
| getCollections | List product collections |
| getOrderDetails | Fetch order details by order ID |
| createProduct | Create a new product listing |
| updateProduct | Update an existing product |
| deleteProducts | Delete one or more products |
| updateProfile | Update the Business profile (address, category, email, website) |
| updateCoverPhoto | Upload a Business cover photo |
Label
| Operation | Description |
|---|---|
| setLabels | Replace all labels on a chat |
| addChatLabel | Add a label to a chat |
| removeChatLabel | Remove a label from a chat |
| addMessageLabel | Add a label to a specific message |
| removeMessageLabel | Remove a label from a specific message |
Broadcast
| Operation | Description |
|---|---|
| sendBroadcast | Send a message to multiple JIDs simultaneously |
| sendStory | Send a WhatsApp Story (status update) |
Call
| Operation | Description |
|---|---|
| reject | Reject an incoming call |
| createLink | Create a WhatsApp call link |
Connection Pooling
A module-scoped connection pool (Map<sessionId, ConnectionEntry>) is shared between the Trigger and Action nodes:
- Trigger establishes the socket during workflow activation and registers it in the pool.
- Action nodes reuse the registered socket, avoiding a second authentication round-trip.
- Without a Trigger (action-only mode), Action nodes create their own connection, which auto-closes after the configured idle timeout.
- Auto-reconnect: on unexpected disconnection, the pool waits 3 seconds and re-creates the connection. A clean logout (status 401) removes the session without retrying.
- Idle timers call
.unref()so Node.js exits cleanly when no other work is pending.
E2E Tests
E2E tests require a real authenticated WhatsApp session and are run manually via GitHub Actions (workflow_dispatch).
Running locally
# 1. Authenticate a session first (run the Trigger once in n8n, or use the Baileys CLI)
# 2. Set environment variables
export E2E_SESSION_ID=e2e-test
export E2E_AUTH_PATH=.baileys-sessions
export [email protected] # your test contact
export [email protected] # optional, for group tests
# 3. Run
npm run test:e2eCI setup (GitHub Actions)
Add the following secrets to your repository:
| Secret | Description |
|---|---|
| E2E_CREDS_JSON | Contents of .baileys-sessions/e2e-test/creds.json |
| E2E_TARGET_JID | WhatsApp JID of the test contact |
| E2E_GROUP_JID | (optional) WhatsApp group JID for group tests |
The workflow is in .github/workflows/e2e.yml and must be triggered manually. Optionally pass test_filter to run a single suite (e.g. send-message).
Test suites
| Suite | File | Coverage |
|---|---|---|
| Send Message | test/e2e/send-message.e2e.ts | sendText, mention, location, contact, poll, delete, reaction, roundtrip |
| Group Operations | test/e2e/group-operations.e2e.ts | create, metadata, subject, description, invite, settings, ephemeral, leave |
| Chat Operations | test/e2e/chat-operations.e2e.ts | archive, mute, pin, markRead, presence, read receipt |
Contributing
git clone https://github.com/jazarie2/n8n-nodes-bailey.git
cd n8n-nodes-bailey
npm install
npm run build # compile TypeScript
npm run lint # ESLint
npm test # unit tests
npm run test:integration # integration testsPRs and issues welcome.
