@areumtecnologia/baileys 1.0.0 → 1.0.1

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 ADDED
File without changes
@@ -0,0 +1,27 @@
1
+ const wb = require('@whiskeysockets/baileys');
2
+ const {
3
+ Browsers,
4
+ makeWASocket,
5
+ decryptPollVote,
6
+ DisconnectReason,
7
+ jidNormalizedUser,
8
+ downloadContentFromMessage,
9
+ downloadMediaMessage,
10
+ getContentType,
11
+ useMultiFileAuthState,
12
+ fetchLatestBaileysVersion,
13
+ } = require('@itsukichan/baileys');
14
+
15
+ module.exports = {
16
+ whiskeysocketsMakeWASocket: wb.makeWASocket,
17
+ itsukichanMakeWASocket: makeWASocket,
18
+ Browsers,
19
+ decryptPollVote,
20
+ DisconnectReason,
21
+ jidNormalizedUser,
22
+ downloadContentFromMessage,
23
+ downloadMediaMessage,
24
+ getContentType,
25
+ useMultiFileAuthState,
26
+ fetchLatestBaileysVersion,
27
+ };
@@ -0,0 +1,58 @@
1
+
2
+ /**
3
+ * @copyright Áreum Tecnologia
4
+ * @author Áreum Tecnologia
5
+ * @license Proprietary
6
+ *
7
+ * Manipula o envio e recebimento de chamadas via WhatsApp utilizando Baileys.
8
+ * Fornece métodos para envio de texto, mídia, localização, contatos, enquetes, ações de mensagem e interatividade.
9
+ *
10
+ * @class CallHandler
11
+ * @classdesc Classe central para manipulação de chamadas no WhatsApp.
12
+ *
13
+ * @property {import('../client').default} client - Instância principal do cliente Baileys.
14
+ *
15
+ * @example
16
+ * const CallHandler = require('./handlers/calls');
17
+ * const handler = new CallHandler(client);
18
+ * await handler.callReject('5511999999999@s.whatsapp.net');
19
+ */
20
+ // const { sendButtons, sendInteractiveMessage } = require('baileys_helper');
21
+ const { Utils, MessageNormalizer } = require('../utils');
22
+
23
+ class CallHandler {
24
+ /**
25
+ * @param {import('../../../client').default} client - A instância principal do cliente.
26
+ */
27
+ constructor(client) {
28
+ this.client = client;
29
+ }
30
+
31
+ /**
32
+ * Rejeita uma chamada.
33
+ * @param {string} jid - O JID do destinatário.
34
+ */
35
+ async reject(call) {
36
+ this.client._validateConnection();
37
+ return this.client.sock.rejectCall(call.id, call.from);
38
+
39
+ }
40
+
41
+ normalizeCall(call) {
42
+ return {
43
+ id: call.id,
44
+ from: call.from,
45
+ status: call.status,
46
+ isVideo: call.isVideo,
47
+ isGroup: call.isGroup,
48
+ groupJid: call.groupJid,
49
+ date: call.date,
50
+ offline: call.offline,
51
+ chatId: call.chatId,
52
+ reject: this.reject.bind(this, call)
53
+ };
54
+ }
55
+
56
+ }
57
+
58
+ module.exports = CallHandler;
@@ -245,6 +245,7 @@ class MessageHandler {
245
245
  return this.client.sock.readMessages([messageKey]);
246
246
  }
247
247
 
