WhatsApp Node Service Setup (Node.js Sidecar)

The WhatsApp Node Service (folder name: xsender-whatsapp-service) is the Node.js sidecar that runs WhatsApp Web sessions for the Node WhatsApp gateway type. It is what lets your users scan a QR code and send WhatsApp messages from their own number — separate from, and complementary to, the official WhatsApp Cloud API gateway.

You only need this guide if you want the Node-based WhatsApp gateway. If you exclusively use the official WhatsApp Cloud API (Meta), you can skip this article — see Gateway → WhatsApp Cloud API instead.

Architecture in two sentences

The XSender PHP app speaks to the Node service over HTTP (default port 3000). The Node service uses whatsapp-web.js under the hood, maintains one WhatsApp Web session per user device, and posts incoming messages + session-status changes back to XSender via POST /api/whatsapp/node/webhook and POST /api/whatsapp/session/status.

Server requirements

Step 1 — Install

The folder xsender-whatsapp-service/ ships inside the CodeCanyon ZIP. If your XSender install is at /var/www/xsender/, the service lives at /var/www/xsender/xsender-whatsapp-service/.

cd /var/www/xsender/xsender-whatsapp-service

# install dependencies (downloads Chromium too)
npm install --production

# (Linux only) install Chromium system dependencies if you didn't already
sudo apt update
sudo apt install -y chromium-browser libnss3 libatk1.0-0 libxss1 libasound2 libxshmfence1

Step 2 — Configure

Create .env inside xsender-whatsapp-service/ (copy from .env.example if present):

PORT=3000
HOST=127.0.0.1

# Where this Node service reports session events back to:
XSENDER_BASE_URL=https://app.yourcompany.com
XSENDER_API_KEY=paste-from-Admin-Panel-Settings-API-Key

# Where session data is persisted (must be writable):
SESSION_DIR=./sessions

# Maximum concurrent sessions (RAM permitting):
MAX_SESSIONS=10

# Chromium executable path — uncomment if puppeteer's bundled Chromium doesn't work:
# PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

Then mirror these in the XSender admin panel:

  1. Admin Panel → Gateway → Messaging Gateways → WhatsApp → Node Service Settings

  2. Set Node Service URL to http://127.0.0.1:3000 (or the LAN/public address if the Node service runs on a different host).

  3. Set Node Service Token to the same value you used for XSENDER_API_KEY above.

  4. Save. The Health Banner at the top of the WhatsApp gateway page will flip to Online once the Node service can reach XSender and vice-versa.

Step 3 — Start the service

sudo npm install -g pm2

cd /var/www/xsender/xsender-whatsapp-service
pm2 start npm --name "xsender-wa-node" -- start

# persist across reboots
pm2 save
pm2 startup
# (run the command pm2 startup prints)

# logs
pm2 logs xsender-wa-node
# status
pm2 status

Option B — systemd

Create /etc/systemd/system/xsender-wa-node.service:

[Unit]
Description=XSender WhatsApp Node Service
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/xsender/xsender-whatsapp-service
ExecStart=/usr/bin/npm start
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now xsender-wa-node
sudo systemctl status xsender-wa-node
sudo journalctl -u xsender-wa-node -f

Option C — cPanel "Setup Node.js App"

Some cPanel hosts ship the Node.js Selector (via CloudLinux / Passenger):

  1. cPanel → Software → Setup Node.js App.

  2. Click Create Application. Node version: 18 or higher.

  3. Application root: xsender-whatsapp-service (relative to your home directory).

  4. Application URL: leave blank (we don't expose it on a public path).

  5. Startup file: index.js (or whatever the service's main file is — check package.json's "main").

  6. Environment variables: add the PORT, XSENDER_BASE_URL, XSENDER_API_KEY entries from Step 2.

  7. Save → Run NPM InstallStart App.

If your cPanel doesn't show "Setup Node.js App", the host has not enabled Node.js — use a small VPS for the Node service and point your cPanel-hosted XSender at it over the public IP (with a firewall rule limiting access).

Step 4 — Pair the first device

  1. Open Admin Panel → Gateway → Messaging Gateways → WhatsApp → Node Devices → Add Device (users do the same in their own panel).

  2. A QR code appears. Open WhatsApp on the phone you want to use as the sender → Settings → Linked Devices → Link a Device → scan.

  3. The session status changes from ConnectingConnected. The phone is now an active WhatsApp sender.

  4. To rotate the device, click Logout in the panel — the session is dropped on both sides — then add a new device with a fresh QR.

Useful Node service commands

# Restart
pm2 restart xsender-wa-node       # PM2
sudo systemctl restart xsender-wa-node  # systemd

# Stop
pm2 stop xsender-wa-node

# Tail logs
pm2 logs xsender-wa-node --lines 200
sudo journalctl -u xsender-wa-node -f

# Wipe all sessions (forces every linked phone to re-scan QR)
pm2 stop xsender-wa-node
rm -rf /var/www/xsender/xsender-whatsapp-service/sessions/*
pm2 start xsender-wa-node

# Update the Node service after an XSender release that bundles a new version
cd /var/www/xsender/xsender-whatsapp-service
git pull                        # if installed from git
# or re-extract xsender-whatsapp-service/ from the new XSender ZIP, overwriting old files
npm install --production
pm2 restart xsender-wa-node

Step 5 — Verify it's working

  1. From the XSender server itself:

    curl http://127.0.0.1:3000/health

    You should see {"status":"ok","sessions":N}.

  2. From inside XSender: Admin Panel → Gateway → Messaging Gateways → WhatsApp → Diagnostics shows a green badge if the Node service is reachable + responds within the configured timeout.

  3. Send a real test message through the Node gateway from Communication → Via Panel.

Troubleshooting

Symptom

Likely cause

Fix

QR never appears, status stuck on "Connecting"

Chromium missing or PUPPETEER download blocked by firewall

Install Chromium system packages; set PUPPETEER_EXECUTABLE_PATH in .env.

Session drops after reboot

SESSION_DIR is on a tmpfs / not persisted

Point SESSION_DIR at a persistent path; ensure write permission.

Health Banner shows "Node service unreachable"

Wrong URL / firewall

From XSender server, curl <Node URL>/health. If it fails, the URL or firewall is wrong.

Messages queue but never send

Session expired (WhatsApp logged the device out)

Open the device in the panel, scan QR again.

Sudden RAM spike, OOM kills

Too many concurrent sessions

Lower MAX_SESSIONS or scale Node service to a larger box.

"Phone got banned" / messages rejected

Sending pattern triggered WhatsApp's anti-spam

Lower send rate, warm up new numbers slowly, use Meta WhatsApp Cloud API for high-volume.