whatsapp-cli-pro 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/index.js +245 -0
- package/package.json +29 -0
- package/readme.md +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jack Williams
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/index.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { Client, LocalAuth } = require('whatsapp-web.js');
|
|
3
|
+
const qrcode = require('qrcode-terminal');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const figlet = require('figlet');
|
|
6
|
+
const gradient = require('gradient-string');
|
|
7
|
+
const boxen = require('boxen');
|
|
8
|
+
const inquirer = require('inquirer');
|
|
9
|
+
const notifier = require('node-notifier');
|
|
10
|
+
|
|
11
|
+
// --- THEME CONFIGURATION ---
|
|
12
|
+
const theme = {
|
|
13
|
+
logo: gradient('cyan', 'blue', 'magenta'),
|
|
14
|
+
text: chalk.cyanBright,
|
|
15
|
+
border: 'magenta',
|
|
16
|
+
wa: chalk.hex('#25D366'),
|
|
17
|
+
warning: chalk.hex('#F7E01D'),
|
|
18
|
+
dim: chalk.dim
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const client = new Client({
|
|
22
|
+
authStrategy: new LocalAuth(),
|
|
23
|
+
puppeteer: {
|
|
24
|
+
args: ['--no-sandbox'],
|
|
25
|
+
headless: true
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// --- UTILS ---
|
|
30
|
+
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
|
|
31
|
+
const clearScreen = () => console.clear();
|
|
32
|
+
|
|
33
|
+
// --- DISPLAY COMPONENTS ---
|
|
34
|
+
|
|
35
|
+
const showBanner = () => {
|
|
36
|
+
const bigTitle = figlet.textSync('WhatsApp - CLI', {
|
|
37
|
+
font: 'ANSI Shadow',
|
|
38
|
+
horizontalLayout: 'full'
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
console.log(theme.logo(bigTitle));
|
|
42
|
+
console.log(theme.dim('━'.repeat(65)));
|
|
43
|
+
console.log(gradient.pastel(' >> SECURE TERMINAL CONNECTION ESTABLISHED <<'));
|
|
44
|
+
console.log(theme.dim('━'.repeat(65)));
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
async function showBootSequence() {
|
|
48
|
+
clearScreen();
|
|
49
|
+
const steps = [
|
|
50
|
+
'Initializing core modules...',
|
|
51
|
+
'Bypassing local firewalls...',
|
|
52
|
+
'Decrypting session keys...',
|
|
53
|
+
'Connecting to WhatsApp servers...',
|
|
54
|
+
'Handshake successful.',
|
|
55
|
+
'Loading interface...'
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
for (const step of steps) {
|
|
59
|
+
process.stdout.write(theme.text(`[SYSTEM] ${step}`));
|
|
60
|
+
await sleep(300);
|
|
61
|
+
process.stdout.clearLine();
|
|
62
|
+
process.stdout.cursorTo(0);
|
|
63
|
+
console.log(chalk.green(`[OK] ${step}`));
|
|
64
|
+
}
|
|
65
|
+
await sleep(500);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// --- MAIN MENUS ---
|
|
69
|
+
|
|
70
|
+
async function showMainMenu() {
|
|
71
|
+
clearScreen();
|
|
72
|
+
showBanner();
|
|
73
|
+
|
|
74
|
+
// Info Bar
|
|
75
|
+
if (client.info) {
|
|
76
|
+
console.log(boxen(`${chalk.bold(client.info.pushname)} | ${client.info.wid.user} | Battery: ${await getBattery()}`, {
|
|
77
|
+
padding: 0, borderStyle: 'classic', borderColor: 'gray', dimBorder: true
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const answers = await inquirer.prompt([
|
|
82
|
+
{
|
|
83
|
+
type: 'list',
|
|
84
|
+
name: 'action',
|
|
85
|
+
message: theme.text('SELECT OPERATION >'),
|
|
86
|
+
choices: [
|
|
87
|
+
{ name: '📨 Open Chat List', value: 'chat_list' },
|
|
88
|
+
{ name: '📡 Broadcast / Manual', value: 'manual' },
|
|
89
|
+
{ name: '❓ Help / Manual', value: 'help' },
|
|
90
|
+
{ name: '❌ Terminate Session', value: 'exit' }
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
]);
|
|
94
|
+
|
|
95
|
+
handleMenu(answers.action);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async function handleMenu(action) {
|
|
99
|
+
switch(action) {
|
|
100
|
+
case 'chat_list': await showContactPicker(); break;
|
|
101
|
+
case 'manual': await manualInput(); break;
|
|
102
|
+
case 'help': await showHelpScreen(); break;
|
|
103
|
+
case 'exit':
|
|
104
|
+
console.log(chalk.red('Terminating...'));
|
|
105
|
+
process.exit(0);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// --- HELP SCREEN ---
|
|
111
|
+
async function showHelpScreen() {
|
|
112
|
+
clearScreen();
|
|
113
|
+
|
|
114
|
+
const helpContent = `
|
|
115
|
+
${chalk.bold.underline('NAVIGATION GUIDE')}
|
|
116
|
+
• Use ${chalk.yellow('UP/DOWN')} arrow keys to navigate menus.
|
|
117
|
+
• Press ${chalk.yellow('ENTER')} to select an option.
|
|
118
|
+
|
|
119
|
+
${chalk.bold.underline('CHAT ROOM COMMANDS')}
|
|
120
|
+
• Type your message and press ENTER to send.
|
|
121
|
+
• Type ${theme.warning('"menu"')} (without quotes) to exit the chat room.
|
|
122
|
+
|
|
123
|
+
${chalk.bold.underline('ICONS LEGEND')}
|
|
124
|
+
📨 : Unread Messages / Chat List
|
|
125
|
+
📡 : Manual Send (By typing number)
|
|
126
|
+
❌ : Exit Application
|
|
127
|
+
`.trim();
|
|
128
|
+
|
|
129
|
+
console.log(boxen(helpContent, {
|
|
130
|
+
title: 'SYSTEM MANUAL',
|
|
131
|
+
titleAlignment: 'center',
|
|
132
|
+
borderStyle: 'double',
|
|
133
|
+
borderColor: 'cyan',
|
|
134
|
+
padding: 1,
|
|
135
|
+
margin: 1
|
|
136
|
+
}));
|
|
137
|
+
|
|
138
|
+
await inquirer.prompt([{ type: 'input', name: 'back', message: 'Press ENTER to return to Main Menu...' }]);
|
|
139
|
+
showMainMenu();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// --- CHAT FUNCTIONS ---
|
|
143
|
+
|
|
144
|
+
async function getBattery() {
|
|
145
|
+
try {
|
|
146
|
+
const batt = await client.getInterface().getBatteryStatus();
|
|
147
|
+
return `${batt.battery}%`;
|
|
148
|
+
} catch (e) { return 'N/A'; }
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function showContactPicker() {
|
|
152
|
+
const chats = await client.getChats();
|
|
153
|
+
const recentChats = chats.slice(0, 12).map(chat => ({
|
|
154
|
+
name: `${chat.name} ${chat.unreadCount > 0 ? chalk.red(`(${chat.unreadCount})`) : ''}`,
|
|
155
|
+
value: chat.id._serialized
|
|
156
|
+
}));
|
|
157
|
+
|
|
158
|
+
recentChats.push(new inquirer.Separator());
|
|
159
|
+
recentChats.push({ name: '🔙 Back', value: 'back' });
|
|
160
|
+
|
|
161
|
+
const { id } = await inquirer.prompt([{
|
|
162
|
+
type: 'list',
|
|
163
|
+
name: 'id',
|
|
164
|
+
message: 'Select Target:',
|
|
165
|
+
choices: recentChats,
|
|
166
|
+
pageSize: 15
|
|
167
|
+
}]);
|
|
168
|
+
|
|
169
|
+
if (id === 'back') return showMainMenu();
|
|
170
|
+
await enterChatRoom(id);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async function enterChatRoom(chatId) {
|
|
174
|
+
clearScreen();
|
|
175
|
+
const chat = await client.getChatById(chatId);
|
|
176
|
+
|
|
177
|
+
// Header
|
|
178
|
+
console.log(gradient.cristal(figlet.textSync(chat.name.substring(0, 10), { font: 'Standard' })));
|
|
179
|
+
console.log(theme.dim('------------------------------------------------'));
|
|
180
|
+
|
|
181
|
+
// Messages
|
|
182
|
+
const messages = await chat.fetchMessages({ limit: 8 });
|
|
183
|
+
messages.forEach(msg => {
|
|
184
|
+
const time = new Date(msg.timestamp * 1000).toLocaleTimeString('en-US', {hour: '2-digit', minute:'2-digit'});
|
|
185
|
+
if (msg.fromMe) {
|
|
186
|
+
console.log(chalk.cyan(`[${time}] Me:`));
|
|
187
|
+
console.log(chalk.white(msg.body));
|
|
188
|
+
} else {
|
|
189
|
+
console.log(theme.wa(`[${time}] ${chat.name}:`));
|
|
190
|
+
console.log(chalk.white(msg.body));
|
|
191
|
+
}
|
|
192
|
+
console.log('');
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Reply Input
|
|
196
|
+
const { reply } = await inquirer.prompt([{
|
|
197
|
+
type: 'input',
|
|
198
|
+
name: 'reply',
|
|
199
|
+
message: theme.logo('Type message (type "menu" to exit) >')
|
|
200
|
+
}]);
|
|
201
|
+
|
|
202
|
+
if (reply.toLowerCase() === 'menu') return showMainMenu();
|
|
203
|
+
|
|
204
|
+
if (reply.trim()) {
|
|
205
|
+
await chat.sendMessage(reply);
|
|
206
|
+
}
|
|
207
|
+
await enterChatRoom(chatId);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async function manualInput() {
|
|
211
|
+
const q = await inquirer.prompt([
|
|
212
|
+
{ type: 'input', name: 'num', message: 'Target Number (628...):' },
|
|
213
|
+
{ type: 'input', name: 'msg', message: 'Message Payload:' }
|
|
214
|
+
]);
|
|
215
|
+
const finalNum = q.num.includes('@c.us') ? q.num : `${q.num}@c.us`;
|
|
216
|
+
await client.sendMessage(finalNum, q.msg);
|
|
217
|
+
console.log(chalk.green('>> Payload Delivered'));
|
|
218
|
+
await sleep(1500);
|
|
219
|
+
showMainMenu();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// --- INIT ---
|
|
223
|
+
|
|
224
|
+
client.on('qr', (qr) => {
|
|
225
|
+
clearScreen();
|
|
226
|
+
console.log(chalk.yellow('Waiting for authentication...'));
|
|
227
|
+
qrcode.generate(qr, { small: true });
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
client.on('ready', async () => {
|
|
231
|
+
await showBootSequence();
|
|
232
|
+
showMainMenu();
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
client.on('message', async msg => {
|
|
236
|
+
const contact = await msg.getContact();
|
|
237
|
+
const name = contact.pushname || contact.number;
|
|
238
|
+
notifier.notify({
|
|
239
|
+
title: `New Message: ${name}`,
|
|
240
|
+
message: msg.body,
|
|
241
|
+
sound: true
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
client.initialize();
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "whatsapp-cli-pro",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "WhatsApp CLI made by Jack Williams",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"whatsapp-cli": "./index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
|
+
},
|
|
12
|
+
"preferGlobal": true,
|
|
13
|
+
"keywords": ["whatsapp", "cli", "terminal"],
|
|
14
|
+
"author": "Jack Williams",
|
|
15
|
+
"license": "ISC",
|
|
16
|
+
"type": "commonjs",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"boxen": "^5.1.2",
|
|
19
|
+
"chalk": "^4.1.2",
|
|
20
|
+
"figlet": "^1.9.4",
|
|
21
|
+
"gradient-string": "^2.0.2",
|
|
22
|
+
"inquirer": "^8.2.7",
|
|
23
|
+
"node-notifier": "^10.0.1",
|
|
24
|
+
"ora": "^5.4.1",
|
|
25
|
+
"qrcode": "^1.5.4",
|
|
26
|
+
"qrcode-terminal": "^0.12.0",
|
|
27
|
+
"whatsapp-web.js": "^1.34.2"
|
|
28
|
+
}
|
|
29
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# WhatsApp CLI Pro
|
|
2
|
+
|
|
3
|
+
 
|
|
4
|
+
|
|
5
|
+
A professional Command Line Interface (CLI) tool for sending and receiving WhatsApp messages directly from your terminal. Built with Node.js and `whatsapp-web.js`.
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
* **Real-time Messaging:** Send and receive messages instantly.
|
|
10
|
+
* **QR Code Authentication:** Login easily by scanning a QR code, just like WhatsApp Web.
|
|
11
|
+
* **Session Persistence:** Login state is saved locally, so you don't need to rescan every time.
|
|
12
|
+
* **Beautiful UI:** Interactive terminal interface with colored output (`chalk`) and ASCII banners (`figlet`).
|
|
13
|
+
* **Lightweight:** Runs purely on Node.js without a browser window (headless).
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
1. **Clone the repository:**
|
|
18
|
+
```bash
|
|
19
|
+
git clone [https://github.com/YOUR_USERNAME/wa-cli-pro.git](https://github.com/YOUR_USERNAME/wa-cli-pro.git)
|
|
20
|
+
cd wa-cli-pro
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
2. **Install dependencies:**
|
|
24
|
+
```bash
|
|
25
|
+
npm install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
3. **Run the application:**
|
|
29
|
+
```bash
|
|
30
|
+
node index.js
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
1. Run the script using `node index.js`.
|
|
36
|
+
2. Scan the QR Code that appears in your terminal using your WhatsApp mobile app (Linked Devices).
|
|
37
|
+
3. Once connected, use the following commands:
|
|
38
|
+
|
|
39
|
+
**Send a message:**
|
|
40
|
+
```bash
|
|
41
|
+
> send 628123456789 Hello from Terminal!
|
|
42
|
+
```
|
|
43
|
+
*(Note: Use the country code, e.g., 62 for Indonesia, without '0' or '+')*
|
|
44
|
+
|
|
45
|
+
**Exit the application:**
|
|
46
|
+
```bash
|
|
47
|
+
> exit
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## ⚠️ Disclaimer
|
|
51
|
+
|
|
52
|
+
This project is for **educational purposes only**. It uses the `whatsapp-web.js` library which emulates a browser instance of WhatsApp Web. It is not affiliated with, associated with, or endorsed by WhatsApp Inc. Use responsibly to avoid your account being restricted.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
Created by [Your Name]
|