248
+ /** Funcional apenas usando baileys e baileys_helper - Envia uma mensagem com botões interativos. */
248
249
  async sendInteractiveMessage(jid, interactiveMessage, more) {
249
250
  const verifiedJid = await this.client.users.isOnWhatsApp(jid);
250
251
  if (verifiedJid && verifiedJid.exists) {
@@ -255,7 +256,7 @@ class MessageHandler {
255
256
  }
256
257
  }
257
258
 
258
- /** Envia uma mensagem com botões interativos. */
259
+ /** Funcional apenas usando baileys e baileys_helper - Envia uma mensagem com botões interativos. */
259
260
  async sendButtons(jid, messageButton) {
260
261
  const verifiedJid = await this.client.users.isOnWhatsApp(jid);
261
262
  if (verifiedJid && verifiedJid.exists) {
@@ -267,18 +268,30 @@ class MessageHandler {
267
268
  }
268
269
 
269
270
  /** Faz o download de mídia de uma mensagem. */
270
- async download(message) {
271
+ async getAttachments(message) {
271
272
  this.client._validateConnection();
272
273
  const type = Object.keys(message.message)[0];
273
274
  const messageContent = message.message[type];
274
- if (!messageContent.url) throw new Error('Mensagem não contém mídia para download.');
275
+ if (!messageContent.url)
276
+ return null;
275
277
 
276
278
  const stream = await this.client.downloadContentFromMessage(messageContent, type.replace('Message', ''));
277
279
  let buffer = Buffer.from([]);
278
280
  for await (const chunk of stream) {
279
281
  buffer = Buffer.concat([buffer, chunk]);
280
282
  }
281
- return buffer;
283
+ return {
284
+ type: messageContent.mimetype,
285
+ buffer,
286
+ save: async (path) => {
287
+ const mime = message.message.imageMessage.mimetype;
288
+ const extension = mime.split('/')[1];
289
+ const filename = `${message.from}-${Date.now()}.${extension}`;
290
+ const filepath = path ? path : this.client.sessionPath + '/media/' + filename;
291
+ await fs.writeFile(filepath, buffer);
292
+ return { filename, filepath };
293
+ }
294
+ };
282
295
  }
283
296
  }
284
297
 
package/index.js CHANGED
@@ -1,24 +1,30 @@
1
- // Biblioteca chamada synapse-b
2
- const wb = require('@whiskeysockets/baileys');
1
+ // Biblioteca chamada @areumtecnologia/baileys
2
+
3
3
  const {
4
4
  Browsers,
5
- makeWASocket,
5
+ itsukichanMakeWASocket,
6
+ whiskeysocketsMakeWASocket,
6
7
  decryptPollVote,
7
8
  DisconnectReason,
8
9
  jidNormalizedUser,
9
10
  downloadContentFromMessage,
11
+ downloadMediaMessage,
12
+ getContentType,
10
13
  useMultiFileAuthState,
11
14
  fetchLatestBaileysVersion,
12
- } = require('@itsukichan/baileys');
15
+ } = require('./handlers/baileys');
13
16
  const { Boom } = require('@hapi/boom');
14
17
  const EventEmitter = require('events');
15
18
  const fs = require('fs/promises');
16
19
  const { constants } = require('fs');
17
20
  const path = require('path');
18
21
  const pino = require('pino');
22
+ const QRCode = require('qrcode');
23
+ const qrcodeTerminal = require('qrcode-terminal');
19
24
  // Importa os handlers de responsabilidades específicas
20
25
  const MessageHandler = require('./handlers/messages');
21
26
  const GroupHandler = require('./handlers/groups');
27
+ const CallHandler = require('./handlers/calls');
22
28
  const { UserHandler, PresenceStatus } = require('./handlers/users');
23
29
  const { MessageNormalizer, MessageStore } = require('./utils');
24
30
  const { InteractiveMessage, CallButton, CopyCodeButton, ListButton, ListRow, ListSection, QuickReplyButton, UrlButton, LocationButton } = require('./types/interactive-messages');
@@ -56,10 +62,10 @@ class Client extends EventEmitter {
56
62
  constructor(options = {}) {
57
63
  super();
58
64
  this.sock = null;
59
- this.dataPath = options.dataPath || ".synapse-b/auth_data";
65
+ this.dataPath = options.dataPath || ".baileys/sessions";
60
66
  this.sessionName = options.sessionName;
61
- this.authPath = [this.dataPath, this.sessionName].join('/');
62
- this.store = options.store ? options.store : new MessageStore(this.authPath);
67
+ this.sessionPath = [this.dataPath, this.sessionName].join('/');
68
+ this.store = options.store ? options.store : new MessageStore(this.sessionPath);
63
69
  this.isOnline = false;
64
70
  this.connected = false;
65
71
  this.manualDisconnect = false;
@@ -69,6 +75,7 @@ class Client extends EventEmitter {
69
75
  this.status = ClientEvent.DISCONNECTED;
70
76
  this.markOnlineOnConnect = options.markOnlineOnConnect || false;
71
77
  this.enviroment = options.enviroment ? options.enviroment : null;
78
+ this.printQRInTerminal = options.printQRInTerminal || false;
72
79
  this.qrCode = null;
73
80
  // =================================================================================================
74
81
  // INTEGRAÇÃO DOS HANDLERS
@@ -78,6 +85,7 @@ class Client extends EventEmitter {
78
85
  this.messages = new MessageHandler(this);
79
86
  this.groups = new GroupHandler(this);
80
87
  this.users = new UserHandler(this);
88
+ this.calls = new CallHandler(this);
81
89
  }
82
90
 
83
91
  /**
@@ -87,17 +95,16 @@ class Client extends EventEmitter {
87
95
  */
88
96
  async connect() {
89
97
  this.status = ClientEvent.INIT;
90
- const { state, saveCreds } = await useMultiFileAuthState(this.authPath);
98
+ const { state, saveCreds } = await useMultiFileAuthState(this.sessionPath);
91
99
  const { version } = await fetchLatestBaileysVersion();
92
- const credsPath = path.resolve(process.cwd(), this.authPath, "creds.json");
100
+ const credsPath = path.resolve(process.cwd(), this.sessionPath, "creds.json");
93
101
  const creds = await this.fileExists(credsPath);
94
102
  if (creds) {
95
103
  // Conecta usando @itsukichan/baileys
96
- this.sock = makeWASocket({
104
+ this.sock = itsukichanMakeWASocket({
97
105
  auth: state,
98
106
  version,
99
107
  browser: this.enviroment ? this.enviroment : Browsers.macOS("Desktop"),
100
- printQRInTerminal: false, // Desabilitamos para controlar via evento
101
108
  logger: pino({ level: this.loggerLevel }),
102
109
  markOnlineOnConnect: this.markOnlineOnConnect || false,
103
110
  keepAliveIntervalMs: 15000,
@@ -111,11 +118,10 @@ class Client extends EventEmitter {
111
118
  });
112
119
  } else {
113
120
  // Conecta usando Baileys
114
- this.sock = wb.makeWASocket({
121
+ this.sock = whiskeysocketsMakeWASocket({
115
122
  auth: state,
116
123
  version,
117
124
  browser: this.enviroment ? this.enviroment : Browsers.macOS("Desktop"),
118
- printQRInTerminal: false, // Desabilitamos para controlar via evento
119
125
  logger: pino({ level: this.loggerLevel }),
120
126
  markOnlineOnConnect: this.markOnlineOnConnect || false,
121
127
  cachedGroupMetadata: async (jid) => groupCache.get(jid),
@@ -153,9 +159,13 @@ class Client extends EventEmitter {
153
159
 
154
160
  if (qr) {
155
161
  this.qrCode = qr;
162
+ const base64 = await QRCode.toDataURL(qr);
163
+ this.qrCodeAttempts = (this.qrCodeAttempts || 0) + 1;
164
+ this.qrCode = { base64, qr, attempts: this.qrCodeAttempts };
156
165
  this.status = ClientEvent.PAIRING_CODE;
157
- this.emit(ClientEvent.PAIRING_CODE, update);
166
+ this.emit(ClientEvent.PAIRING_CODE, this.qrCode);
158
167
  this.emit(ClientEvent.STATUS_CHANGE, this.status);
168
+ this.printQRInTerminal ? qrcodeTerminal.generate(qr, { small: true }) : null;
159
169
  return;
160
170
  }
161
171
 
@@ -177,10 +187,12 @@ class Client extends EventEmitter {
177
187
  break;
178
188
 
179
189
  case 'open':
190
+ this.user = this.sock.user;
191
+ this.qrCode = null; // Limpa o QR code após a conexão
180
192
  this.connected = true;
181
193
  this.manualDisconnect = false;
182
194
  this.status = ClientEvent.CONNECTED;
183
- this.emit(ClientEvent.CONNECTED, update);
195
+ this.emit(ClientEvent.CONNECTED, this.user);
184
196
  this.emit(ClientEvent.STATUS_CHANGE, this.status);
185
197
  this.presenceSetInterval = setInterval(() => {
186
198
  if (this.sock?.sendPresenceUpdate) {
@@ -217,7 +229,7 @@ class Client extends EventEmitter {
217
229
  statusType = DisconnectReasons.LOGGED_OUT;
218
230
  disconnectReason = { statusCode, statusType, reason: reasonType, details: boomError.data };
219
231
  try {
220
- await fs.rm(this.authPath, { recursive: true, force: true });
232
+ await fs.rm(this.sessionPath, { recursive: true, force: true });
221
233
  // if (this.restartOnClose) this.connect();
222
234
  } catch (err) {
223
235
  this.emit(ClientEvent.ERROR, err);
@@ -256,7 +268,9 @@ class Client extends EventEmitter {
256
268
  // OUTROS EVENTOS DE INTERAÇÃO
257
269
  // =================================================================================================
258
270
 
259
- this.sock.ev.on('call', (calls) => this.emit(ClientEvent.CALL, calls[0]));
271
+ this.sock.ev.on('call', ([call]) => {
272
+ this.emit(ClientEvent.CALL, this.calls.normalizeCall(call));
273
+ });
260
274
  this.sock.ev.on('groups.update', async ([event]) => {
261
275
  this.emit(ClientEvent.GROUP_UPDATE, event);
262
276
  const metadata = await this.sock.groupMetadata(event.id);
@@ -268,8 +282,7 @@ class Client extends EventEmitter {
268
282
  const metadata = await this.sock.groupMetadata(event.id)
269
283
  groupCache.set(event.id, metadata)
270
284
  });
271
- // this.sock.ev.on('groups.update', (updates) => this.emit(ClientEvent.GROUP_UPDATE, updates));
272
- // this.sock.ev.on('group-participants.update', (update) => this.emit(ClientEvent.GROUP_PARTICIPANTS_UPDATE, update));
285
+
273
286
  this.sock.ev.on('presence.update', (update) => this.emit(ClientEvent.PRESENCE_UPDATE, update));
274
287
  this.sock.ev.on('contacts.update', (updates) => this.emit(ClientEvent.CONTACT_UPDATE, updates));
275
288
  this.sock.ev.on('blocklist.update', (update) => this.emit(ClientEvent.BLOCKLIST_UPDATE, update));
@@ -284,7 +297,7 @@ class Client extends EventEmitter {
284
297
  const messages = history.messages.filter(m => m.key.remoteJid === chatId);
285
298
  for (const msg of messages) {
286
299
  const nmsg = MessageNormalizer.normalize(msg, this);
287
- if (nmsg && this.store && this.store.setMessage) this.store.setMessage(chatId, nmsg);
300
+ if (nmsg && this.store && this.store?.setMessage) this.store?.setMessage(chatId, nmsg);
288
301
  }
289
302
  }
290
303
  this.emit(ClientEvent.MESSAGES_HISTORY_SYNC_DONE, history);
@@ -308,7 +321,9 @@ class Client extends EventEmitter {
308
321
  this.emit(ClientEvent.BROADCAST_MESSAGE, msg);
309
322
  } else {
310
323
  const nmsg = await MessageNormalizer.normalize(msg, this);
311
- this.store.setMessage(nmsg.chatId, nmsg);
324
+ if (nmsg && this.store && this.store?.setMessage) {
325
+ this.store?.setMessage(nmsg.chatId, nmsg);
326
+ }
312
327
  // Mensagens de conversacao
313
328
  switch (type) {
314
329
  case 'append':
@@ -373,18 +388,26 @@ class Client extends EventEmitter {
373
388
  }
374
389
  }
375
390
 
391
+ // Metodos usados pelos handlers
376
392
  async decryptPollVote(vote, voteParams) {
377
393
  return await decryptPollVote(vote, voteParams);
378
394
  }
379
395
 
396
+ // Metodos usados pelos handlers
380
397
  jidNormalizedUser(id) {
381
398
  return jidNormalizedUser(id);
382
399
  }
383
400
 
401
+ // Metodos usados pelos handlers
384
402
  async downloadContentFromMessage(content, type) {
385
403
  return await downloadContentFromMessage(content, type);
386
404
  }
387
405
 
406
+ // Metodos usados pelos handlers
407
+ async getContentType(message) {
408
+ return getContentType(message);
409
+ }
410
+
388
411
  async fileExists(path) {
389
412
  try {
390
413
  await fs.access(path, constants.F_OK);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@areumtecnologia/baileys",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "More baileys fork",
5
5
  "license": "ISC",
6
6
  "author": "Áreum Tecnologia",
@@ -11,6 +11,10 @@
11
11
  },
12
12
  "dependencies": {
13
13
  "@itsukichan/baileys": "^7.3.2",
14
- "baileys": "^7.0.0-rc.9"
14
+ "@whiskeysockets/baileys": "^7.0.0-rc.9",
15
+ "crypto-digest-sync": "^1.0.0",
16
+ "node-cache": "^5.1.2",
17
+ "qrcode": "^1.5.4",
18
+ "qrcode-terminal": "^0.12.0"
15
19
  }
16
- }
20
+ }
@@ -1,5 +1,4 @@
1
1
  const digestSync = require('crypto-digest-sync');
2
-
3
2
  /**
4
3
  * Classe utilitária estática para normalizar o objeto de mensagem do Baileys
5
4
  * em uma estrutura rica, consistente e completa. (Versão 3 - Final)
@@ -35,17 +34,19 @@ class MessageNormalizer {
35
34
  const chatId = rawMessage.key.remoteJid.includes('@lid') ? rawMessage.key.remoteJidAlt : rawMessage.key.remoteJid;
36
35
  const isGroup = chatId.endsWith('@g.us');
37
36
  const clientJid = client.jidNormalizedUser(client.sock.user.id);
38
-
37
+ const from = isGroup ? rawMessage.key.participant : rawMessage.key.fromMe ? clientJid : chatId;
38
+ const to = isGroup ? rawMessage.key.participant : rawMessage.key.fromMe ? chatId : clientJid;
39
39
  const normalized = {
40
40
  id: rawMessage.key.id,
41
- from: isGroup ? rawMessage.key.participant : rawMessage.key.fromMe ? clientJid : chatId,
42
- to: isGroup ? rawMessage.key.participant : rawMessage.key.fromMe ? chatId : clientJid,
41
+ from: from,
42
+ to: to,
43
43
  chatId: chatId,
44
44
  timestamp: new Date(Number(rawMessage.messageTimestamp) * 1000),
45
45
  fromMe: rawMessage.key.fromMe,
46
46
  isGroup: isGroup,
47
47
  sender: {
48
- id: isGroup ? rawMessage.key.participant : rawMessage.key.fromMe ? clientJid : chatId,
48
+ id: from,
49
+ lid: rawMessage.key.remoteJid.includes('@lid') ? rawMessage.key.remoteJid : null,
49
50
  pushName: rawMessage.pushName || ''
50
51
  },
51
52
  type,
@@ -65,6 +66,9 @@ class MessageNormalizer {
65
66
  reaction: this._extractReaction(rawMessage.message),
66
67
  pollUpdate: await this._extractPollUpdate(rawMessage, client),
67
68
  poll: this._extractPollCreation(rawMessage),
69
+ getAttachments: async () => {
70
+ return await client.messages.getAttachments(rawMessage);
71
+ },
68
72
  raw: rawMessage // Referência ao objeto original para acesso avançado
69
73
  };
70
74
 
@@ -1,8 +0,0 @@
1
- {
2
- "folders": [
3
- {
4
- "path": "."
5
- }
6
- ],
7
- "settings": {}
8
- }
package/desktop.ini DELETED
Binary file
Binary file
package/tests/app.js DELETED
@@ -1,68 +0,0 @@
1
- const { Client, ClientEvent } = require('../index'); // Caminho para sua classe Client
2
- // 1. Instanciação do Cliente atualizada para usar a nova classe
3
- const client = new Client({
4
- sessionName: sessionId,
5
- restartOnClose: true,
6
- markOnlineOnConnect: false,
7
- enviroment: [account.name || 'MacOS', 'Chrome', '118.0.0.0'],
8
- store: {
9
- // getMessage: async (chatId, mid) => {
10
- // const msg = (await messages.select([{ chat_id: chatId }, AND, { mid }]))[0];
11
- // return msg;
12
- // },
13
- // setMessage: async (chatId, msg) => {
14
- // // Nao implementa pois ja registra as mensagens nos eventos message_received e message_sent
15
- // }
16
- }
17
- });
18
-
19
- client.on(ClientEvent.STATUS_CHANGE, async (status) => {
20
- console.log(new Date().toLocaleDateString('pt-br'), `[${sessionId}] Status alterado para: ${status}`);
21
- });
22
-
23
- client.on(ClientEvent.PAIRING_CODE, async ({ qr }) => {
24
- console.log(new Date().toLocaleDateString('pt-br'), `[${sessionId}] QR Code recebido. Enviando via webhook...`);
25
- const base64 = await QRCode.toDataURL(qr);
26
- client.qrCodeAttempts = (client.qrCodeAttempts || 0) + 1;
27
- client.qrCode = { base64, url: qr, attempts: client.qrCodeAttempts, status: 'waiting' };
28
- });
29
-
30
- client.on(ClientEvent.PAIRING_SUCCESS, async (event) => {
31
- console.log(new Date().toLocaleDateString('pt-br'), `[${sessionId}] QR Code lido com sucesso. Enviando via webhook...`);
32
- });
33
-
34
- client.on(ClientEvent.CONNECTED, async () => {
35
- console.log(new Date().toLocaleDateString('pt-br'), `[${sessionId}] Conectado com sucesso.`);
36
- client.qrCode = null; // Limpa o QR code após a conexão
37
-
38
- // Envia mensagem de boas-vindas usando o novo handler
39
- const user = client.sock.user;
40
- const welcomeMessage = `🤖 Olá, ${user.name || 'usuário'}!\nSua sessão (${sessionId}) foi conectada com sucesso.`;
41
- await client.messages.sendTextMessage(user.id, welcomeMessage);
42
-
43
- });
44
-
45
- client.on(ClientEvent.DISCONNECTED, async (reason) => {
46
- console.log(new Date().toLocaleDateString('pt-br'), `[${sessionId}] Desconectado. Motivo: ${reason.statusType}`, reason.details || '');
47
- });
48
-
49
- client.on(ClientEvent.MESSAGE_RECEIVED, async (msg) => {
50
- console.log(new Date().toLocaleDateString('pt-br'), `[${sessionId}] Mensagem recebida de ${msg.from}`);
51
- });
52
-
53
- client.on(ClientEvent.MESSAGE_SENT, async (msg) => {
54
- console.log(new Date().toLocaleDateString('pt-br'), `[${sessionId}] Mensagem enviada para ${msg.to}`);
55
- });
56
-
57
- client.on(ClientEvent.CALL, async (call) => {
58
- console.log(new Date().toLocaleDateString('pt-br'), `[${sessionId}] Chamada recebida de ${call.from}`);
59
-
60
- });
61
-
62
- client.on(ClientEvent.ERROR, (error) => {
63
- console.error(new Date().toLocaleDateString('pt-br'), `[${sessionId}] Ocorreu um erro na instância do cliente:`, error, error?.lastDisconnect?.output);
64
- });
65
-
66
-
67
- // Inicia a conexão
68
- await client.connect();
package/tests/desktop.ini DELETED
Binary file
package/types/desktop.ini DELETED
Binary file
package/utils/desktop.ini DELETED
Binary file