@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 +27 -0
- package/README.md +28 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +46 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
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:
|
|
2507
|
-
|
|
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]);
|