@arcaelas/whatsapp 6.1.0 → 6.1.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.
|
@@ -52,6 +52,8 @@ const internal_1 = require("../../lib/internal");
|
|
|
52
52
|
const message_1 = require("../../lib/message");
|
|
53
53
|
const status_1 = require("../../lib/status");
|
|
54
54
|
const store_1 = require("../../lib/store");
|
|
55
|
+
/** Rechazo del servidor: estado terminal, el único que puede retroceder el avance. / Server rejection: terminal state, the only one allowed to move the state backwards. */
|
|
56
|
+
const ERROR = 0;
|
|
55
57
|
/** Estados legibles del mensaje que el receipt puede avanzar. / Readable message states a receipt can advance to. */
|
|
56
58
|
const READ = 4;
|
|
57
59
|
const PLAYED = 5;
|
|
@@ -573,15 +575,30 @@ class WhatsApp {
|
|
|
573
575
|
* @internal
|
|
574
576
|
*/
|
|
575
577
|
async #persist_contact(raw) {
|
|
576
|
-
const
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
578
|
+
const current = (0, store_1.deserialize)(await this.engine.get(`/contact/${raw.id}`));
|
|
579
|
+
// Los upserts del re-sync llegan con los campos vacíos: sin fusionar borran el nombre
|
|
580
|
+
// que ya se conocía y el chat pasa a mostrar el número pelado.
|
|
581
|
+
// Re-sync upserts arrive with empty fields: without merging they wipe the name already
|
|
582
|
+
// known and the chat falls back to showing the bare number.
|
|
583
|
+
const doc = current
|
|
584
|
+
? {
|
|
585
|
+
id: raw.id,
|
|
586
|
+
lid: raw.lid ?? current.lid,
|
|
587
|
+
name: raw.name ?? current.name,
|
|
588
|
+
notify: raw.notify ?? current.notify,
|
|
589
|
+
verified_name: raw.verified_name ?? current.verified_name,
|
|
590
|
+
img_url: raw.img_url ?? current.img_url,
|
|
591
|
+
status: raw.status ?? current.status,
|
|
592
|
+
}
|
|
593
|
+
: raw;
|
|
594
|
+
await this.engine.set(`/contact/${raw.id}`, (0, store_1.serialize)(doc));
|
|
595
|
+
if (doc.lid) {
|
|
596
|
+
await this.engine.set(`/lid/${doc.lid}`, (0, store_1.serialize)(doc.id));
|
|
580
597
|
}
|
|
581
|
-
if (
|
|
582
|
-
const person = new this.Contact(
|
|
583
|
-
const cached_chat = (0, store_1.deserialize)(await this.engine.get(`/chat/${
|
|
584
|
-
this.emit('contact:created', person, new this.Chat(cached_chat ?? { id:
|
|
598
|
+
if (!current) {
|
|
599
|
+
const person = new this.Contact(doc);
|
|
600
|
+
const cached_chat = (0, store_1.deserialize)(await this.engine.get(`/chat/${doc.id}`));
|
|
601
|
+
this.emit('contact:created', person, new this.Chat(cached_chat ?? { id: doc.id, name: person.name }), this);
|
|
585
602
|
}
|
|
586
603
|
}
|
|
587
604
|
/** @internal */
|
|
@@ -609,6 +626,7 @@ class WhatsApp {
|
|
|
609
626
|
const patch = {
|
|
610
627
|
...(c.notify && { notify: c.notify }),
|
|
611
628
|
...(c.name && { name: c.name }),
|
|
629
|
+
...(c.verifiedName && { verified_name: c.verifiedName }),
|
|
612
630
|
...(c.imgUrl && { img_url: c.imgUrl }),
|
|
613
631
|
...(c.status && { status: c.status }),
|
|
614
632
|
...(c.lid && { lid: c.lid }),
|
|
@@ -947,6 +965,13 @@ class WhatsApp {
|
|
|
947
965
|
if (existing_doc.reactions) {
|
|
948
966
|
doc.reactions = existing_doc.reactions;
|
|
949
967
|
}
|
|
968
|
+
// El historial reporta el estado que tenía al sincronizarse: si acá se reescribe
|
|
969
|
+
// por otro cambio (edición, destacado), el estado ya conocido se conserva.
|
|
970
|
+
// History reports the state it had when synced: if the doc gets rewritten here
|
|
971
|
+
// for another change (edit, star), the state already known is kept.
|
|
972
|
+
if (existing_doc.status > doc.status) {
|
|
973
|
+
doc.status = existing_doc.status;
|
|
974
|
+
}
|
|
950
975
|
if (existing_doc.status >= doc.status &&
|
|
951
976
|
existing_doc.caption === doc.caption &&
|
|
952
977
|
existing_doc.edited === doc.edited &&
|
|
@@ -958,16 +983,25 @@ class WhatsApp {
|
|
|
958
983
|
if (!existing_doc && !doc.me) {
|
|
959
984
|
const push_name = msg.pushName ?? null;
|
|
960
985
|
const is_group = cid.endsWith('@g.us');
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
986
|
+
// El contacto se completa cuando no existe y también cuando existe sin ningún
|
|
987
|
+
// nombre: el mensaje trae el pushName y el nombre del negocio verificado, que
|
|
988
|
+
// es lo único que queda si un re-sync anterior dejó la ficha en blanco.
|
|
989
|
+
// The contact is filled in when missing and also when it exists with no name at
|
|
990
|
+
// all: the message carries the pushName and the verified business name, the only
|
|
991
|
+
// thing left when an earlier re-sync blanked the card.
|
|
992
|
+
if (doc.author) {
|
|
993
|
+
const known = (0, store_1.deserialize)(await this.engine.get(`/contact/${doc.author}`));
|
|
994
|
+
if (!known || !(known.name ?? known.notify ?? known.verified_name)) {
|
|
995
|
+
await this.#persist_contact({
|
|
996
|
+
id: doc.author,
|
|
997
|
+
lid: msg.key.remoteJid?.endsWith('@lid') ? msg.key.remoteJid : null,
|
|
998
|
+
name: null,
|
|
999
|
+
notify: push_name,
|
|
1000
|
+
verified_name: msg.verifiedBizName ?? null,
|
|
1001
|
+
img_url: null,
|
|
1002
|
+
status: null,
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
971
1005
|
}
|
|
972
1006
|
if (!(await this.engine.get(`/chat/${cid}`))) {
|
|
973
1007
|
const chat_raw = {
|
|
@@ -1103,8 +1137,14 @@ class WhatsApp {
|
|
|
1103
1137
|
await this.engine.set(path, (0, store_1.serialize)(doc), doc.created_at);
|
|
1104
1138
|
const msg_instance = (0, message_1.message)(this, doc);
|
|
1105
1139
|
this.emit(doc.starred ? 'message:starred' : 'message:unstarred', msg_instance, await msg_instance.chat(), this);
|
|
1140
|
+
// WhatsApp reemite los acks desordenados al reconectar (un `sent` después
|
|
1141
|
+
// de un `delivered`), así que el estado solo avanza; el rechazo (`error`)
|
|
1142
|
+
// es terminal y sí puede pisar lo que hubiera.
|
|
1143
|
+
// WhatsApp re-emits acks out of order on reconnect (a `sent` after a
|
|
1144
|
+
// `delivered`), so the state only moves forward; a rejection (`error`) is
|
|
1145
|
+
// terminal and may override whatever was there.
|
|
1106
1146
|
}
|
|
1107
|
-
else if (status !== undefined) {
|
|
1147
|
+
else if (status !== undefined && (status > doc.status || status === ERROR)) {
|
|
1108
1148
|
raw.status = status;
|
|
1109
1149
|
doc.status = status;
|
|
1110
1150
|
// El rechazo del servidor viaja como stub del update; sin persistirlo el
|
|
@@ -13,6 +13,8 @@ import { bind } from '../../lib/internal.js';
|
|
|
13
13
|
import { Audio, Document, Event, Image, Location, message, Message, Poll, Sticker, Text, VCard, Video, } from '../../lib/message/index.js';
|
|
14
14
|
import { Feed, TTL_MS as FEED_TTL_MS } from '../../lib/status/index.js';
|
|
15
15
|
import { deserialize, serialize } from '../../lib/store/index.js';
|
|
16
|
+
/** Rechazo del servidor: estado terminal, el único que puede retroceder el avance. / Server rejection: terminal state, the only one allowed to move the state backwards. */
|
|
17
|
+
const ERROR = 0;
|
|
16
18
|
/** Estados legibles del mensaje que el receipt puede avanzar. / Readable message states a receipt can advance to. */
|
|
17
19
|
const READ = 4;
|
|
18
20
|
const PLAYED = 5;
|
|
@@ -534,15 +536,30 @@ export class WhatsApp {
|
|
|
534
536
|
* @internal
|
|
535
537
|
*/
|
|
536
538
|
async #persist_contact(raw) {
|
|
537
|
-
const
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
539
|
+
const current = deserialize(await this.engine.get(`/contact/${raw.id}`));
|
|
540
|
+
// Los upserts del re-sync llegan con los campos vacíos: sin fusionar borran el nombre
|
|
541
|
+
// que ya se conocía y el chat pasa a mostrar el número pelado.
|
|
542
|
+
// Re-sync upserts arrive with empty fields: without merging they wipe the name already
|
|
543
|
+
// known and the chat falls back to showing the bare number.
|
|
544
|
+
const doc = current
|
|
545
|
+
? {
|
|
546
|
+
id: raw.id,
|
|
547
|
+
lid: raw.lid ?? current.lid,
|
|
548
|
+
name: raw.name ?? current.name,
|
|
549
|
+
notify: raw.notify ?? current.notify,
|
|
550
|
+
verified_name: raw.verified_name ?? current.verified_name,
|
|
551
|
+
img_url: raw.img_url ?? current.img_url,
|
|
552
|
+
status: raw.status ?? current.status,
|
|
553
|
+
}
|
|
554
|
+
: raw;
|
|
555
|
+
await this.engine.set(`/contact/${raw.id}`, serialize(doc));
|
|
556
|
+
if (doc.lid) {
|
|
557
|
+
await this.engine.set(`/lid/${doc.lid}`, serialize(doc.id));
|
|
541
558
|
}
|
|
542
|
-
if (
|
|
543
|
-
const person = new this.Contact(
|
|
544
|
-
const cached_chat = deserialize(await this.engine.get(`/chat/${
|
|
545
|
-
this.emit('contact:created', person, new this.Chat(cached_chat ?? { id:
|
|
559
|
+
if (!current) {
|
|
560
|
+
const person = new this.Contact(doc);
|
|
561
|
+
const cached_chat = deserialize(await this.engine.get(`/chat/${doc.id}`));
|
|
562
|
+
this.emit('contact:created', person, new this.Chat(cached_chat ?? { id: doc.id, name: person.name }), this);
|
|
546
563
|
}
|
|
547
564
|
}
|
|
548
565
|
/** @internal */
|
|
@@ -570,6 +587,7 @@ export class WhatsApp {
|
|
|
570
587
|
const patch = {
|
|
571
588
|
...(c.notify && { notify: c.notify }),
|
|
572
589
|
...(c.name && { name: c.name }),
|
|
590
|
+
...(c.verifiedName && { verified_name: c.verifiedName }),
|
|
573
591
|
...(c.imgUrl && { img_url: c.imgUrl }),
|
|
574
592
|
...(c.status && { status: c.status }),
|
|
575
593
|
...(c.lid && { lid: c.lid }),
|
|
@@ -908,6 +926,13 @@ export class WhatsApp {
|
|
|
908
926
|
if (existing_doc.reactions) {
|
|
909
927
|
doc.reactions = existing_doc.reactions;
|
|
910
928
|
}
|
|
929
|
+
// El historial reporta el estado que tenía al sincronizarse: si acá se reescribe
|
|
930
|
+
// por otro cambio (edición, destacado), el estado ya conocido se conserva.
|
|
931
|
+
// History reports the state it had when synced: if the doc gets rewritten here
|
|
932
|
+
// for another change (edit, star), the state already known is kept.
|
|
933
|
+
if (existing_doc.status > doc.status) {
|
|
934
|
+
doc.status = existing_doc.status;
|
|
935
|
+
}
|
|
911
936
|
if (existing_doc.status >= doc.status &&
|
|
912
937
|
existing_doc.caption === doc.caption &&
|
|
913
938
|
existing_doc.edited === doc.edited &&
|
|
@@ -919,16 +944,25 @@ export class WhatsApp {
|
|
|
919
944
|
if (!existing_doc && !doc.me) {
|
|
920
945
|
const push_name = msg.pushName ?? null;
|
|
921
946
|
const is_group = cid.endsWith('@g.us');
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
947
|
+
// El contacto se completa cuando no existe y también cuando existe sin ningún
|
|
948
|
+
// nombre: el mensaje trae el pushName y el nombre del negocio verificado, que
|
|
949
|
+
// es lo único que queda si un re-sync anterior dejó la ficha en blanco.
|
|
950
|
+
// The contact is filled in when missing and also when it exists with no name at
|
|
951
|
+
// all: the message carries the pushName and the verified business name, the only
|
|
952
|
+
// thing left when an earlier re-sync blanked the card.
|
|
953
|
+
if (doc.author) {
|
|
954
|
+
const known = deserialize(await this.engine.get(`/contact/${doc.author}`));
|
|
955
|
+
if (!known || !(known.name ?? known.notify ?? known.verified_name)) {
|
|
956
|
+
await this.#persist_contact({
|
|
957
|
+
id: doc.author,
|
|
958
|
+
lid: msg.key.remoteJid?.endsWith('@lid') ? msg.key.remoteJid : null,
|
|
959
|
+
name: null,
|
|
960
|
+
notify: push_name,
|
|
961
|
+
verified_name: msg.verifiedBizName ?? null,
|
|
962
|
+
img_url: null,
|
|
963
|
+
status: null,
|
|
964
|
+
});
|
|
965
|
+
}
|
|
932
966
|
}
|
|
933
967
|
if (!(await this.engine.get(`/chat/${cid}`))) {
|
|
934
968
|
const chat_raw = {
|
|
@@ -1064,8 +1098,14 @@ export class WhatsApp {
|
|
|
1064
1098
|
await this.engine.set(path, serialize(doc), doc.created_at);
|
|
1065
1099
|
const msg_instance = message(this, doc);
|
|
1066
1100
|
this.emit(doc.starred ? 'message:starred' : 'message:unstarred', msg_instance, await msg_instance.chat(), this);
|
|
1101
|
+
// WhatsApp reemite los acks desordenados al reconectar (un `sent` después
|
|
1102
|
+
// de un `delivered`), así que el estado solo avanza; el rechazo (`error`)
|
|
1103
|
+
// es terminal y sí puede pisar lo que hubiera.
|
|
1104
|
+
// WhatsApp re-emits acks out of order on reconnect (a `sent` after a
|
|
1105
|
+
// `delivered`), so the state only moves forward; a rejection (`error`) is
|
|
1106
|
+
// terminal and may override whatever was there.
|
|
1067
1107
|
}
|
|
1068
|
-
else if (status !== undefined) {
|
|
1108
|
+
else if (status !== undefined && (status > doc.status || status === ERROR)) {
|
|
1069
1109
|
raw.status = status;
|
|
1070
1110
|
doc.status = status;
|
|
1071
1111
|
// El rechazo del servidor viaja como stub del update; sin persistirlo el
|