WA Bot

{{ loginError }}

Dashboard

{{ waStatus }}
WhatsApp Status
{{ stats.autoreply }}
Auto-Reply Rules
{{ stats.commands }}
Quick Commands
Scan QR Code
Open WhatsApp → Settings → Linked Devices
Setelah scan QR, tunggu beberapa menit sampai status berubah menjadi ready. Jangan refresh halaman selama proses loading.

QR Code expired

WhatsApp disconnected

Messages

{{ selectedChatIds.length }} selected
{{ chat.name }} {{ formatTime(chat.timestamp) }}
{{ chat.lastMessage || 'No messages' }}
{{ chat.unreadCount }}
Loading chats...
{{ selectedChat.name }}
{{ msg.body }}
{{ formatTime(msg.timestamp) }}
{{ f.name }}

Auto-Reply Rules

Cara Kerja: Setiap pesan masuk akan dicocokkan dengan keyword di bawah. Jika cocok, bot akan membalas otomatis.

Default Auto-Reply: Buat rule dengan keyword default untuk membalas pesan yang tidak cocok dengan keyword manapun. Rule ini hanya dijalankan sebagai fallback jika tidak ada rule lain yang match. Match type pada rule default akan diabaikan.
KeywordMatchModeResponse / ScriptStatusActions
{{ r.keyword }} {{ r.matchType }} {{ r.mode === 'script' ? '⚡ Script' : 'đŸ’Ŧ Message' }} {{ r.mode === 'script' ? (r.script || '').substring(0, 60) + '...' : r.response }} {{ r.enabled ? 'ON' : 'OFF' }}
No rules yet

Quick Commands

CommandModeReply / ScriptStatusActions
{{ c.command }} {{ c.mode === 'script' ? '⚡ Script' : 'đŸ’Ŧ Message' }} {{ c.mode === 'script' ? (c.script || '').substring(0, 60) + '...' : c.replyMessage }} {{ c.enabled ? 'ON' : 'OFF' }}
No commands yet

OnMessage Hooks

Scripts that run on every incoming message.
#NameScript PreviewStatusActions
{{ idx + 1 }} {{ h.name }} {{ (h.script || '').substring(0, 80) }}{{ (h.script||'').length > 80 ? '...' : '' }} {{ h.enabled ? 'ON' : 'OFF' }}
No hooks yet. Add one to run custom code on every message.
Simulate: {{ simHook.name }}
{{ simResult.success ? '✅ Success' : '❌ Error' }} {{ simResult.duration }}ms
{{ simResult.error }}
Returned: {{ simResult.returned }}
Messages sent (simulated):
→ {{ s.to }}: {{ s.text }}
Hook ran without sending any message or returning a value.
â„šī¸ Hook Script Context:
async function(client, msg, axios)
  • msg.body — message text
  • msg.from / msg.to — sender / recipient chat ID
  • msg.fromMe — boolean, true if you sent it
  • msg.chatId — the chat where message was sent
  • msg.type — message type (chat, image, etc.)
  • client.send(text) — reply to the same chat
  • client.sendTo(chatId, text) — send to any chat
  • return "text" — shorthand to reply to the chat
Hook Execution Log {{ hookLogEntries.length }}
TimeHookStatusDirMessagems
{{ formatLogTime(log.ts) }} {{ log.hookName }} OK ERR replied {{ log.fromMe ? '→ OUT' : '← IN' }} {{ log.msgBody }} {{ log.duration }}ms
No logs yet. Send a message to trigger hooks.

Categories

No categories yet. Create one above.
{{ cat }}
No members. Go to Messages → select chats → assign here.
{{ getChatName(chatId) }} {{ chatId }}

Queued API Requests

