@roidev/kachina-md 2.0.4 → 2.1.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.
Files changed (2) hide show
  1. package/lib/client/Client.js +109 -13
  2. package/package.json +8 -3
@@ -2,7 +2,8 @@ import makeWASocket, {
2
2
  DisconnectReason,
3
3
  useMultiFileAuthState,
4
4
  makeCacheableSignalKeyStore,
5
- fetchLatestBaileysVersion
5
+ fetchLatestBaileysVersion,
6
+ downloadMediaMessage
6
7
  } from 'baileys';
7
8
  import { Boom } from '@hapi/boom';
8
9
  import pino from 'pino';
@@ -12,10 +13,6 @@ import { serialize } from '../helpers/serialize.js';
12
13
  import { PluginHandler } from '../handlers/PluginHandler.js';
13
14
  import {
14
15
  createSticker,
15
- createFullSticker,
16
- createCroppedSticker,
17
- createCircleSticker,
18
- createRoundedSticker,
19
16
  StickerTypes
20
17
  } from '../helpers/sticker.js';
21
18
 
@@ -68,6 +65,43 @@ export class Client extends EventEmitter {
68
65
 
69
66
  this.sock.ev.on('creds.update', saveCreds);
70
67
 
68
+ // Handle pairing code request (must be before connection)
69
+ if (this.config.loginMethod === 'pairing' && !state.creds.registered) {
70
+ if (!this.config.phoneNumber) {
71
+ throw new Error('Phone number is required for pairing method. Example: { phoneNumber: "628123456789" }');
72
+ }
73
+
74
+ // Format phone number (remove + and spaces)
75
+ const phoneNumber = this.config.phoneNumber.replace(/[^0-9]/g, '');
76
+
77
+ if (phoneNumber.length < 10) {
78
+ throw new Error('Invalid phone number format. Use country code without +. Example: 628123456789');
79
+ }
80
+
81
+ // Request pairing code after socket is initialized
82
+ setTimeout(async () => {
83
+ try {
84
+ const code = await this.sock.requestPairingCode(phoneNumber);
85
+ this.emit('pairing.code', code);
86
+
87
+ // Log to console with formatting
88
+ console.log('\n┌─────────────────────────────────────┐');
89
+ console.log('│ WhatsApp Pairing Code │');
90
+ console.log('├─────────────────────────────────────┤');
91
+ console.log(`│ Code: ${code} │`);
92
+ console.log('└─────────────────────────────────────┘');
93
+ console.log('\nSteps to pair:');
94
+ console.log('1. Open WhatsApp on your phone');
95
+ console.log('2. Go to Settings > Linked Devices');
96
+ console.log('3. Tap "Link a Device"');
97
+ console.log('4. Enter the code above\n');
98
+ } catch (error) {
99
+ this.emit('pairing.error', error);
100
+ console.error('Failed to request pairing code:', error.message);
101
+ }
102
+ }, 3000);
103
+ }
104
+
71
105
  this.sock.ev.on('connection.update', async (update) => {
72
106
  await this.handleConnectionUpdate(update);
73
107
  });
@@ -124,17 +158,15 @@ export class Client extends EventEmitter {
124
158
  this.user = this.sock.user;
125
159
  this.emit('ready', this.user);
126
160
 
127
- // Request pairing code if needed
128
- if (!this.sock.authState.creds.registered && this.config.loginMethod === 'pairing') {
129
- if (this.config.phoneNumber) {
130
- setTimeout(async () => {
131
- const code = await this.sock.requestPairingCode(this.config.phoneNumber);
132
- this.emit('pairing.code', code);
133
- }, 3000);
134
- }
161
+ // Log success message
162
+ if (this.config.loginMethod === 'pairing') {
163
+ console.log('\n✓ Successfully connected via pairing code!\n');
135
164
  }
136
165
  } else if (connection === 'connecting') {
137
166
  this.emit('connecting');
167
+ if (this.config.loginMethod === 'pairing') {
168
+ console.log('Waiting for pairing code confirmation...');
169
+ }
138
170
  }
139
171
  }
140
172
 
@@ -225,6 +257,70 @@ export class Client extends EventEmitter {
225
257
  });
