@whanext/core 0.19.3 → 0.19.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.
- package/CHANGELOG.md +12 -0
- package/MIGRATING_TO_ZAPO.md +1 -1
- package/README.md +2 -0
- package/dist/index.js +46 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.19.4
|
|
4
|
+
### Corrigido
|
|
5
|
+
- Corrigida a normalização de `timestampMs` dos eventos nativos de chamada; removida uma referência inválida ao helper privado `#number`.
|
|
6
|
+
- Chamadas no provider Zapo agora usam o evento nativo `call`, sem depender do plugin completo de VoIP.
|
|
7
|
+
- `rejectCall()` envia diretamente a sinalização mínima `<call><reject/></call>` pelo `client.lowlevel.sendNode()`, preservando `callId` e `callCreatorJid`.
|
|
8
|
+
- Removidas as dependências `@zapo-js/voip`, `@roamhq/wrtc` e `libmlow-wasm` do WhaNext Core; detectar/rejeitar chamadas não exige WebRTC nem binário nativo.
|
|
9
|
+
- O `callCreatorJid` técnico é mantido em cache limitado para que a rejeição use o endereço de protocolo correto mesmo quando o evento público expõe o `callerPnJid`.
|
|
10
|
+
|
|
11
|
+
### Compatibilidade
|
|
12
|
+
- A API pública permanece igual: `app.on('call')`, `CallEvent` e `rejectCall(callId, from)` não mudam para consumidores.
|
|
13
|
+
- O suporte completo a aceitar/realizar chamadas VoIP não faz parte da API pública do WhaNext.
|
|
14
|
+
|
|
3
15
|
## 0.19.3
|
|
4
16
|
### Corrigido
|
|
5
17
|
- Carregamento lazy do plugin VoIP do Zapo para evitar importar o runtime WebRTC em consumidores e testes que não inicializam o provider.
|
package/MIGRATING_TO_ZAPO.md
CHANGED
|
@@ -58,7 +58,7 @@ O provider usa `@zapo-js/media-utils`. Para processamento completo de imagem, v
|
|
|
58
58
|
|
|
59
59
|
## Chamadas
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
A partir da v0.19.4, `app.on('call')` usa o evento `call` nativo do Zapo e `rejectCall()` envia somente a sinalização de rejeição pelo `client.lowlevel`. O WhaNext não carrega o stack completo de VoIP/WebRTC para detectar ou rejeitar chamadas.
|
|
62
62
|
|
|
63
63
|
## Checklist de atualização
|
|
64
64
|
|
package/README.md
CHANGED
|
@@ -994,6 +994,8 @@ app.on('call', async (call) => {
|
|
|
994
994
|
|
|
995
995
|
`call.status` reflete o ciclo da chamada (`offer`, `ringing`, `preaccept`, `timeout`, `reject`, `accept`). `call.isVideo` e `call.isGroup` indicam o tipo. Somente chamadas em `offer` podem ser rejeitadas.
|
|
996
996
|
|
|
997
|
+
No provider Zapo, detecção e rejeição usam apenas a sinalização nativa de chamadas e `client.lowlevel.sendNode()`. O WhaNext não carrega o stack completo de VoIP/WebRTC para esse fluxo.
|
|
998
|
+
|
|
997
999
|
## Erros
|
|
998
1000
|
|
|
999
1001
|
```ts
|
package/dist/index.js
CHANGED
|
@@ -2710,6 +2710,7 @@ var ZapoProvider = class {
|
|
|
2710
2710
|
#messageKeyStore = /* @__PURE__ */ new WeakMap();
|
|
2711
2711
|
#deliveredMessageStore = /* @__PURE__ */ new Set();
|
|
2712
2712
|
#handledProtocolStore = /* @__PURE__ */ new Set();
|
|
2713
|
+
#callCreatorStore = /* @__PURE__ */ new Map();
|
|
2713
2714
|
#messageCacheSize;
|
|
2714
2715
|
#client;
|
|
2715
2716
|
#intentionalClose = false;
|
|
@@ -2965,9 +2966,26 @@ var ZapoProvider = class {
|
|
|
2965
2966
|
const presence = this.#requireClient().presence;
|
|
2966
2967
|
await presence.sendChatstate(chatId, { state: value });
|
|
2967
2968
|
}
|
|
2968
|
-
async rejectCall(callId,
|
|
2969
|
+
async rejectCall(callId, from) {
|
|
2969
2970
|
const client = this.#requireClient();
|
|
2970
|
-
|
|
2971
|
+
const creator = this.#callCreatorStore.get(callId) ?? from;
|
|
2972
|
+
if (!creator) {
|
|
2973
|
+
throw new WhaNextError("ARGUMENT_INVALID", "Call creator is required to reject a call.");
|
|
2974
|
+
}
|
|
2975
|
+
const lowlevel = client.lowlevel;
|
|
2976
|
+
await lowlevel.sendNode({
|
|
2977
|
+
tag: "call",
|
|
2978
|
+
attrs: { to: creator },
|
|
2979
|
+
content: [
|
|
2980
|
+
{
|
|
2981
|
+
tag: "reject",
|
|
2982
|
+
attrs: {
|
|
2983
|
+
"call-id": callId,
|
|
2984
|
+
"call-creator": creator
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
]
|
|
2988
|
+
});
|
|
2971
2989
|
}
|
|
2972
2990
|
async #ensureClient() {
|
|
2973
2991
|
if (this.#client) return this.#client;
|
|
@@ -2996,8 +3014,6 @@ var ZapoProvider = class {
|
|
|
2996
3014
|
messageSecret: "sqlite"
|
|
2997
3015
|
}
|
|
2998
3016
|
});
|
|
2999
|
-
const { voipPlugin } = await import("@zapo-js/voip");
|
|
3000
|
-
const voip = voipPlugin({ logLevel: "warn" });
|
|
3001
3017
|
const client = new WaClient({
|
|
3002
3018
|
store,
|
|
3003
3019
|
sessionId: this.#options.sessionId ?? "default",
|
|
@@ -3009,8 +3025,7 @@ var ZapoProvider = class {
|
|
|
3009
3025
|
autoDecrypt: true,
|
|
3010
3026
|
persistAllSecrets: true
|
|
3011
3027
|
},
|
|
3012
|
-
media: { processor: createMediaProcessor() }
|
|
3013
|
-
plugins: [voip]
|
|
3028
|
+
media: { processor: createMediaProcessor() }
|
|
3014
3029
|
}, new WhaNextZapoLogger(this.#logger));
|
|
3015
3030
|
this.#client = client;
|
|
3016
3031
|
this.#bind(client);
|
|
@@ -3050,22 +3065,8 @@ var ZapoProvider = class {
|
|
|
3050
3065
|
client.on("group", (event) => {
|
|
3051
3066
|
this.#handleGroupEvent(event);
|
|
3052
3067
|
});
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
const call = this.#normalizeVoipCall(event, "offer");
|
|
3056
|
-
if (call) void this.#events.emit("call", call);
|
|
3057
|
-
});
|
|
3058
|
-
voipClient.on("voip_call_state", (event) => {
|
|
3059
|
-
const state = event.stateData?.state;
|
|
3060
|
-
if (state === "incoming_ringing" || state === "ended") return;
|
|
3061
|
-
const call = this.#normalizeVoipCall(event);
|
|
3062
|
-
if (call) void this.#events.emit("call", call);
|
|
3063
|
-
});
|
|
3064
|
-
voipClient.on("voip_call_ended", (event) => {
|
|
3065
|
-
const call = this.#normalizeVoipCall(
|
|
3066
|
-
event,
|
|
3067
|
-
this.#callEndStatus(event.stateData?.endReason)
|
|
3068
|
-
);
|
|
3068
|
+
client.on("call", (event) => {
|
|
3069
|
+
const call = this.#normalizeCall(event);
|
|
3069
3070
|
if (call) void this.#events.emit("call", call);
|
|
3070
3071
|
});
|
|
3071
3072
|
client.on("connection", (event) => {
|
|
@@ -3571,49 +3572,49 @@ var ZapoProvider = class {
|
|
|
3571
3572
|
timestamp: /* @__PURE__ */ new Date()
|
|
3572
3573
|
};
|
|
3573
3574
|
}
|
|
3574
|
-
#
|
|
3575
|
+
#normalizeCall(event) {
|
|
3575
3576
|
const id = event.callId;
|
|
3576
|
-
const
|
|
3577
|
-
const
|
|
3577
|
+
const creator = event.callCreatorJid ?? void 0;
|
|
3578
|
+
const from = event.callerPnJid ?? creator;
|
|
3579
|
+
const chatId = event.groupJid ?? from;
|
|
3578
3580
|
if (!id || !from || !chatId) return void 0;
|
|
3581
|
+
if (creator) {
|
|
3582
|
+
this.#callCreatorStore.delete(id);
|
|
3583
|
+
this.#callCreatorStore.set(id, creator);
|
|
3584
|
+
while (this.#callCreatorStore.size > 256) {
|
|
3585
|
+
const oldest = this.#callCreatorStore.keys().next().value;
|
|
3586
|
+
if (!oldest) break;
|
|
3587
|
+
this.#callCreatorStore.delete(oldest);
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
const timestampMs = toNumber2(event.timestampMs);
|
|
3579
3591
|
return {
|
|
3580
3592
|
id,
|
|
3581
3593
|
chatId,
|
|
3582
3594
|
from,
|
|
3583
|
-
status:
|
|
3584
|
-
isVideo: event.
|
|
3595
|
+
status: this.#callStatus(event.type),
|
|
3596
|
+
isVideo: event.isVideo === true,
|
|
3585
3597
|
isGroup: Boolean(event.groupJid),
|
|
3586
|
-
date:
|
|
3598
|
+
date: timestampMs && timestampMs > 0 ? new Date(timestampMs) : /* @__PURE__ */ new Date()
|
|
3587
3599
|
};
|
|
3588
3600
|
}
|
|
3589
3601
|
#callStatus(status) {
|
|
3590
3602
|
switch (status?.toLowerCase()) {
|
|
3591
3603
|
case "offer":
|
|
3592
|
-
case "initiating":
|
|
3593
3604
|
return "offer";
|
|
3594
3605
|
case "ringing":
|
|
3595
|
-
case "incoming_ringing":
|
|
3596
3606
|
return "ringing";
|
|
3597
3607
|
case "preaccept":
|
|
3598
|
-
case "connecting":
|
|
3599
3608
|
return "preaccept";
|
|
3600
3609
|
case "accept":
|
|
3601
|
-
case "accepted":
|
|
3602
|
-
case "active":
|
|
3603
3610
|
return "accept";
|
|
3604
3611
|
case "reject":
|
|
3605
|
-
case "rejected":
|
|
3606
3612
|
case "terminate":
|
|
3607
|
-
case "terminated":
|
|
3608
|
-
case "ended":
|
|
3609
3613
|
return "reject";
|
|
3610
3614
|
default:
|
|
3611
3615
|
return "timeout";
|
|
3612
3616
|
}
|
|
3613
3617
|
}
|
|
3614
|
-
#callEndStatus(reason) {
|
|
3615
|
-
return reason?.toLowerCase() === "timeout" ? "timeout" : "reject";
|
|
3616
|
-
}
|
|
3617
3618
|
#groupAction(action) {
|
|
3618
3619
|
const value = action?.toLowerCase() ?? "";
|
|
3619
3620
|
if (value.includes("promote")) return "promote";
|
|
@@ -3773,6 +3774,12 @@ var WhaNextZapoLogger = class _WhaNextZapoLogger {
|
|
|
3773
3774
|
return context ? { ...this.#context, ...context } : this.#context;
|
|
3774
3775
|
}
|
|
3775
3776
|
};
|
|
3777
|
+
function toNumber2(value) {
|
|
3778
|
+
if (typeof value === "number") return value;
|
|
3779
|
+
if (value?.toNumber) return value.toNumber();
|
|
3780
|
+
if (typeof value?.low === "number") return value.low;
|
|
3781
|
+
return void 0;
|
|
3782
|
+
}
|
|
3776
3783
|
function toSeconds(value) {
|
|
3777
3784
|
const raw = typeof value === "number" ? value : value?.toNumber ? value.toNumber() : value?.low;
|
|
3778
3785
|
if (raw === void 0) return void 0;
|