Messages sent via /api/send-message are queued with a 5s delay between each.
{{ queueList.length }}
Total
{{ queueList.filter(q=>q.status==='pending').length }}
Pending
{{ queueList.filter(q=>q.status==='sending').length }}
Sending
{{ queueList.filter(q=>q.status==='sent').length }}
Sent
{{ queueList.filter(q=>q.status==='failed').length }}
Failed
#Ref IDRecipientMessageStatusCreatedSent
{{ idx + 1 }} {{ q.reference_id.length > 12 ? q.reference_id.substring(0,12)+'â€Ļ' : q.reference_id }}— {{ q.number }} {{ (q.message || '').substring(0, 80) }} Pending Sending Sent Failed {{ formatLogTime(q.createdAt) }} {{ q.sentAt ? formatLogTime(q.sentAt) : '-' }}
Queue is empty. Messages sent via API will appear here.
Check Message Status API

Check the delivery status of a queued message by its queue ID or reference_id.

GET /api/message-status/:id

The :id param can be the queue ID (UUID) returned by send-message, or your custom reference_id.

Example: cURL
curl {{ baseUrl }}/api/message-status/YOUR_REFERENCE_ID \
  -H "X-API-Key: YOUR_API_KEY"
Example: Fetch
fetch("{{ baseUrl }}/api/message-status/YOUR_REFERENCE_ID", {
  headers: { "X-API-Key": "YOUR_API_KEY" }
}).then(r => r.json()).then(console.log);
Response
{
  "id": "uuid-queue-id",
  "reference_id": "your-custom-ref",
  "number": "6282146727409",
  "chatId": "6282146727409@c.us",
  "message": "Hello!",
  "status": "sent",   // pending | sending | sent | failed
  "error": null,
  "createdAt": 1709654400000,
  "sentAt": 1709654405000
}
💡 Tip: Pass "reference_id" when calling /api/send-message to tag messages with your own ID for easy tracking.

Queue Hooks

Run custom JavaScript when a queued message is sent or fails. Available: msg, axios
onSent Hook
onFailed Hook
msg Object Reference
{
  id: "uuid-queue-id",
  reference_id: "your-custom-ref",  // or null
  number: "6282146727409",
  chatId: "6282146727409@c.us",
  message: "Hello!",
  status: "sent",        // "sent" or "failed"
  error: null,           // error message if failed
  createdAt: 1709654400000,
  sentAt: 1709654405000  // null if failed
}

Network Monitor