226
258
  }
227
259
 
260
+ /**
261
+ * Read and download view once message
262
+ * @param {Object} quotedMessage - The quoted message object (m.quoted)
263
+ * @returns {Promise<{buffer: Buffer, type: 'image'|'video', caption: string}>}
264
+ */
265
+ async readViewOnce(quotedMessage) {
266
+ if (!quotedMessage) {
267
+ throw new Error('Quoted message is required');
268
+ }
269
+
270
+ // Get view once message
271
+ const ViewOnceImg = quotedMessage?.message?.imageMessage;
272
+ const ViewOnceVid = quotedMessage?.message?.videoMessage;
273
+
274
+ // Check if it's a view once message
275
+ if (!ViewOnceImg?.viewOnce && !ViewOnceVid?.viewOnce) {
276
+ throw new Error('Message is not a view once message');
277
+ }
278
+
279
+ // Download the media
280
+ const buffer = await downloadMediaMessage(
281
+ quotedMessage,
282
+ 'buffer',
283
+ {},
284
+ { logger: this.config.logger }
285
+ );
286
+
287
+ // Return buffer with type and caption
288
+ return {
289
+ buffer,
290
+ type: ViewOnceImg ? 'image' : 'video',
291
+ caption: ViewOnceImg?.caption || ViewOnceVid?.caption || ''
292
+ };
293
+ }
294
+
295
+ /**
296
+ * Read view once message and send to chat
297
+ * @param {string} jid - Chat ID to send to
298
+ * @param {Object} quotedMessage - The quoted message object (m.quoted)
299
+ * @param {Object} options - Additional options
300
+ * @returns {Promise}
301
+ */
302
+ async sendViewOnce(jid, quotedMessage, options = {}) {
303
+ try {
304
+ // Read the view once message
305
+ const { buffer, type, caption } = await this.readViewOnce(quotedMessage);
306
+
307
+ // Send based on type
308
+ if (type === 'image') {
309
+ return await this.sendImage(jid, buffer, caption, {
310
+ jpegThumbnail: null,
311
+ ...options
312
+ });
313
+ } else {
314
+ return await this.sendVideo(jid, buffer, caption, {
315
+ jpegThumbnail: null,
316
+ ...options
317
+ });
318
+ }
319
+ } catch (error) {
320
+ throw new Error(`Failed to send view once: ${error.message}`);
321
+ }
322
+ }
323
+
228
324
  async groupMetadata(jid) {
229
325
  return await this.sock.groupMetadata(jid);
230
326
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roidev/kachina-md",
3
- "version": "2.0.4",
3
+ "version": "2.1.0",
4
4
  "description": "WhatsApp Bot Framework - Simple, Fast, and Modular",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
@@ -8,7 +8,10 @@
8
8
  "build": "node build.js",
9
9
  "test": "node examples/basic-bot.js",
10
10
  "prepublishOnly": "npm run build",
11
- "release": "bash scripts/release.sh"
11
+ "release": "bash scripts/release.sh",
12
+ "docs:dev": "vitepress dev docs-site --host",
13
+ "docs:build": "vitepress build docs-site",
14
+ "docs:preview": "vitepress preview docs-site"
12
15
  },
13
16
  "keywords": [
14
17
  "whatsapp",
@@ -44,7 +47,9 @@
44
47
  "wa-sticker-formatter": "^4.4.4"
45
48
  },
46
49
  "devDependencies": {
47
- "gradient-string": "^2.0.2"
50
+ "gradient-string": "^2.0.2",
51
+ "vitepress": "^1.6.4",
52
+ "vue": "^3.5.24"
48
53
  },
49
54
  "engines": {
50
55
  "node": ">=16.0.0"