@vielhuber/wahelper 1.8.2 → 1.8.4

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/package.json +1 -1
  2. package/wahelper-daemon.js +113 -30
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vielhuber/wahelper",
3
- "version": "1.8.2",
3
+ "version": "1.8.4",
4
4
  "description": "Lightweight whatsapp integration layer.",
5
5
  "main": "wahelper.js",
6
6
  "files": [
@@ -4,7 +4,9 @@ import makeWASocket, {
4
4
  useMultiFileAuthState,
5
5
  DisconnectReason,
6
6
  downloadMediaMessage,
7
+ extractMessageContent,
7
8
  fetchLatestBaileysVersion,
9
+ normalizeMessageContent,
8
10
  Browsers
9
11
  } from 'baileys';
10
12
  import P from 'pino';
@@ -272,7 +274,7 @@ export default class wahelperDaemon {
272
274
  this.log('storeDataToDatabase');
273
275
 
274
276
  let messages = Array.isArray(data?.messages) ? data.messages : [];
275
- let chats = Array.isArray(data?.chats) ? data.chats : [];
277
+ let chats = Array.isArray(data) ? data : Array.isArray(data?.chats) ? data.chats : [];
276
278
  if (messages.length === 0 && chats.length === 0) {
277
279
  return;
278
280
  }
@@ -365,37 +367,116 @@ export default class wahelperDaemon {
365
367
  mediaData = null,
366
368
  mediaBufferInput = null;
367
369
 
368
- if (messages__value.message?.conversation) {
369
- content = messages__value.message.conversation;
370
- } else if (messages__value.message?.extendedTextMessage?.text) {
371
- content = messages__value.message.extendedTextMessage.text;
372
- } else if (messages__value.message?.imageMessage) {
373
- content = messages__value.message.imageMessage.caption || null;
370
+ // disappearing, view-once, edited and document-with-caption messages wrap
371
+ // the real payload one or more levels deep — unwrap once so every branch
372
+ // below sees the same shape
373
+ let payload = normalizeMessageContent(messages__value.message);
374
+ let mediaMessage = { key: messages__value.key, message: payload };
375
+
376
+ if (payload?.conversation) {
377
+ content = payload.conversation;
378
+ } else if (payload?.extendedTextMessage?.text) {
379
+ content = payload.extendedTextMessage.text;
380
+ } else if (payload?.imageMessage) {
381
+ content = payload.imageMessage.caption || null;
374
382
  mediaFilename = id + '.jpg';
375
- mediaBufferInput = messages__value;
376
- } else if (messages__value.message?.stickerMessage) {
377
- content = messages__value.message.stickerMessage.caption || null;
383
+ mediaBufferInput = mediaMessage;
384
+ } else if (payload?.stickerMessage) {
385
+ content = payload.stickerMessage.caption || null;
378
386
  mediaFilename = id + '.webp';
379
- mediaBufferInput = messages__value;
380
- } else if (messages__value.message?.videoMessage) {
381
- content = messages__value.message.videoMessage.caption || null;
387
+ mediaBufferInput = mediaMessage;
388
+ } else if (payload?.videoMessage) {
389
+ content = payload.videoMessage.caption || null;
382
390
  mediaFilename = id + '.mp4';
383
- mediaBufferInput = messages__value;
384
- } else if (messages__value.message?.documentMessage) {
385
- content = messages__value.message.documentMessage.caption || null;
386
- mediaFilename = messages__value.message.documentMessage.fileName || id + '.bin';
387
- mediaBufferInput = messages__value;
388
- } else if (messages__value.message?.documentWithCaptionMessage) {
389
- content =
390
- messages__value.message.documentWithCaptionMessage.message.documentMessage.caption || null;
391
- mediaFilename =
392
- messages__value.message.documentWithCaptionMessage.message.documentMessage.fileName ||
393
- id + '.bin';
394
- mediaBufferInput = messages__value.message.documentWithCaptionMessage;
395
- } else if (messages__value.message?.audioMessage) {
396
- content = messages__value.message.audioMessage.caption || null;
391
+ mediaBufferInput = mediaMessage;
392
+ } else if (payload?.ptvMessage) {
393
+ // a video note is a videoMessage under a different key, and baileys'
394
+ // media downloader has no path for "ptv" — hand it the video it is
395
+ content = payload.ptvMessage.caption || null;
396
+ mediaFilename = id + '.mp4';
397
+ mediaBufferInput = { key: messages__value.key, message: { videoMessage: payload.ptvMessage } };
398
+ } else if (payload?.documentMessage) {
399
+ content = payload.documentMessage.caption || null;
400
+ mediaFilename = payload.documentMessage.fileName || id + '.bin';
401
+ mediaBufferInput = mediaMessage;
402
+ } else if (payload?.audioMessage) {
403
+ content = payload.audioMessage.caption || null;
397
404
  mediaFilename = id + '.ogg';
398
- mediaBufferInput = messages__value;
405
+ mediaBufferInput = mediaMessage;
406
+ } else if (
407
+ payload?.pollCreationMessage ||
408
+ payload?.pollCreationMessageV2 ||
409
+ payload?.pollCreationMessageV3 ||
410
+ payload?.pollCreationMessageV4
411
+ ) {
412
+ // a poll is a turn of its own: without it a reader cannot tell that a
413
+ // question was already answered by putting it to a vote
414
+ let poll =
415
+ payload.pollCreationMessage ||
416
+ payload.pollCreationMessageV2 ||
417
+ payload.pollCreationMessageV3 ||
418
+ payload.pollCreationMessageV4;
419
+ content =
420
+ '[Poll] ' +
421
+ (poll.name || '') +
422
+ (poll.options || []).map(option => '\n- ' + (option.optionName || '')).join('');
423
+ } else if (payload?.pollUpdateMessage) {
424
+ // the vote itself is encrypted against the poll, but the fact that
425
+ // somebody voted is the part that says "this was answered"
426
+ content = '[Poll vote] on message ' + (payload.pollUpdateMessage.pollCreationMessageKey?.id || '');
427
+ } else if (payload?.reactionMessage?.text) {
428
+ // an emoji reaction counts as having replied; an empty text means the
429
+ // reaction was withdrawn and carries nothing worth storing
430
+ content =
431
+ '[Reaction] ' +
432
+ payload.reactionMessage.text +
433
+ ' to message ' +
434
+ (payload.reactionMessage.key?.id || '');
435
+ } else if (payload?.locationMessage) {
436
+ content =
437
+ '[Location] ' +
438
+ [
439
+ payload.locationMessage.name,
440
+ payload.locationMessage.address,
441
+ payload.locationMessage.degreesLatitude + ', ' + payload.locationMessage.degreesLongitude,
442
+ payload.locationMessage.comment
443
+ ]
444
+ .filter(part => part !== null && part !== undefined && part !== '')
445
+ .join(' | ');
446
+ } else if (payload?.liveLocationMessage) {
447
+ content =
448
+ '[Live location] ' +
449
+ payload.liveLocationMessage.degreesLatitude +
450
+ ', ' +
451
+ payload.liveLocationMessage.degreesLongitude +
452
+ (payload.liveLocationMessage.caption ? ' | ' + payload.liveLocationMessage.caption : '');
453
+ } else if (payload?.contactMessage) {
454
+ content =
455
+ '[Contact] ' +
456
+ (payload.contactMessage.displayName || '') +
457
+ (payload.contactMessage.vcard ? '\n' + payload.contactMessage.vcard : '');
458
+ } else if (payload?.contactsArrayMessage) {
459
+ content =
460
+ '[Contacts] ' +
461
+ (payload.contactsArrayMessage.contacts || [])
462
+ .map(contact => contact.displayName || '')
463
+ .filter(name => name !== '')
464
+ .join(', ');
465
+ } else if (payload?.groupInviteMessage) {
466
+ content =
467
+ '[Group invite] ' +
468
+ (payload.groupInviteMessage.groupName || payload.groupInviteMessage.groupJid || '') +
469
+ (payload.groupInviteMessage.caption ? '\n' + payload.groupInviteMessage.caption : '');
470
+ } else if (payload?.eventMessage) {
471
+ content =
472
+ '[Event] ' +
473
+ (payload.eventMessage.isCanceled === true ? '(canceled) ' : '') +
474
+ (payload.eventMessage.name || '') +
475
+ (payload.eventMessage.description ? '\n' + payload.eventMessage.description : '');
476
+ } else if (extractMessageContent(payload)?.conversation) {
477
+ // buttons, lists and templates carry their text one wrapper deeper;
478
+ // baileys already knows where, so ask it instead of unpacking each one
479
+ content = extractMessageContent(payload).conversation;
399
480
  } else {
400
481
  continue;
401
482
  }
@@ -1067,5 +1148,7 @@ export default class wahelperDaemon {
1067
1148
  }
1068
1149
  }
1069
1150
 
1070
- let daemon = new wahelperDaemon();
1071
- daemon.init();
1151
+ if (process.argv[1] && fs.realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) {
1152
+ let daemon = new wahelperDaemon();
1153
+ daemon.init();
1154
+ }