All HTTP requests to /api/* endpoints are logged here.
{{ networkLog.length }}
Total
{{ networkLog.filter(l=>l.statusCode>=200&&l.statusCode<300).length }}
2xx
{{ networkLog.filter(l=>l.statusCode>=400&&l.statusCode<500).length }}
4xx
{{ networkLog.filter(l=>l.statusCode>=500).length }}
5xx
#MethodURLStatusTimeIPDate
{{ idx + 1 }} {{ l.method }} {{ l.url }} {{ l.statusCode }} {{ l.duration }}ms {{ l.ip }} {{ formatLogTime(l.createdAt) }}
No requests logged yet.

Tools

Backup Data

Download all your settings as a JSON file: auto-reply rules, commands, hooks, categories, pinned chats, contact names, and main number.

Restore Data

Upload a previously downloaded backup JSON file to restore all settings. This will overwrite existing data.

{{ toolsResult.message }}
â„šī¸ Backup includes:
  • Auto-Reply rules
  • Quick Commands
  • OnMessage Hooks
  • Categories & assignments
  • Pinned chats
  • Contact names
  • Main number setting

âš ī¸ Note: API key, password, and WhatsApp session are not included for security.

API Key

Use "main" as number in API calls to auto-resolve to this number.
Use * to allow all. Otherwise one number per line (e.g. 6282146727409). Numbers not listed will be rejected.

📡 API Documentation

Base URL: {{ baseUrl }}

Send to a single number
curl -X POST {{ baseUrl }}/api/send-message \
  -H "Content-Type: application/json" \
  -H "X-API-Key: {{ apiKeyValue }}" \
  -d '{"number": "6282146727409", "message": "Hello!"}'
fetch("{{ baseUrl }}/api/send-message", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "{{ apiKeyValue }}"
  },
  body: JSON.stringify({ number: "6282146727409", message: "Hello!" })
}).then(r => r.json()).then(console.log);
const axios = require('axios');
axios.post('{{ baseUrl }}/api/send-message', {
  number: '6282146727409',
  message: 'Hello!'
}, {
  headers: { 'X-API-Key': '{{ apiKeyValue }}' }
}).then(res => console.log(res.data));
import 'package:dio/dio.dart';
final dio = Dio();
final response = await dio.post('{{ baseUrl }}/api/send-message',
  data: {'number': '6282146727409', 'message': 'Hello!'},
  options: Options(headers: {'X-API-Key': '{{ apiKeyValue }}'}),
);
print(response.data);
import 'dart:convert';
import 'package:http/http.dart' as http;
final response = await http.post(
  Uri.parse('{{ baseUrl }}/api/send-message'),
  headers: {'Content-Type': 'application/json', 'X-API-Key': '{{ apiKeyValue }}'},
  body: jsonEncode({'number': '6282146727409', 'message': 'Hello!'}),
);
print(response.body);
Send to multiple numbers
curl -X POST {{ baseUrl }}/api/send-message \
  -H "Content-Type: application/json" \
  -H "X-API-Key: {{ apiKeyValue }}" \
  -d '{
  "recipients": ["6282146727409", "628xxx"],
  "message": "Hello everyone!"
}'
fetch("{{ baseUrl }}/api/send-message", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "{{ apiKeyValue }}"
  },
  body: JSON.stringify({
    recipients: ["6282146727409", "628xxx"],
    message: "Hello everyone!"
  })
}).then(r => r.json()).then(console.log);
const axios = require('axios');
axios.post('{{ baseUrl }}/api/send-message', {
  recipients: ['6282146727409', '628xxx'],
  message: 'Hello everyone!'
}, {
  headers: { 'X-API-Key': '{{ apiKeyValue }}' }
}).then(res => console.log(res.data));
import 'package:dio/dio.dart';
final dio = Dio();
final response = await dio.post('{{ baseUrl }}/api/send-message',
  data: {
    'recipients': ['6282146727409', '628xxx'],
    'message': 'Hello everyone!'
  },
  options: Options(headers: {'X-API-Key': '{{ apiKeyValue }}'}),
);
print(response.data);
import 'dart:convert';
import 'package:http/http.dart' as http;
final response = await http.post(
  Uri.parse('{{ baseUrl }}/api/send-message'),
  headers: {'Content-Type': 'application/json', 'X-API-Key': '{{ apiKeyValue }}'},
  body: jsonEncode({
    'recipients': ['6282146727409', '628xxx'],
    'message': 'Hello everyone!'
  }),
);
print(response.body);
Send to group(s)
curl -X POST {{ baseUrl }}/api/send-message \
  -H "Content-Type: application/json" \
  -H "X-API-Key: {{ apiKeyValue }}" \
  -d '{
  "recipients": ["120363xxx@g.us"],
  "message": "Hello group!"
}'
fetch("{{ baseUrl }}/api/send-message", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "{{ apiKeyValue }}"
  },
  body: JSON.stringify({
    recipients: ["120363xxx@g.us"],
    message: "Hello group!"
  })
}).then(r => r.json()).then(console.log);
const axios = require('axios');
axios.post('{{ baseUrl }}/api/send-message', {
  recipients: ['120363xxx@g.us'],
  message: 'Hello group!'
}, {
  headers: { 'X-API-Key': '{{ apiKeyValue }}' }
}).then(res => console.log(res.data));
import 'package:dio/dio.dart';
final dio = Dio();
final response = await dio.post('{{ baseUrl }}/api/send-message',
  data: {
    'recipients': ['120363xxx@g.us'],
    'message': 'Hello group!'
  },
  options: Options(headers: {'X-API-Key': '{{ apiKeyValue }}'}),
);
print(response.data);
import 'dart:convert';
import 'package:http/http.dart' as http;
final response = await http.post(
  Uri.parse('{{ baseUrl }}/api/send-message'),
  headers: {'Content-Type': 'application/json', 'X-API-Key': '{{ apiKeyValue }}'},
  body: jsonEncode({
    'recipients': ['120363xxx@g.us'],
    'message': 'Hello group!'
  }),
);
print(response.body);
Send to multiple groups + numbers
curl -X POST {{ baseUrl }}/api/send-message \
  -H "Content-Type: application/json" \
  -H "X-API-Key: {{ apiKeyValue }}" \
  -d '{
  "recipients": [
    "6282146727409",
    "628xxx",
    "120363xxx@g.us",
    "120363yyy@g.us"
  ],
  "message": "Hello!"
}'
fetch("{{ baseUrl }}/api/send-message", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "{{ apiKeyValue }}"
  },
  body: JSON.stringify({
    recipients: [
      "6282146727409",
      "628xxx",
      "120363xxx@g.us",
      "120363yyy@g.us"
    ],
    message: "Hello!"
  })
}).then(r => r.json()).then(console.log);
const axios = require('axios');
axios.post('{{ baseUrl }}/api/send-message', {
  recipients: [
    '6282146727409',
    '628xxx',
    '120363xxx@g.us',
    '120363yyy@g.us'
  ],
  message: 'Hello!'
}, {
  headers: { 'X-API-Key': '{{ apiKeyValue }}' }
}).then(res => console.log(res.data));
import 'package:dio/dio.dart';
final dio = Dio();
final response = await dio.post('{{ baseUrl }}/api/send-message',
  data: {
    'recipients': [
      '6282146727409',
      '628xxx',
      '120363xxx@g.us',
      '120363yyy@g.us'
    ],
    'message': 'Hello!'
  },
  options: Options(headers: {'X-API-Key': '{{ apiKeyValue }}'}),
);
print(response.data);
import 'dart:convert';
import 'package:http/http.dart' as http;
final response = await http.post(
  Uri.parse('{{ baseUrl }}/api/send-message'),
  headers: {'Content-Type': 'application/json', 'X-API-Key': '{{ apiKeyValue }}'},
  body: jsonEncode({
    'recipients': [
      '6282146727409',
      '628xxx',
      '120363xxx@g.us',
      '120363yyy@g.us'
    ],
    'message': 'Hello!'
  }),
);
print(response.body);
Send to Main Number (use "main")
curl -X POST {{ baseUrl }}/api/send-message \
  -H "Content-Type: application/json" \
  -H "X-API-Key: {{ apiKeyValue }}" \
  -d '{"number": "main", "message": "Hello!"}'
fetch("{{ baseUrl }}/api/send-message", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "{{ apiKeyValue }}"
  },
  body: JSON.stringify({ number: "main", message: "Hello!" })
}).then(r => r.json()).then(console.log);
const axios = require('axios');
axios.post('{{ baseUrl }}/api/send-message', {
  number: 'main',
  message: 'Hello!'
}, {
  headers: { 'X-API-Key': '{{ apiKeyValue }}' }
}).then(res => console.log(res.data));
import 'package:dio/dio.dart';
final dio = Dio();
final response = await dio.post('{{ baseUrl }}/api/send-message',
  data: {'number': 'main', 'message': 'Hello!'},
  options: Options(headers: {'X-API-Key': '{{ apiKeyValue }}'}),
);
print(response.data);
import 'dart:convert';
import 'package:http/http.dart' as http;
final response = await http.post(
  Uri.parse('{{ baseUrl }}/api/send-message'),
  headers: {'Content-Type': 'application/json', 'X-API-Key': '{{ apiKeyValue }}'},
  body: jsonEncode({'number': 'main', 'message': 'Hello!'}),
);
print(response.body);
Send Image / File from URL
curl -X POST {{ baseUrl }}/api/send-message \
  -H "Content-Type: application/json" \
  -H "X-API-Key: {{ apiKeyValue }}" \
  -d '{
  "number": "6282146727409",
  "message": "Check this image!",
  "media": { "url": "https://example.com/photo.jpg" }
}'
fetch("{{ baseUrl }}/api/send-message", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "{{ apiKeyValue }}"
  },
  body: JSON.stringify({
    number: "6282146727409",
    message: "Check this image!",
    media: { url: "https://example.com/photo.jpg" }
  })
}).then(r => r.json()).then(console.log);
const axios = require('axios');
axios.post('{{ baseUrl }}/api/send-message', {
  number: '6282146727409',
  message: 'Check this image!',
  media: { url: 'https://example.com/photo.jpg' }
}, {
  headers: { 'X-API-Key': '{{ apiKeyValue }}' }
}).then(res => console.log(res.data));
import 'package:dio/dio.dart';
final dio = Dio();
final response = await dio.post('{{ baseUrl }}/api/send-message',
  data: {
    'number': '6282146727409',
    'message': 'Check this image!',
    'media': { 'url': 'https://example.com/photo.jpg' }
  },
  options: Options(headers: {'X-API-Key': '{{ apiKeyValue }}'}),
);
print(response.data);
import 'dart:convert';
import 'package:http/http.dart' as http;
final response = await http.post(
  Uri.parse('{{ baseUrl }}/api/send-message'),
  headers: {'Content-Type': 'application/json', 'X-API-Key': '{{ apiKeyValue }}'},
  body: jsonEncode({
    'number': '6282146727409',
    'message': 'Check this image!',
    'media': { 'url': 'https://example.com/photo.jpg' }
  }),
);
print(response.body);
Send File with Base64 Data
curl -X POST {{ baseUrl }}/api/send-message \
  -H "Content-Type: application/json" \
  -H "X-API-Key: {{ apiKeyValue }}" \
  -d '{
  "number": "6282146727409",
  "message": "Here is the document",
  "media": {
    "data": "BASE64_ENCODED_DATA",
    "mimetype": "application/pdf",
    "filename": "document.pdf"
  }
}'
fetch("{{ baseUrl }}/api/send-message", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "{{ apiKeyValue }}"
  },
  body: JSON.stringify({
    number: "6282146727409",
    message: "Here is the document",
    media: {
      data: "BASE64_ENCODED_DATA",
      mimetype: "application/pdf",
      filename: "document.pdf"
    }
  })
}).then(r => r.json()).then(console.log);
const axios = require('axios');
const fs = require('fs');
const fileData = fs.readFileSync('document.pdf').toString('base64');
axios.post('{{ baseUrl }}/api/send-message', {
  number: '6282146727409',
  message: 'Here is the document',
  media: {
    data: fileData,
    mimetype: 'application/pdf',
    filename: 'document.pdf'
  }
}, {
  headers: { 'X-API-Key': '{{ apiKeyValue }}' }
}).then(res => console.log(res.data));
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
final dio = Dio();
final bytes = await File('document.pdf').readAsBytes();
final response = await dio.post('{{ baseUrl }}/api/send-message',
  data: {
    'number': '6282146727409',
    'message': 'Here is the document',
    'media': {
      'data': base64Encode(bytes),
      'mimetype': 'application/pdf',
      'filename': 'document.pdf'
    }
  },
  options: Options(headers: {'X-API-Key': '{{ apiKeyValue }}'}),
);
print(response.data);
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
final bytes = await File('document.pdf').readAsBytes();
final response = await http.post(
  Uri.parse('{{ baseUrl }}/api/send-message'),
  headers: {'Content-Type': 'application/json', 'X-API-Key': '{{ apiKeyValue }}'},
  body: jsonEncode({
    'number': '6282146727409',
    'message': 'Here is the document',
    'media': {
      'data': base64Encode(bytes),
      'mimetype': 'application/pdf',
      'filename': 'document.pdf'
    }
  }),
);
print(response.body);
Send Media Only (no caption)
curl -X POST {{ baseUrl }}/api/send-message \
  -H "Content-Type: application/json" \
  -H "X-API-Key: {{ apiKeyValue }}" \
  -d '{
  "number": "6282146727409",
  "media": { "url": "https://example.com/photo.jpg" }
}'
// Same as above examples, just omit the "message" field.
// Only "number" (or "recipients") + "media" is required.
📌 Notes:
  • Use "number" for a single recipient or "recipients" array for multiple.
  • Use "main" as number to send to your configured Main Number ({{ mainNumber }}).
  • Phone numbers: use country code without + (e.g. 6282146727409).
  • Group IDs: use the full ID ending with @g.us (e.g. 120363xxx@g.us).
  • You can mix phone numbers and group IDs in the "recipients" array.
  • Media: Use "media": {"url": "..."} to send from a URL, or "media": {"data": "BASE64", "mimetype": "...", "filename": "..."} for base64.
  • "message" is optional when sending media — it becomes the caption. You can send media without text.
  • Either "message" or "media" (or both) must be provided.
  • Reference ID: Pass "reference_id" to tag messages with your own tracking ID.

🔍 Check Message Status

Check the delivery status of a queued message by its queue ID or your custom reference_id.

GET /api/message-status/:id
Send with reference_id
curl -X POST {{ baseUrl }}/api/send-message \
  -H "Content-Type: application/json" \
  -H "X-API-Key: {{ apiKeyValue }}" \
  -d '{
  "number": "6282146727409",
  "message": "Hello!",
  "reference_id": "order-12345"
}'
fetch("{{ baseUrl }}/api/send-message", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "{{ apiKeyValue }}"
  },
  body: JSON.stringify({
    number: "6282146727409",
    message: "Hello!",
    reference_id: "order-12345"
  })
}).then(r => r.json()).then(console.log);
const axios = require('axios');
axios.post('{{ baseUrl }}/api/send-message', {
  number: '6282146727409',
  message: 'Hello!',
  reference_id: 'order-12345'
}, {
  headers: { 'X-API-Key': '{{ apiKeyValue }}' }
}).then(res => console.log(res.data));
import 'package:dio/dio.dart';
final dio = Dio();
final response = await dio.post('{{ baseUrl }}/api/send-message',
  data: {
    'number': '6282146727409',
    'message': 'Hello!',
    'reference_id': 'order-12345'
  },
  options: Options(headers: {'X-API-Key': '{{ apiKeyValue }}'}),
);
print(response.data);
import 'dart:convert';
import 'package:http/http.dart' as http;
final response = await http.post(
  Uri.parse('{{ baseUrl }}/api/send-message'),
  headers: {'Content-Type': 'application/json', 'X-API-Key': '{{ apiKeyValue }}'},
  body: jsonEncode({
    'number': '6282146727409',
    'message': 'Hello!',
    'reference_id': 'order-12345'
  }),
);
print(response.body);
Check status
curl {{ baseUrl }}/api/message-status/order-12345 \
  -H "X-API-Key: {{ apiKeyValue }}"
fetch("{{ baseUrl }}/api/message-status/order-12345", {
  headers: { "X-API-Key": "{{ apiKeyValue }}" }
}).then(r => r.json()).then(console.log);
const axios = require('axios');
axios.get('{{ baseUrl }}/api/message-status/order-12345', {
  headers: { 'X-API-Key': '{{ apiKeyValue }}' }
}).then(res => console.log(res.data));
import 'package:dio/dio.dart';
final dio = Dio();
final response = await dio.get('{{ baseUrl }}/api/message-status/order-12345',
  options: Options(headers: {'X-API-Key': '{{ apiKeyValue }}'}),
);
print(response.data);
import 'dart:convert';
import 'package:http/http.dart' as http;
final response = await http.get(
  Uri.parse('{{ baseUrl }}/api/message-status/order-12345'),
  headers: {'X-API-Key': '{{ apiKeyValue }}'},
);
print(jsonDecode(response.body));
Response
{
  "id": "uuid-queue-id",
  "reference_id": "order-12345",
  "number": "6282146727409",
  "chatId": "6282146727409@c.us",
  "message": "Hello!",
  "status": "sent",   // pending | sending | sent | failed
  "error": null,
  "createdAt": 1709654400000,
  "sentAt": 1709654405000
}