@innovatorssoft/innovators-bot2 1.2.8
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/README.md +718 -0
- package/example.jpg +0 -0
- package/example.js +710 -0
- package/index.js +1494 -0
- package/package.json +42 -0
- package/publish-dual.js +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,718 @@
|
|
|
1
|
+
# INNOVATORS SOFT WhatsApp Bot 2
|
|
2
|
+
|
|
3
|
+
A powerful WhatsApp client library that provides seamless integration between Baileys and WhatsApp-web.js style APIs. This library makes it easy to create WhatsApp bots and automation tools with a familiar interface.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 Easy to use, familiar WhatsApp-web.js style API
|
|
8
|
+
- 📱 Multi-device support (Baileys v7.x.x)
|
|
9
|
+
- 💬 Send and receive messages
|
|
10
|
+
- � Message reactions (add/remove emoji reactions)
|
|
11
|
+
- �📸 Media handling (images, videos, documents)
|
|
12
|
+
- 👥 Group management
|
|
13
|
+
- 💾 Message history and chat management
|
|
14
|
+
- 🔄 Auto-reconnect functionality
|
|
15
|
+
- 📝 Read receipts
|
|
16
|
+
- 🔐 LID (Local Identifier) support for enhanced privacy
|
|
17
|
+
- 🗂️ Signal repository store for LID/PN mapping
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install innovators-bot2
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start With Qr Code
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
const { WhatsAppClient } = require('innovators-bot2')
|
|
29
|
+
const qrcode = require('qrcode-terminal')
|
|
30
|
+
|
|
31
|
+
// Create client instance
|
|
32
|
+
const client = new WhatsAppClient({ sessionName: ".Sessions" });
|
|
33
|
+
|
|
34
|
+
// Handle QR Code
|
|
35
|
+
client.on('qr', qr => {
|
|
36
|
+
qrcode.generate(qr, { small: true })
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
// Handle ready event
|
|
40
|
+
client.on('connected', () => {
|
|
41
|
+
console.log('Client is ready!')
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// Connect to WhatsApp
|
|
45
|
+
client.connect()
|
|
46
|
+
```
|
|
47
|
+
## Quick Start With Pairing code
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
const { WhatsAppClient } = require('innovators-bot2')
|
|
51
|
+
const qrcode = require('qrcode-terminal')
|
|
52
|
+
const config = require('./config.json');
|
|
53
|
+
|
|
54
|
+
// Get authmethod from config file (default to 'qr' if not specified)
|
|
55
|
+
const authMethod = (config.whatsapp && config.whatsapp.authMethod) || 'qr';
|
|
56
|
+
|
|
57
|
+
const client = new WhatsAppClient({
|
|
58
|
+
sessionName: ".Sessions",
|
|
59
|
+
authmethod: authMethod
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Handle ready event
|
|
63
|
+
client.on('connected', () => {
|
|
64
|
+
console.log('Client is ready!')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
// Connect to WhatsApp
|
|
68
|
+
client.connect()
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Usage Examples
|
|
72
|
+
|
|
73
|
+
### 1. Basic Messaging
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
// Send a text message
|
|
77
|
+
await client.sendMessage('1234567890@s.whatsapp.net', 'Hello world!')
|
|
78
|
+
|
|
79
|
+
// Send a reply
|
|
80
|
+
await client.reply('1234567890@s.whatsapp.net', 'This is a reply', {
|
|
81
|
+
quoted: originalMessage
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
// Send with mentions
|
|
85
|
+
await client.sendMessage('1234567890@s.whatsapp.net', {
|
|
86
|
+
type: 'text',
|
|
87
|
+
text: 'Hey @user!',
|
|
88
|
+
mentions: ['user@s.whatsapp.net']
|
|
89
|
+
})
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 2. Media Handling
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
// Send an image
|
|
96
|
+
await client.sendMedia('1234567890@s.whatsapp.net', './image.jpg', {
|
|
97
|
+
caption: 'Check out this image!'
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
// Send a document
|
|
101
|
+
await client.sendDocument('1234567890@s.whatsapp.net', './document.pdf',
|
|
102
|
+
'Check out this document!'
|
|
103
|
+
)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 3. Sticker Management
|
|
107
|
+
|
|
108
|
+
Create stickers easily from any image buffer with automatic conversion and metadata support.
|
|
109
|
+
|
|
110
|
+
```javascript
|
|
111
|
+
const fs = require('fs');
|
|
112
|
+
|
|
113
|
+
// Send a sticker from an image or video buffer
|
|
114
|
+
const buffer = fs.readFileSync('./image.jpg');
|
|
115
|
+
await client.sendSticker('1234567890@s.whatsapp.net', buffer, {
|
|
116
|
+
packName: 'Innovators',
|
|
117
|
+
author: 'Innovators Bot',
|
|
118
|
+
type: 'full', // 'full' or 'crop'
|
|
119
|
+
quality: 50
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 4. Anti-Delete System
|
|
124
|
+
|
|
125
|
+
The library includes a built-in Anti-Delete system that tracks deleted messages in real-time.
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
128
|
+
// Listen for deleted messages
|
|
129
|
+
client.on('message-deleted', async (data) => {
|
|
130
|
+
console.log(`User ${data.jid} deleted a message!`);
|
|
131
|
+
|
|
132
|
+
// Content of the deleted message
|
|
133
|
+
const original = data.originalMessage;
|
|
134
|
+
|
|
135
|
+
// Reply to the chat with the deleted content
|
|
136
|
+
await client.sendMessage(data.jid, 'I saw that! 😉', {
|
|
137
|
+
quoted: original
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 5. Group Management
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
// Get all groups
|
|
146
|
+
const groups = await client.getAllGroups()
|
|
147
|
+
|
|
148
|
+
// Add participant to group
|
|
149
|
+
// Note: If adding fails due to user's privacy settings (403),
|
|
150
|
+
// an invitation link is automatically sent to the user instead.
|
|
151
|
+
const result = await client.changeGroupParticipants(groupId, ['1234567890@s.whatsapp.net'], 'add')
|
|
152
|
+
|
|
153
|
+
if (result[0].status === 403 && result[0].invitationSent) {
|
|
154
|
+
console.log('User has privacy settings enabled. Invitation link sent!')
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Send a manual group invitation link
|
|
158
|
+
await client.sendGroupInvitation(groupId, '1234567890@s.whatsapp.net', 'Join my group!')
|
|
159
|
+
|
|
160
|
+
// Remove participant
|
|
161
|
+
await client.changeGroupParticipants(groupId, ['1234567890@s.whatsapp.net'], 'remove')
|
|
162
|
+
|
|
163
|
+
// Promote to admin
|
|
164
|
+
await client.changeGroupParticipants(groupId, ['1234567890@s.whatsapp.net'], 'promote')
|
|
165
|
+
|
|
166
|
+
// Demote admin
|
|
167
|
+
await client.changeGroupParticipants(groupId, ['1234567890@s.whatsapp.net'], 'demote')
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### 4. Interactive Messages
|
|
171
|
+
|
|
172
|
+
#### Buttons
|
|
173
|
+
```javascript
|
|
174
|
+
// Send interactive buttons
|
|
175
|
+
await client.sendButtons('1234567890@s.whatsapp.net', {
|
|
176
|
+
text: 'Do you like this bot?',
|
|
177
|
+
title: 'Feedback',
|
|
178
|
+
subtitle: 'Let us know!',
|
|
179
|
+
footer: 'Powered by Baileys',
|
|
180
|
+
interactiveButtons: [
|
|
181
|
+
{
|
|
182
|
+
name: 'quick_reply',
|
|
183
|
+
buttonParamsJson: JSON.stringify({
|
|
184
|
+
display_text: '✅ Yes',
|
|
185
|
+
id: 'text_yes'
|
|
186
|
+
})
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: 'quick_reply',
|
|
190
|
+
buttonParamsJson: JSON.stringify({
|
|
191
|
+
display_text: '❌ No',
|
|
192
|
+
id: 'text_no'
|
|
193
|
+
})
|
|
194
|
+
}
|
|
195
|
+
]
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
#### List Messages
|
|
200
|
+
```javascript
|
|
201
|
+
// Send interactive list
|
|
202
|
+
await client.SendList('1234567890@s.whatsapp.net', {
|
|
203
|
+
text: 'Please select an option:',
|
|
204
|
+
title: 'Main Menu',
|
|
205
|
+
buttonText: 'View Options',
|
|
206
|
+
footer: 'Scroll to see more options',
|
|
207
|
+
sections: [
|
|
208
|
+
{
|
|
209
|
+
title: 'Account',
|
|
210
|
+
rows: [
|
|
211
|
+
{ title: 'Profile', id: 'profile', description: 'View your profile' },
|
|
212
|
+
{ title: 'Settings', id: 'settings', description: 'Account settings' }
|
|
213
|
+
]
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
title: 'Help',
|
|
217
|
+
rows: [
|
|
218
|
+
{ title: 'Support', id: 'support', description: 'Contact support' },
|
|
219
|
+
{ title: 'About', id: 'about', description: 'About this bot' }
|
|
220
|
+
]
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 4. Message History
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
// Get chat history
|
|
230
|
+
const messages = await client.loadMessages(chatId, 50)
|
|
231
|
+
|
|
232
|
+
// Get specific message
|
|
233
|
+
const message = await client.loadMessage(chatId, messageId)
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## More Examples and Information
|
|
237
|
+
|
|
238
|
+
For a complete working example with message handling, group management, and error handling, check out our [`example.js`](https://github.com/innovatorssoft/innovators-bot2/blob/main/example.js) file. This example includes:
|
|
239
|
+
|
|
240
|
+
- 🔄 Connection handling and QR code generation
|
|
241
|
+
- 📨 Message handling with commands
|
|
242
|
+
- 👥 Group management examples
|
|
243
|
+
- ⚡ Event listeners for various scenarios
|
|
244
|
+
- 🛠️ Error handling and logging
|
|
245
|
+
|
|
246
|
+
Feel free to use this example as a starting point for your WhatsApp bot implementation.
|
|
247
|
+
|
|
248
|
+
## Bot Commands
|
|
249
|
+
|
|
250
|
+
The library includes example bot commands that you can use:
|
|
251
|
+
|
|
252
|
+
### Basic Commands
|
|
253
|
+
- `!ping` - Check if bot is alive
|
|
254
|
+
- `!echo <text>` - Echo back your text
|
|
255
|
+
- `!help` - Show all available commands
|
|
256
|
+
|
|
257
|
+
### Messaging
|
|
258
|
+
- `!mention` - Mention you in a message
|
|
259
|
+
- `!reply` - Reply to your message
|
|
260
|
+
- `!react` - React to your message with ❤️
|
|
261
|
+
- `!read` - Mark messages as read
|
|
262
|
+
- `!typing` - Show typing indicator
|
|
263
|
+
- `!presence` - Set online presence
|
|
264
|
+
|
|
265
|
+
### Media & Content
|
|
266
|
+
- `!media` - Send an example image
|
|
267
|
+
- `!doc` - Send an example document
|
|
268
|
+
- `!location` - Send a location
|
|
269
|
+
- `!contact` - Send a contact card
|
|
270
|
+
|
|
271
|
+
### Group Management
|
|
272
|
+
- `!groups` - List all your groups
|
|
273
|
+
- `!add <number>` - Add participant to group
|
|
274
|
+
- `!remove <number>` - Remove participant from group
|
|
275
|
+
- `!promote <number>` - Promote participant to admin
|
|
276
|
+
- `!demote <number>` - Demote admin to participant
|
|
277
|
+
- `!list` - Show interactive list message
|
|
278
|
+
|
|
279
|
+
### Interactive Messages
|
|
280
|
+
- `!buttons` - Show interactive buttons
|
|
281
|
+
- `!list` - Display a scrollable list
|
|
282
|
+
- `!logout` - Logout from current session
|
|
283
|
+
|
|
284
|
+
### 🛡️ Protection
|
|
285
|
+
- `Anti-Delete` - Automatically tracks and emits events for deleted messages
|
|
286
|
+
|
|
287
|
+
### 🔐 JID & LID/PN Management (v7.x.x)
|
|
288
|
+
- `!lid` - Get your LID (Local Identifier)
|
|
289
|
+
- `!pn <lid>` - Get phone number from a LID
|
|
290
|
+
- `!parse <jid>` - Parse detailed JID information
|
|
291
|
+
- `!normalize <number>` - Normalize a number to JID format
|
|
292
|
+
|
|
293
|
+
### 🎨 Sticker Commands
|
|
294
|
+
- `!sticker` - Create a sticker from an image
|
|
295
|
+
|
|
296
|
+
### Connection Events
|
|
297
|
+
```javascript
|
|
298
|
+
// When QR code is generated
|
|
299
|
+
client.on('qr', qr => {
|
|
300
|
+
qrcode.generate(qr, { small: true })
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
// When connection is established
|
|
304
|
+
client.on('connected', () => {
|
|
305
|
+
console.log('Client is ready!')
|
|
306
|
+
})
|
|
307
|
+
|
|
308
|
+
// When connection is in progress
|
|
309
|
+
client.on('connecting', (message) => {
|
|
310
|
+
console.log('Connection status:', message)
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
// When disconnected
|
|
314
|
+
client.on('disconnected', (error) => {
|
|
315
|
+
console.log('Client disconnected:', error)
|
|
316
|
+
})
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Message Events
|
|
320
|
+
```javascript
|
|
321
|
+
// When a new message is received
|
|
322
|
+
client.on('message', async msg => {
|
|
323
|
+
console.log('Message from:', msg.from)
|
|
324
|
+
console.log('Message content:', msg.body)
|
|
325
|
+
|
|
326
|
+
// Mark message as read
|
|
327
|
+
await client.readMessage(msg.raw.key)
|
|
328
|
+
|
|
329
|
+
// Handle different message types
|
|
330
|
+
if (msg.hasMedia) {
|
|
331
|
+
console.log('Message contains media')
|
|
332
|
+
// Handle media message
|
|
333
|
+
}
|
|
334
|
+
})
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Message Reaction Events
|
|
338
|
+
|
|
339
|
+
Listen for when users add or remove reactions (emojis) from messages:
|
|
340
|
+
|
|
341
|
+
```javascript
|
|
342
|
+
// When a message receives a reaction
|
|
343
|
+
client.on('message-reaction', async (reaction) => {
|
|
344
|
+
console.log('Reaction received!')
|
|
345
|
+
console.log('Chat:', reaction.from)
|
|
346
|
+
console.log('Sender:', reaction.sender)
|
|
347
|
+
console.log('Emoji:', reaction.emoji)
|
|
348
|
+
console.log('Is removed:', reaction.isRemoved)
|
|
349
|
+
|
|
350
|
+
// Check if reaction was added or removed
|
|
351
|
+
if (reaction.isRemoved) {
|
|
352
|
+
console.log('User removed their reaction')
|
|
353
|
+
} else {
|
|
354
|
+
console.log(`User reacted with: ${reaction.emoji}`)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Access the message key that was reacted to
|
|
358
|
+
console.log('Message ID:', reaction.messageKey.id)
|
|
359
|
+
|
|
360
|
+
// For group messages, get the participant who reacted
|
|
361
|
+
if (reaction.from.endsWith('@g.us')) {
|
|
362
|
+
console.log('Participant who reacted:', reaction.sender)
|
|
363
|
+
}
|
|
364
|
+
})
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
#### Reaction Event Data Structure
|
|
368
|
+
|
|
369
|
+
The `message-reaction` event provides the following data:
|
|
370
|
+
|
|
371
|
+
| Property | Type | Description |
|
|
372
|
+
|----------|------|-------------|
|
|
373
|
+
| `from` | `string` | Chat JID where the reaction occurred (prefers PN over LID) |
|
|
374
|
+
| `sender` | `string` | JID of the user who reacted (in groups, this is the participant) |
|
|
375
|
+
| `participant` | `string\|null` | Original participant JID (could be LID or PN) |
|
|
376
|
+
| `participantAlt` | `string\|null` | Alternate participant JID format |
|
|
377
|
+
| `emoji` | `string\|null` | The emoji used for the reaction (null if removed) |
|
|
378
|
+
| `isRemoved` | `boolean` | `true` if the reaction was removed, `false` if added |
|
|
379
|
+
| `messageKey` | `object` | The message key object that was reacted to |
|
|
380
|
+
| `timestamp` | `Date` | When the reaction event was processed |
|
|
381
|
+
| `raw` | `object` | Raw reaction data from Baileys |
|
|
382
|
+
|
|
383
|
+
#### Sending Reactions
|
|
384
|
+
|
|
385
|
+
You can also send reactions to messages programmatically:
|
|
386
|
+
|
|
387
|
+
```javascript
|
|
388
|
+
// React to a message
|
|
389
|
+
await client.sendMessage(chatId, {
|
|
390
|
+
type: 'reaction',
|
|
391
|
+
emoji: '❤️',
|
|
392
|
+
messageKey: messageToReactTo.key
|
|
393
|
+
})
|
|
394
|
+
|
|
395
|
+
// Remove a reaction (send empty emoji)
|
|
396
|
+
await client.sendMessage(chatId, {
|
|
397
|
+
type: 'reaction',
|
|
398
|
+
emoji: '',
|
|
399
|
+
messageKey: messageToReactTo.key
|
|
400
|
+
})
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### LID Mapping Events
|
|
404
|
+
```javascript
|
|
405
|
+
// Listen for LID/PN mapping updates
|
|
406
|
+
client.on('lid-mapping-update', (update) => {
|
|
407
|
+
console.log('New LID/PN mappings received:', update)
|
|
408
|
+
// Handle new mappings as needed
|
|
409
|
+
})
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Error Handling
|
|
413
|
+
|
|
414
|
+
```javascript
|
|
415
|
+
// Global error handler
|
|
416
|
+
client.on('error', error => {
|
|
417
|
+
console.error('Client Error:', error)
|
|
418
|
+
// Handle specific error types
|
|
419
|
+
if (error.message.includes('Connection Closed')) {
|
|
420
|
+
console.log('Attempting to reconnect...')
|
|
421
|
+
client.connect()
|
|
422
|
+
}
|
|
423
|
+
})
|
|
424
|
+
|
|
425
|
+
// Example with try-catch
|
|
426
|
+
try {
|
|
427
|
+
await client.sendMessage(to, message)
|
|
428
|
+
} catch (error) {
|
|
429
|
+
console.error('Error sending message:', error)
|
|
430
|
+
if (error.message.includes('Not connected')) {
|
|
431
|
+
console.log('Reconnecting...')
|
|
432
|
+
await client.connect()
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
## Baileys v7.x.x LID Store Implementation
|
|
438
|
+
|
|
439
|
+
### Overview
|
|
440
|
+
|
|
441
|
+
This library fully supports Baileys v7.x.x LID (Local Identifier) system for enhanced privacy and WhatsApp's transition to username-based identification.
|
|
442
|
+
|
|
443
|
+
| Feature | Description |
|
|
444
|
+
|---------|-------------|
|
|
445
|
+
| **LID Support** | Full support for Local Identifiers alongside Phone Numbers |
|
|
446
|
+
| **Store Access** | Automatic initialization via `client.sock.signalRepository.lidMapping` |
|
|
447
|
+
| **Helper Methods** | `getLIDForPN()`, `getPNForLID()`, `getLIDsForPNs()` |
|
|
448
|
+
| **Event Handling** | `lid-mapping-update` event for real-time mapping updates |
|
|
449
|
+
| **Message Handling** | Automatic preference for PN over LID with fallback support |
|
|
450
|
+
| **Compatibility** | Backward compatible with v6.x code patterns |
|
|
451
|
+
|
|
452
|
+
### What are LIDs?
|
|
453
|
+
|
|
454
|
+
**LID (Local Identifier)** is WhatsApp's privacy feature that replaces phone numbers in large groups. Key points:
|
|
455
|
+
|
|
456
|
+
- **Unique per user** (not per group)
|
|
457
|
+
- Ensures user anonymity in large groups
|
|
458
|
+
- Allows messaging users via either LID or PN (Phone Number)
|
|
459
|
+
- Part of WhatsApp's transition to username system (@username)
|
|
460
|
+
|
|
461
|
+
#### JID Format Changes
|
|
462
|
+
|
|
463
|
+
- **PN (Phone Number)**: `1234567890@s.whatsapp.net` (traditional format)
|
|
464
|
+
- **LID**: `123456@lid` (new format)
|
|
465
|
+
|
|
466
|
+
### Accessing the Store
|
|
467
|
+
|
|
468
|
+
The store is automatically initialized when you create a WhatsAppClient and is accessible via the internal socket:
|
|
469
|
+
|
|
470
|
+
```javascript
|
|
471
|
+
const client = new WhatsAppClient({ sessionName: ".Sessions" });
|
|
472
|
+
await client.connect();
|
|
473
|
+
|
|
474
|
+
// Store is available internally as client.store
|
|
475
|
+
// Access via: client.sock.signalRepository.lidMapping
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### Available Methods
|
|
479
|
+
|
|
480
|
+
The WhatsAppClient provides convenient methods to work with LID/PN mappings:
|
|
481
|
+
|
|
482
|
+
#### Quick Reference
|
|
483
|
+
|
|
484
|
+
```javascript
|
|
485
|
+
// Get LID from Phone Number
|
|
486
|
+
const lid = await client.getLIDForPN('1234567890@s.whatsapp.net');
|
|
487
|
+
|
|
488
|
+
// Get Phone Number from LID
|
|
489
|
+
const pn = await client.getPNForLID('123456@lid');
|
|
490
|
+
|
|
491
|
+
// Get multiple LIDs
|
|
492
|
+
const lids = await client.getLIDsForPNs(['phone1@s.whatsapp.net', 'phone2@s.whatsapp.net']);
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
#### Detailed Examples
|
|
496
|
+
|
|
497
|
+
```javascript
|
|
498
|
+
// Get LID from Phone Number
|
|
499
|
+
const lid = await client.getLIDForPN('1234567890@s.whatsapp.net');
|
|
500
|
+
console.log('LID:', lid);
|
|
501
|
+
|
|
502
|
+
// Get Phone Number from LID
|
|
503
|
+
const pn = await client.getPNForLID('123456@lid');
|
|
504
|
+
console.log('Phone Number:', pn);
|
|
505
|
+
|
|
506
|
+
// Get multiple LIDs from multiple PNs
|
|
507
|
+
const lids = await client.getLIDsForPNs([
|
|
508
|
+
'1234567890@s.whatsapp.net',
|
|
509
|
+
'0987654321@s.whatsapp.net'
|
|
510
|
+
]);
|
|
511
|
+
console.log('LIDs:', lids);
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Message Handling with LID Support
|
|
515
|
+
|
|
516
|
+
The library automatically handles both LID and PN formats in messages:
|
|
517
|
+
|
|
518
|
+
```javascript
|
|
519
|
+
client.on('message', async msg => {
|
|
520
|
+
// msg.from will prefer PN over LID when available
|
|
521
|
+
console.log('Message from:', msg.from);
|
|
522
|
+
|
|
523
|
+
// Access raw message key for both formats
|
|
524
|
+
const remoteJid = msg.raw.key.remoteJid; // Primary JID
|
|
525
|
+
const remoteJidAlt = msg.raw.key.remoteJidAlt; // Alternate JID
|
|
526
|
+
|
|
527
|
+
// For group messages
|
|
528
|
+
const participant = msg.raw.key.participant; // Could be LID or PN
|
|
529
|
+
const participantAlt = msg.raw.key.participantAlt; // Alternate format
|
|
530
|
+
|
|
531
|
+
// Convert LID to PN if needed
|
|
532
|
+
if (remoteJid.endsWith('@lid')) {
|
|
533
|
+
const phoneNumber = await client.getPNForLID(remoteJid);
|
|
534
|
+
console.log('Phone number:', phoneNumber);
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### Best Practices
|
|
540
|
+
|
|
541
|
+
#### 1. Prefer PN over LID for Compatibility
|
|
542
|
+
|
|
543
|
+
```javascript
|
|
544
|
+
const getPreferredJid = (messageKey) => {
|
|
545
|
+
if (messageKey.remoteJidAlt?.endsWith('@s.whatsapp.net')) {
|
|
546
|
+
return messageKey.remoteJidAlt; // Use PN
|
|
547
|
+
}
|
|
548
|
+
return messageKey.remoteJid; // Fallback to primary JID
|
|
549
|
+
};
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
#### 2. Convert LID to PN When Needed
|
|
553
|
+
|
|
554
|
+
```javascript
|
|
555
|
+
const convertToPN = async (jid) => {
|
|
556
|
+
if (jid.endsWith('@lid')) {
|
|
557
|
+
const pn = await client.getPNForLID(jid);
|
|
558
|
+
return pn || jid; // Return PN if found, otherwise return LID
|
|
559
|
+
}
|
|
560
|
+
return jid;
|
|
561
|
+
};
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
#### 3. Handle Both Formats Gracefully
|
|
565
|
+
|
|
566
|
+
```javascript
|
|
567
|
+
// Always handle undefined returns
|
|
568
|
+
const lid = await client.getLIDForPN(phoneNumber);
|
|
569
|
+
if (lid) {
|
|
570
|
+
console.log('LID found:', lid);
|
|
571
|
+
} else {
|
|
572
|
+
console.log('No LID mapping available, using PN');
|
|
573
|
+
}
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### Common Use Cases
|
|
577
|
+
|
|
578
|
+
#### Getting User's LID
|
|
579
|
+
|
|
580
|
+
```javascript
|
|
581
|
+
client.on('message', async msg => {
|
|
582
|
+
if (msg.body === '!myid') {
|
|
583
|
+
const lid = await client.getLIDForPN(msg.from);
|
|
584
|
+
if (lid) {
|
|
585
|
+
await msg.reply(`Your LID: ${lid}\nYour PN: ${msg.from}`);
|
|
586
|
+
} else {
|
|
587
|
+
await msg.reply('No LID found. You may be using a PN-only session.');
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
#### Resolving LID to Phone Number
|
|
594
|
+
|
|
595
|
+
```javascript
|
|
596
|
+
client.on('message', async msg => {
|
|
597
|
+
if (msg.body.startsWith('!lookup ')) {
|
|
598
|
+
const lid = msg.body.split(' ')[1];
|
|
599
|
+
const phoneNumber = await client.getPNForLID(lid);
|
|
600
|
+
|
|
601
|
+
if (phoneNumber) {
|
|
602
|
+
await msg.reply(`Phone number: ${phoneNumber}`);
|
|
603
|
+
} else {
|
|
604
|
+
await msg.reply('No phone number found for that LID.');
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
#### Handling Group Messages with LIDs
|
|
611
|
+
|
|
612
|
+
```javascript
|
|
613
|
+
client.on('message', async msg => {
|
|
614
|
+
if (msg.isGroup) {
|
|
615
|
+
const participant = msg.raw.key.participant;
|
|
616
|
+
const participantAlt = msg.raw.key.participantAlt;
|
|
617
|
+
|
|
618
|
+
// Use alternate (PN) if available, otherwise use primary
|
|
619
|
+
const senderJid = participantAlt || participant;
|
|
620
|
+
|
|
621
|
+
console.log('Group message from:', senderJid);
|
|
622
|
+
|
|
623
|
+
// Get LID if sender is using PN
|
|
624
|
+
if (senderJid.endsWith('@s.whatsapp.net')) {
|
|
625
|
+
const lid = await client.getLIDForPN(senderJid);
|
|
626
|
+
console.log('Sender LID:', lid);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### Helper Functions
|
|
633
|
+
|
|
634
|
+
```javascript
|
|
635
|
+
// Check if JID is a Phone Number
|
|
636
|
+
const isPnUser = (jid) => {
|
|
637
|
+
return jid?.endsWith('@s.whatsapp.net');
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
// Check if JID is a LID
|
|
641
|
+
const isLidUser = (jid) => {
|
|
642
|
+
return jid?.endsWith('@lid');
|
|
643
|
+
};
|
|
644
|
+
|
|
645
|
+
// Get preferred JID format
|
|
646
|
+
const getPreferredFormat = async (jid, client) => {
|
|
647
|
+
if (isLidUser(jid)) {
|
|
648
|
+
const pn = await client.getPNForLID(jid);
|
|
649
|
+
return pn || jid;
|
|
650
|
+
}
|
|
651
|
+
return jid;
|
|
652
|
+
};
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
### Authentication State Requirements
|
|
656
|
+
|
|
657
|
+
⚠️ **Important**: Your authentication state must support these keys:
|
|
658
|
+
- `lid-mapping` - Stores LID/PN mappings
|
|
659
|
+
- `device-list` - Manages linked devices
|
|
660
|
+
- `tctoken` - Token for communications
|
|
661
|
+
|
|
662
|
+
The library handles this automatically with `useMultiFileAuthState`.
|
|
663
|
+
|
|
664
|
+
### Migration from v6.x to v7.x
|
|
665
|
+
|
|
666
|
+
If you're upgrading from Baileys v6.x:
|
|
667
|
+
|
|
668
|
+
1. **Store access changed**: Access via `sock.signalRepository.lidMapping` instead of separate store parameter
|
|
669
|
+
2. **New message key fields**: Check for `remoteJidAlt` and `participantAlt`
|
|
670
|
+
3. **Event listener**: Add handler for `lid-mapping-update` event
|
|
671
|
+
4. **Function naming**: `isJidUser()` replaced with `isPnUser()`
|
|
672
|
+
5. **Automatic handling**: The WhatsAppClient already implements these changes
|
|
673
|
+
|
|
674
|
+
### Troubleshooting
|
|
675
|
+
|
|
676
|
+
#### Store is undefined
|
|
677
|
+
|
|
678
|
+
**Problem**: Cannot access LID store methods
|
|
679
|
+
|
|
680
|
+
**Solution**: Ensure client is connected before accessing store:
|
|
681
|
+
```javascript
|
|
682
|
+
await client.connect();
|
|
683
|
+
// Wait for 'connected' event
|
|
684
|
+
client.on('connected', async () => {
|
|
685
|
+
// Now store methods are available
|
|
686
|
+
const lid = await client.getLIDForPN(phoneNumber);
|
|
687
|
+
});
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
#### No LID found for PN
|
|
691
|
+
|
|
692
|
+
**Problem**: `getLIDForPN()` returns `undefined`
|
|
693
|
+
|
|
694
|
+
**Possible causes**:
|
|
695
|
+
- User hasn't migrated to LID system yet
|
|
696
|
+
- No LID/PN mapping received from WhatsApp server
|
|
697
|
+
- Using old session that doesn't support LIDs
|
|
698
|
+
|
|
699
|
+
**Solution**: Always handle `undefined` returns gracefully
|
|
700
|
+
|
|
701
|
+
### Additional Resources
|
|
702
|
+
|
|
703
|
+
For more detailed information about the LID system implementation, see:
|
|
704
|
+
- [LID_STORE_GUIDE.md](./LID_STORE_GUIDE.md) - Complete implementation guide
|
|
705
|
+
- [Baileys Migration Guide](https://baileys.wiki/docs/migration/to-v7.0.0/) - Official migration documentation
|
|
706
|
+
- [example.js](./example.js) - Working examples with LID handling
|
|
707
|
+
|
|
708
|
+
## Contributing
|
|
709
|
+
|
|
710
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
711
|
+
|
|
712
|
+
## License
|
|
713
|
+
|
|
714
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
715
|
+
|
|
716
|
+
## Credits
|
|
717
|
+
|
|
718
|
+
Developed by [Innovators Soft](https://facebook.com/innovatorssoft). Based on the [@itsukichan/baileys](https://github.com/itsukichann/baileys) library.
|
package/example.jpg
ADDED
|
Binary file
|