@whanext/core 0.14.0 → 0.14.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.14.2
4
+
5
+ ### Corrigido
6
+
7
+ - Mensagens privadas recebidas agora combinam `remoteJid` e `remoteJidAlt` nas identidades normalizadas do remetente, preservando PN JID e LID quando o WhatsApp fornece ambos.
8
+ - `message.sender`, `message.senderIds` e `ctx.user.phone` passam a expor corretamente o número do remetente em chats privados LID sem exigir tratamento de Baileys na aplicação.
9
+ - A identidade alternativa só é usada para mensagens recebidas em chats privados; mensagens de grupo e mensagens `fromMe` mantêm o comportamento anterior.
10
+
11
+ ### Compatibilidade
12
+
13
+ - Nenhuma API pública foi removida ou alterada. Aplicações que já usam `ctx.user.phone` passam apenas a receber o número em mais casos.
14
+
15
+ ## 0.14.1
16
+
17
+ ### Corrigido
18
+
19
+ - A normalização agora preserva corretamente o envelope de visualização única (`viewOnceMessage`, `viewOnceMessageV2` e `viewOnceMessageV2Extension`) antes de desembrulhar a mídia.
20
+ - `message.isViewOnce` passa a ser verdadeiro mesmo quando o Baileys representa a visualização única apenas pelo wrapper externo.
21
+ - Mensagens citadas agora expõem `quoted.isViewOnce`, `quoted.contentKind` e `quoted.media`, permitindo distinguir mídia normal de visualização única sem heurísticas na aplicação.
22
+ - `app.media.download()` aceita diretamente uma `QuotedMessage`, permitindo `app.media.download(message.quoted)` quando houver mídia citada.
23
+ - `app.account.jid`, `app.account.lid`, `app.account.phoneNumber` e `app.account.selfChatId` expõem identidades canônicas da própria conta. `selfChatId` prioriza PN JID sem sufixo de dispositivo antes de usar LID.
24
+
25
+ ### Compatibilidade
26
+
27
+ - Os novos campos de `QuotedMessage` são opcionais no contrato público para não quebrar providers customizados ou objetos criados manualmente. O provider Baileys oficial os preenche nas mensagens normalizadas.
28
+ - `app.media.download(message)` e `app.media.download(message.keys)` continuam funcionando sem alteração.
29
+
3
30
  ## 0.14.0
4
31
 
5
32
  ### Adicionado
package/README.md CHANGED
@@ -373,7 +373,21 @@ const downloaded = await app.media.download(message);
373
373
  await writeFile(`./downloads/${downloaded.fileName ?? message.id}`, downloaded.data);
374
374
  ```
375
375
 
376
- `download()` aceita a `Message` recebida ou a sua `MessageKey` e devolve o buffer junto dos metadados normalizados. A mídia deve ser baixada enquanto a mensagem ainda está no cache da instância; o provider tenta renovar a URL de mídia automaticamente quando necessário.
376
+ `download()` aceita a `Message` recebida, uma `QuotedMessage` ou uma `MessageKey` e devolve o buffer junto dos metadados normalizados. A mídia deve ser baixada enquanto a mensagem ainda está no cache da instância; o provider tenta renovar a URL de mídia automaticamente quando necessário.
377
+
378
+ Para visualização única citada, o provider oficial preserva os metadados do envelope sem expor tipos do Baileys:
379
+
380
+ ```ts
381
+ if (message.quoted?.isViewOnce && message.quoted.hasMedia) {
382
+ const media = await app.media.download(message.quoted);
383
+
384
+ console.log(message.quoted.contentKind); // image | video | audio
385
+ console.log(message.quoted.media?.kind);
386
+ console.log(media.mimetype);
387
+ }
388
+ ```
389
+
390
+ Isso também funciona quando a mídia de visualização única aparece dentro de envelopes `viewOnceMessageV2` ou `viewOnceMessageV2Extension`.
377
391
 
378
392
  Stickers aceitam `Uint8Array`, URL ou caminho local e devem estar em WebP, inclusive para animações. Texto, imagem e vídeo aceitam `User` diretamente em `mentions`.
379
393
 
@@ -559,6 +573,19 @@ if (ctx.isOwner) {
559
573
  }
560
574
  ```
561
575
 
576
+ A identidade da própria conta também pode ser consultada sem escolher manualmente entre JID e LID:
577
+
578
+ ```ts
579
+ console.log(app.account.jid); // 5531...@s.whatsapp.net
580
+ console.log(app.account.lid); // ...@lid
581
+ console.log(app.account.phoneNumber); // 5531...
582
+ console.log(app.account.selfChatId); // destino preferencial para falar consigo mesmo
583
+ ```
584
+
585
+ `selfChatId` prioriza o PN JID canônico e remove automaticamente sufixos de dispositivo como `:12@s.whatsapp.net`.
586
+
587
+ Em conversas privadas endereçadas por LID, o provider também aproveita o `remoteJidAlt` enviado pelo WhatsApp para preencher a identidade PN do remetente. Assim, quando esse mapeamento estiver presente no evento ao vivo, `ctx.user.phone` continua retornando o número normalmente mesmo que `ctx.chatId` termine em `@lid`.
588
+
562
589
  Na API legada, use `onlyOwner: true`:
563
590
 
564
591
  ```ts
package/dist/index.d.ts CHANGED
@@ -86,6 +86,9 @@ interface QuotedMessage {
86
86
  senderId?: string;
87
87
  sender?: User;
88
88
  hasMedia: boolean;
89
+ isViewOnce?: boolean;
90
+ contentKind?: MessageContentKind;
91
+ media?: MessageMedia;
89
92
  }
90
93
  interface Message {
91
94
  id: string;
@@ -428,7 +431,7 @@ declare class MediaService {
428
431
  video(chatId: string, content: VideoContent): Promise<SentMessage>;
429
432
  audio(chatId: string, content: AudioContent): Promise<SentMessage>;
430
433
  sticker(chatId: string, content: StickerContent): Promise<SentMessage>;
431
- download(message: Message | MessageKey): Promise<DownloadedMedia>;
434
+ download(message: Message | QuotedMessage | MessageKey): Promise<DownloadedMedia>;
432
435
  }
433
436
 
434
437
  declare class MemberService {
@@ -715,6 +718,10 @@ declare class AccountService {
715
718
  readonly id: string | undefined;
716
719
  constructor(provider: WhatsAppProvider, id?: string);
717
720
  get ids(): readonly string[];
721
+ get jid(): string | undefined;
722
+ get lid(): string | undefined;
723
+ get phoneNumber(): string | undefined;
724
+ get selfChatId(): string | undefined;
718
725
  isOwner(message: Pick<Message, 'keys' | 'senderIds'>): boolean;
719
726
  }
720
727
 
package/dist/index.js CHANGED
@@ -1726,6 +1726,25 @@ var AccountService = class {
1726
1726
  get ids() {
1727
1727
  return uniqueIdentities(this.#provider.getCurrentUserIds());
1728
1728
  }
1729
+ get jid() {
1730
+ const identity = this.ids.find((candidate) => candidate.endsWith("@s.whatsapp.net") || candidate.endsWith("@c.us"));
1731
+ if (identity) {
1732
+ return normalizeIdentity(identity);
1733
+ }
1734
+ const phone = this.ids.map((candidate) => identityPhoneNumber(candidate)).find((candidate) => candidate !== void 0);
1735
+ return phone ? `${phone}@s.whatsapp.net` : void 0;
1736
+ }
1737
+ get lid() {
1738
+ const identity = this.ids.find((candidate) => candidate.endsWith("@lid"));
1739
+ return identity ? normalizeIdentity(identity) : void 0;
1740
+ }
1741
+ get phoneNumber() {
1742
+ const jid = this.jid;
1743
+ return jid ? identityPhoneNumber(jid) : void 0;
1744
+ }
1745
+ get selfChatId() {
1746
+ return this.jid ?? this.lid ?? this.ids[0];
1747
+ }
1729
1748
  isOwner(message) {
1730
1749
  if (message.keys.fromMe) {
1731
1750
  return true;
@@ -1900,7 +1919,7 @@ var MediaService = class {
1900
1919
  return this.#provider.sendMessage(chatId, content);
1901
1920
  }
1902
1921
  download(message) {
1903
- const key = "keys" in message ? message.keys : message;
1922
+ const key = "keys" in message ? message.keys : "key" in message ? message.key : message;
1904
1923
  return this.#provider.downloadMedia(key);
1905
1924
  }
1906
1925
  };
@@ -2331,6 +2350,13 @@ function unwrapMessageContent(input) {
2331
2350
  const nested = content.ephemeralMessage?.message ?? content.viewOnceMessage?.message ?? content.viewOnceMessageV2?.message ?? content.viewOnceMessageV2Extension?.message;
2332
2351
  return nested ? unwrapMessageContent(nested) : content;
2333
2352
  }
2353
+ function isViewOnceContent(input) {
2354
+ if (!input) return false;
2355
+ if (input.viewOnceMessage?.message || input.viewOnceMessageV2?.message || input.viewOnceMessageV2Extension?.message) {
2356
+ return true;
2357
+ }
2358
+ return isViewOnceContent(input.ephemeralMessage?.message);
2359
+ }
2334
2360
  function extractQuotedBaileysMessage(input) {
2335
2361
  const chatId = input.key.remoteJid;
2336
2362
  const content = unwrapMessageContent(input.message);
@@ -2362,10 +2388,14 @@ function normalizeBaileysMessage(input) {
2362
2388
  const type = getContentType(content);
2363
2389
  const node = type ? content[type] : void 0;
2364
2390
  const context = getContextInfo(node);
2391
+ const isPrivateIncoming = !chatId.endsWith("@g.us") && input.key.fromMe !== true;
2392
+ const remoteJidAlt = input.key.remoteJidAlt;
2365
2393
  const senderIds = uniqueIdentities([
2366
2394
  input.key.participant,
2367
2395
  input.key.participantAlt,
2368
- input.key.participantUsername?.includes("@") ? input.key.participantUsername : void 0
2396
+ input.key.participantUsername?.includes("@") ? input.key.participantUsername : void 0,
2397
+ isPrivateIncoming ? remoteJidAlt : void 0,
2398
+ isPrivateIncoming ? chatId : void 0
2369
2399
  ]);
2370
2400
  const senderJid = senderIds.find((identity) => identity.endsWith("@s.whatsapp.net") || identity.endsWith("@c.us"));
2371
2401
  const senderLid = senderIds.find((identity) => identity.endsWith("@lid"));
@@ -2376,7 +2406,8 @@ function normalizeBaileysMessage(input) {
2376
2406
  ...input.pushName ? { name: input.pushName } : {}
2377
2407
  });
2378
2408
  const mentionedUsers = (context?.mentionedJid ?? []).map((identity) => User.fromIdentities([identity]));
2379
- const media = getMedia(type, node, Boolean(input.key.isViewOnce));
2409
+ const viewOnce = Boolean(input.key.isViewOnce) || isViewOnceContent(input.message);
2410
+ const media = getMedia(type, node, viewOnce);
2380
2411
  const contentKind = getContentKind(type);
2381
2412
  const text = getText(content);
2382
2413
  const caption = getCaption(content);
@@ -2496,21 +2527,26 @@ function getQuoted(context, chatId) {
2496
2527
  return void 0;
2497
2528
  }
2498
2529
  const quoted = context.quotedMessage;
2530
+ const quotedIsViewOnce = isViewOnceContent(quoted);
2499
2531
  const content = unwrapMessageContent(quoted);
2532
+ const type = content ? getContentType(content) : void 0;
2533
+ const node = type && content ? content[type] : void 0;
2534
+ const media = getMedia(type, node, quotedIsViewOnce);
2500
2535
  const result = {
2501
2536
  key: {
2502
2537
  id: context.stanzaId,
2503
2538
  chatId: context.remoteJid ?? chatId,
2504
2539
  fromMe: false
2505
2540
  },
2506
- hasMedia: Boolean(
2507
- content && getMedia(
2508
- getContentType(content),
2509
- content[getContentType(content) ?? "conversation"],
2510
- false
2511
- )
2512
- )
2541
+ hasMedia: media !== void 0,
2542
+ isViewOnce: media?.viewOnce ?? quotedIsViewOnce
2513
2543
  };
2544
+ if (content) {
2545
+ result.contentKind = getContentKind(type);
2546
+ }
2547
+ if (media) {
2548
+ result.media = media;
2549
+ }
2514
2550
  if (context.participant) {
2515
2551
  result.senderId = context.participant;
2516
2552
  result.sender = User.fromIdentities([context.participant]);