@oxidezap/baileyrs 0.1.0 → 0.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.
- package/README.md +70 -0
- package/lib/Compatibility/legacy-store/namespaces.d.ts +20 -0
- package/lib/Compatibility/legacy-store/namespaces.js +27 -0
- package/lib/Compatibility/legacy-store/routing.js +13 -8
- package/lib/Compatibility/newsletter-results.d.ts +15 -0
- package/lib/Compatibility/newsletter-results.js +38 -0
- package/lib/Socket/business.d.ts +29 -0
- package/lib/Socket/business.js +104 -0
- package/lib/Socket/chat-actions.d.ts +20 -11
- package/lib/Socket/chat-actions.js +171 -83
- package/lib/Socket/events.js +5 -5
- package/lib/Socket/index.d.ts +85 -14
- package/lib/Socket/index.js +36 -26
- package/lib/Socket/internals.d.ts +88 -0
- package/lib/Socket/internals.js +145 -0
- package/lib/Socket/messages.d.ts +1 -15
- package/lib/Socket/messages.js +3 -22
- package/lib/Socket/newsletter.d.ts +61 -6
- package/lib/Socket/newsletter.js +125 -7
- package/lib/Socket/privacy.d.ts +25 -0
- package/lib/Socket/privacy.js +54 -0
- package/lib/Socket/server-queries.d.ts +38 -0
- package/lib/Socket/server-queries.js +121 -0
- package/lib/Socket/types.d.ts +6 -0
- package/lib/Types/Product.d.ts +9 -0
- package/lib/Utils/index.d.ts +1 -0
- package/lib/Utils/index.js +3 -0
- package/lib/Utils/link-preview.d.ts +60 -0
- package/lib/Utils/link-preview.js +357 -0
- package/lib/Utils/messages.d.ts +20 -7
- package/lib/Utils/messages.js +14 -3
- package/lib/Utils/wrap-legacy-store.d.ts +1 -0
- package/lib/Utils/wrap-legacy-store.js +1 -0
- package/package.json +4 -2
|
@@ -1,89 +1,177 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
1
|
+
import { Boom } from '../Utils/boom.js';
|
|
2
|
+
/**
|
|
3
|
+
* Refuse a field the mutation carries but the wire call cannot. Dropping it
|
|
4
|
+
* would report success for a change that never happened, which is the failure
|
|
5
|
+
* this whole path exists to stop.
|
|
6
|
+
*/
|
|
7
|
+
const rejectUnsupportedFields = (where, value, fields) => {
|
|
8
|
+
const present = fields.filter(field => value[field] != null);
|
|
9
|
+
if (present.length) {
|
|
10
|
+
throw new Boom(`${where}: ${present.join(', ')} cannot be set through this client`, {
|
|
11
|
+
statusCode: 400,
|
|
12
|
+
data: { fields: present }
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
export const makeChatActionMethods = (ctx) => {
|
|
17
|
+
const methods = {
|
|
18
|
+
pinChat: async (jid, pin) => {
|
|
19
|
+
await (await ctx.getClient()).pinChat(jid, pin);
|
|
20
|
+
},
|
|
21
|
+
muteChat: async (jid, muteUntil) => {
|
|
22
|
+
await (await ctx.getClient()).muteChat(jid, muteUntil);
|
|
23
|
+
},
|
|
24
|
+
archiveChat: async (jid, archive) => {
|
|
25
|
+
await (await ctx.getClient()).archiveChat(jid, archive);
|
|
26
|
+
},
|
|
27
|
+
starMessage: async (jid, messageId, star) => {
|
|
28
|
+
await (await ctx.getClient()).starMessage(jid, messageId, star);
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* Compatibility wrapper for original Baileys chatModify API.
|
|
32
|
+
* Routes to the appropriate bridge method based on the modification type.
|
|
33
|
+
*
|
|
34
|
+
* Every variant either runs or throws. A variant that resolved without
|
|
35
|
+
* doing anything told the caller their chat was labelled when nothing was
|
|
36
|
+
* synced, and no signature or type catches that.
|
|
37
|
+
*/
|
|
38
|
+
chatModify: async (mod, jid) => {
|
|
39
|
+
const client = await ctx.getClient();
|
|
40
|
+
if ('archive' in mod) {
|
|
41
|
+
await client.archiveChat(jid, mod.archive);
|
|
35
42
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
await client.markChatAsRead(jid, mod.markRead);
|
|
39
|
-
}
|
|
40
|
-
else if ('delete' in mod) {
|
|
41
|
-
await client.deleteChat(jid);
|
|
42
|
-
}
|
|
43
|
-
else if ('deleteForMe' in mod) {
|
|
44
|
-
await client.deleteMessageForMe(jid, mod.deleteForMe.key.id, !!mod.deleteForMe.key.fromMe);
|
|
45
|
-
}
|
|
46
|
-
else if ('pushNameSetting' in mod) {
|
|
47
|
-
await client.setPushName(mod.pushNameSetting);
|
|
48
|
-
}
|
|
49
|
-
else if ('contact' in mod) {
|
|
50
|
-
// Save/rename a contact (syncs the name to linked devices). `jid` is the
|
|
51
|
-
// contact's bare PN jid.
|
|
52
|
-
if (mod.contact) {
|
|
53
|
-
await client.saveContact(jid, mod.contact.fullName ?? undefined, mod.contact.firstName ?? undefined, mod.contact.saveOnPrimaryAddressbook ?? true);
|
|
43
|
+
else if ('pin' in mod) {
|
|
44
|
+
await client.pinChat(jid, mod.pin);
|
|
54
45
|
}
|
|
55
|
-
else {
|
|
56
|
-
|
|
57
|
-
// bridge/core path yet — warn instead of silently dropping.
|
|
58
|
-
ctx.logger.warn({ jid }, 'chatModify: contact removal (contact: null) not yet supported by bridge');
|
|
46
|
+
else if ('mute' in mod) {
|
|
47
|
+
await client.muteChat(jid, mod.mute);
|
|
59
48
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
// clears the whole chat. deleteStarred/deleteMedia aren't part of the
|
|
65
|
-
// Baileys `clear` shape, so default both to false (keep starred + media).
|
|
66
|
-
if (mod.clear) {
|
|
67
|
-
await client.clearChat(jid, false, false);
|
|
49
|
+
else if ('star' in mod) {
|
|
50
|
+
for (const msg of mod.star.messages) {
|
|
51
|
+
await client.starMessage(jid, msg.id, mod.star.star);
|
|
52
|
+
}
|
|
68
53
|
}
|
|
54
|
+
else if ('markRead' in mod) {
|
|
55
|
+
await client.markChatAsRead(jid, mod.markRead);
|
|
56
|
+
}
|
|
57
|
+
else if ('delete' in mod) {
|
|
58
|
+
await client.deleteChat(jid);
|
|
59
|
+
}
|
|
60
|
+
else if ('deleteForMe' in mod) {
|
|
61
|
+
await client.deleteMessageForMe(jid, mod.deleteForMe.key.id, !!mod.deleteForMe.key.fromMe);
|
|
62
|
+
}
|
|
63
|
+
else if ('pushNameSetting' in mod) {
|
|
64
|
+
await client.setPushName(mod.pushNameSetting);
|
|
65
|
+
}
|
|
66
|
+
else if ('contact' in mod) {
|
|
67
|
+
// Save/rename a contact (syncs the name to linked devices). `jid` is the
|
|
68
|
+
// contact's bare PN jid.
|
|
69
|
+
if (mod.contact) {
|
|
70
|
+
rejectUnsupportedFields('chatModify contact', mod.contact, ['lidJid', 'pnJid', 'username']);
|
|
71
|
+
await client.saveContact(jid, mod.contact.fullName ?? undefined, mod.contact.firstName ?? undefined, mod.contact.saveOnPrimaryAddressbook ?? true);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// Its own method, not `saveContact` with empty fields: removal is
|
|
75
|
+
// the one contact mutation the wire models as a `Remove`, and a
|
|
76
|
+
// `Set` carrying empty values renames the contact to "".
|
|
77
|
+
await client.removeContact(jid);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else if ('clear' in mod) {
|
|
81
|
+
// Clear a chat's messages while keeping the chat. `lastMessages` (the
|
|
82
|
+
// message range) is ignored, same as the `delete` branch — the bridge
|
|
83
|
+
// clears the whole chat. deleteStarred/deleteMedia aren't part of the
|
|
84
|
+
// Baileys `clear` shape, so default both to false (keep starred + media).
|
|
85
|
+
if (mod.clear) {
|
|
86
|
+
await client.clearChat(jid, false, false);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else if ('disableLinkPreviews' in mod) {
|
|
90
|
+
await client.setLinkPreviewsDisabled(mod.disableLinkPreviews.isPreviewsDisabled ?? false);
|
|
91
|
+
}
|
|
92
|
+
else if ('addLabel' in mod) {
|
|
93
|
+
// One upstream variant, two wire actions: an edit carrying
|
|
94
|
+
// `deleted` is the delete, not a separate modification.
|
|
95
|
+
if (mod.addLabel.deleted) {
|
|
96
|
+
await client.deleteLabel(mod.addLabel.id);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
rejectUnsupportedFields('chatModify addLabel', mod.addLabel, ['predefinedId']);
|
|
100
|
+
// The mutation replaces the whole label, so a missing field is
|
|
101
|
+
// not "leave it alone", it is "set it to nothing". Upstream can
|
|
102
|
+
// omit one because it builds the proto directly; this call
|
|
103
|
+
// cannot, so both are required rather than defaulted.
|
|
104
|
+
if (mod.addLabel.name === undefined || mod.addLabel.color === undefined) {
|
|
105
|
+
throw new Boom('chatModify addLabel: name and color are both required, because the label mutation is a full replace and an omitted field would reset it', { statusCode: 400 });
|
|
106
|
+
}
|
|
107
|
+
await client.createLabel(mod.addLabel.id, mod.addLabel.name, mod.addLabel.color);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else if ('addChatLabel' in mod) {
|
|
111
|
+
await client.addChatLabel(mod.addChatLabel.labelId, jid);
|
|
112
|
+
}
|
|
113
|
+
else if ('removeChatLabel' in mod) {
|
|
114
|
+
await client.removeChatLabel(mod.removeChatLabel.labelId, jid);
|
|
115
|
+
}
|
|
116
|
+
else if ('addMessageLabel' in mod) {
|
|
117
|
+
await client.addMessageLabel(mod.addMessageLabel.labelId, jid, mod.addMessageLabel.messageId);
|
|
118
|
+
}
|
|
119
|
+
else if ('removeMessageLabel' in mod) {
|
|
120
|
+
await client.removeMessageLabel(mod.removeMessageLabel.labelId, jid, mod.removeMessageLabel.messageId);
|
|
121
|
+
}
|
|
122
|
+
else if ('quickReply' in mod) {
|
|
123
|
+
// Upstream's `timestamp` is the app-state index key, the same slot
|
|
124
|
+
// the core calls `id`. Deleting is the same upsert with `deleted`.
|
|
125
|
+
// `||`, not `??`: upstream treats an empty timestamp as absent and
|
|
126
|
+
// mints a key, and the core rejects an empty index outright.
|
|
127
|
+
const id = mod.quickReply.timestamp || String(Math.floor(Date.now() / 1000));
|
|
128
|
+
if (mod.quickReply.deleted) {
|
|
129
|
+
await client.deleteQuickReply(id);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
await client.setQuickReply(id, mod.quickReply.shortcut ?? '', mod.quickReply.message ?? '', mod.quickReply.keywords ?? [], mod.quickReply.count ?? 0);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
const variant = Object.keys(mod)[0] ?? '(empty)';
|
|
137
|
+
throw new Boom(`chatModify: unsupported modification '${variant}'`, { statusCode: 400, data: { variant, jid } });
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
// Upstream models all of these as sugar over `chatModify`, and so do we:
|
|
141
|
+
// one place decides which bridge call a modification becomes, so the
|
|
142
|
+
// method and the modification can never disagree.
|
|
143
|
+
addOrEditContact: async (jid, contact) => {
|
|
144
|
+
await methods.chatModify({ contact }, jid);
|
|
145
|
+
},
|
|
146
|
+
removeContact: async (jid) => {
|
|
147
|
+
await methods.chatModify({ contact: null }, jid);
|
|
148
|
+
},
|
|
149
|
+
addLabel: async (jid, labels) => {
|
|
150
|
+
await methods.chatModify({ addLabel: { ...labels } }, jid);
|
|
151
|
+
},
|
|
152
|
+
addChatLabel: async (jid, labelId) => {
|
|
153
|
+
await methods.chatModify({ addChatLabel: { labelId } }, jid);
|
|
154
|
+
},
|
|
155
|
+
removeChatLabel: async (jid, labelId) => {
|
|
156
|
+
await methods.chatModify({ removeChatLabel: { labelId } }, jid);
|
|
157
|
+
},
|
|
158
|
+
addMessageLabel: async (jid, messageId, labelId) => {
|
|
159
|
+
await methods.chatModify({ addMessageLabel: { labelId, messageId } }, jid);
|
|
160
|
+
},
|
|
161
|
+
removeMessageLabel: async (jid, messageId, labelId) => {
|
|
162
|
+
await methods.chatModify({ removeMessageLabel: { labelId, messageId } }, jid);
|
|
163
|
+
},
|
|
164
|
+
star: async (jid, messages, star) => {
|
|
165
|
+
await methods.chatModify({ star: { messages, star } }, jid);
|
|
166
|
+
},
|
|
167
|
+
// No jid: a quick reply is account-wide, keyed only by its index.
|
|
168
|
+
addOrEditQuickReply: async (quickReply) => {
|
|
169
|
+
await methods.chatModify({ quickReply }, '');
|
|
170
|
+
},
|
|
171
|
+
removeQuickReply: async (timestamp) => {
|
|
172
|
+
await methods.chatModify({ quickReply: { timestamp, deleted: true } }, '');
|
|
69
173
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
// removeChatLabel, addMessageLabel, removeMessageLabel, quickReply
|
|
74
|
-
const variant = Object.keys(mod)[0];
|
|
75
|
-
ctx.logger.warn({ variant, jid }, 'chatModify: variant requires app-state patch support not yet available in bridge');
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
/**
|
|
79
|
-
* Force re-sync of app state collections.
|
|
80
|
-
*
|
|
81
|
-
* In the Rust bridge architecture, app state is managed internally by the engine
|
|
82
|
-
* and synced automatically on connect. This method is a no-op provided for API
|
|
83
|
-
* compatibility with upstream Baileys.
|
|
84
|
-
*/
|
|
85
|
-
resyncAppState: async (_collections, _isInitialSync) => {
|
|
86
|
-
ctx.logger.info('resyncAppState: app state is synced automatically by the Rust bridge');
|
|
87
|
-
}
|
|
88
|
-
});
|
|
174
|
+
};
|
|
175
|
+
return methods;
|
|
176
|
+
};
|
|
89
177
|
//# sourceMappingURL=chat-actions.js.map
|
package/lib/Socket/events.js
CHANGED
|
@@ -813,7 +813,7 @@ const dispatchCanonicalEvent = (canonical, dispatchCtx) => {
|
|
|
813
813
|
}
|
|
814
814
|
catch (err) {
|
|
815
815
|
// One bad event must not poison the rest of the pipeline.
|
|
816
|
-
dispatchCtx.ctx.
|
|
816
|
+
dispatchCtx.ctx.reportUnexpectedError(err, `dispatching a '${canonical.type}' event`);
|
|
817
817
|
}
|
|
818
818
|
};
|
|
819
819
|
/** Aggregate adjacent ordinary messages while preserving every side-effecting
|
|
@@ -852,7 +852,7 @@ const dispatchCanonicalBatch = (ctx, dispatchCtx, count, canonicalAt) => {
|
|
|
852
852
|
}
|
|
853
853
|
}
|
|
854
854
|
catch (err) {
|
|
855
|
-
ctx.
|
|
855
|
+
ctx.reportUnexpectedError(err, `dispatching a '${CANONICAL_MESSAGE_EVENT}' event`);
|
|
856
856
|
}
|
|
857
857
|
}
|
|
858
858
|
if (pending)
|
|
@@ -884,7 +884,7 @@ export const makeEventHandlers = (ctx, callbacks) => {
|
|
|
884
884
|
view = decodeMessageWireBatch(batch);
|
|
885
885
|
}
|
|
886
886
|
catch (err) {
|
|
887
|
-
ctx.
|
|
887
|
+
ctx.reportUnexpectedError(err, 'decoding the message wire batch');
|
|
888
888
|
return;
|
|
889
889
|
}
|
|
890
890
|
const { messageData, messageOffsets, infos } = view;
|
|
@@ -923,7 +923,7 @@ export const makeEventHandlers = (ctx, callbacks) => {
|
|
|
923
923
|
receipts = decodeReceiptWireBatch(batch);
|
|
924
924
|
}
|
|
925
925
|
catch (err) {
|
|
926
|
-
ctx.
|
|
926
|
+
ctx.reportUnexpectedError(err, 'decoding the receipt wire batch');
|
|
927
927
|
return;
|
|
928
928
|
}
|
|
929
929
|
// The decoded payload matches the single-event wire shape; the union's
|
|
@@ -937,7 +937,7 @@ export const makeEventHandlers = (ctx, callbacks) => {
|
|
|
937
937
|
acks = decodeServerAckWireBatch(batch);
|
|
938
938
|
}
|
|
939
939
|
catch (err) {
|
|
940
|
-
ctx.
|
|
940
|
+
ctx.reportUnexpectedError(err, 'decoding the server-ack wire batch');
|
|
941
941
|
return;
|
|
942
942
|
}
|
|
943
943
|
for (const data of acks)
|
package/lib/Socket/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Buffer } from 'node:buffer';
|
|
|
2
2
|
import { type UploadMediaResult } from '@oxidezap/whatsapp-rust-bridge';
|
|
3
3
|
import { WebSocketClient } from '../Compatibility/websocket-client.js';
|
|
4
4
|
import { type MediaType } from '../Defaults/index.js';
|
|
5
|
-
import type { BinaryNode, AuthenticationCreds, ConnectionState, Contact, ReachoutTimelockState, SignalKeyStoreWithTransaction, UserFacingSocketConfig,
|
|
5
|
+
import type { BinaryNode, AuthenticationCreds, ConnectionState, Contact, ReachoutTimelockState, SignalKeyStoreWithTransaction, UserFacingSocketConfig, WABusinessProfile, WAMessage, WAMessageKey } from '../Types/index.js';
|
|
6
6
|
import type Long from 'long';
|
|
7
7
|
import type { MediaDownloadOptions } from '../Utils/messages-media.js';
|
|
8
8
|
import type { proto } from '../WAProto/runtime.js';
|
|
@@ -12,12 +12,33 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
|
|
|
12
12
|
sendRetryRequest: (node: BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
|
|
13
13
|
updateBlockStatus: (jid: string, action: 'block' | 'unblock') => Promise<void>;
|
|
14
14
|
fetchBlocklist: () => Promise<Array<string | undefined>>;
|
|
15
|
+
getCatalog: ({ jid, limit, cursor }: import("../index.js").GetCatalogOptions) => Promise<import("../index.js").CatalogPage>;
|
|
16
|
+
getCollections: (jid?: string, limit?: number) => Promise<import("../index.js").CollectionsPage>;
|
|
17
|
+
getOrderDetails: (orderId: string, tokenBase64: string, sellerJid?: string) => Promise<import("@oxidezap/whatsapp-rust-bridge").OrderResult>;
|
|
18
|
+
updateBussinesProfile: (args: import("../Types/Bussines.js").UpdateBussinesProfileProps) => Promise<void>;
|
|
19
|
+
updateCoverPhoto: (photo: import("../index.js").WAMediaUpload) => Promise<never>;
|
|
20
|
+
removeCoverPhoto: (id: string) => Promise<void>;
|
|
21
|
+
productCreate: (create: import("../index.js").ProductCreate) => Promise<never>;
|
|
22
|
+
productUpdate: (productId: string, update: import("../index.js").ProductUpdate) => Promise<never>;
|
|
23
|
+
productDelete: (productIds: string[]) => Promise<never>;
|
|
15
24
|
pinChat: (jid: string, pin: boolean) => Promise<void>;
|
|
16
25
|
muteChat: (jid: string, muteUntil?: number | null) => Promise<void>;
|
|
17
26
|
archiveChat: (jid: string, archive: boolean) => Promise<void>;
|
|
18
27
|
starMessage: (jid: string, messageId: string, star: boolean) => Promise<void>;
|
|
19
28
|
chatModify: (mod: import("../index.js").ChatModification, jid: string) => Promise<void>;
|
|
20
|
-
|
|
29
|
+
addOrEditContact: (jid: string, contact: proto.SyncActionValue.IContactAction) => Promise<void>;
|
|
30
|
+
removeContact: (jid: string) => Promise<void>;
|
|
31
|
+
addLabel: (jid: string, labels: import("../Types/Label.js").LabelActionBody) => Promise<void>;
|
|
32
|
+
addChatLabel: (jid: string, labelId: string) => Promise<void>;
|
|
33
|
+
removeChatLabel: (jid: string, labelId: string) => Promise<void>;
|
|
34
|
+
addMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
|
|
35
|
+
removeMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
|
|
36
|
+
star: (jid: string, messages: {
|
|
37
|
+
id: string;
|
|
38
|
+
fromMe?: boolean;
|
|
39
|
+
}[], star: boolean) => Promise<void>;
|
|
40
|
+
addOrEditQuickReply: (quickReply: import("../Types/Bussines.js").QuickReplyAction) => Promise<void>;
|
|
41
|
+
removeQuickReply: (timestamp: string) => Promise<void>;
|
|
21
42
|
onWhatsApp: (...phoneNumber: string[]) => Promise<import("./contacts.js").OnWhatsAppResult[] | undefined>;
|
|
22
43
|
profilePictureUrl: (jid: string, type?: 'preview' | 'image', timeoutMs?: number) => Promise<string | undefined>;
|
|
23
44
|
fetchUserInfo: (...jids: string[]) => Promise<Record<string, import("@oxidezap/whatsapp-rust-bridge").UserInfoResult>>;
|
|
@@ -74,6 +95,14 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
|
|
|
74
95
|
communityMemberAddMode: (jid: string, mode: 'admin_add' | 'all_member_add') => Promise<void>;
|
|
75
96
|
communityJoinApprovalMode: (jid: string, mode: 'on' | 'off') => Promise<void>;
|
|
76
97
|
communityFetchAllParticipating: () => Promise<Record<string, import("../index.js").GroupMetadata>>;
|
|
98
|
+
waitForSocketOpen: () => Promise<void>;
|
|
99
|
+
upsertMessage: (msg: WAMessage, type: import("../index.js").MessageUpsertType) => Promise<void>;
|
|
100
|
+
onUnexpectedError: (err: Error, msg: string) => void;
|
|
101
|
+
resyncAppState: (collections?: readonly ('critical_block' | 'critical_unblock_low' | 'regular_high' | 'regular_low' | 'regular')[], isInitialSync?: boolean) => Promise<void>;
|
|
102
|
+
updateServerTimeOffset: (node: BinaryNode) => never;
|
|
103
|
+
sendUnifiedSession: () => Promise<never>;
|
|
104
|
+
appPatch: (patchCreate: import("../index.js").WAPatchCreate) => Promise<never>;
|
|
105
|
+
messageRetryManager: null;
|
|
77
106
|
sendMessage: (jid: string, content: import("../index.js").AnyMessageContent, options?: Omit<import("../index.js").MessageGenerationOptions, 'waClient' | 'logger' | 'userJid' | 'mediaInNote'>) => Promise<WAMessage>;
|
|
78
107
|
updateMediaMessage: (message: WAMessage) => Promise<WAMessage>;
|
|
79
108
|
relayMessage: (jid: string, message: proto.IMessage, options: import("../index.js").MessageRelayOptions) => Promise<string>;
|
|
@@ -81,12 +110,31 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
|
|
|
81
110
|
sendReceipt: (jid: string, participant: string | undefined, messageIds: string[], type: import("../index.js").MessageReceiptType) => Promise<void>;
|
|
82
111
|
sendReceipts: (keys: WAMessageKey[], type: import("../index.js").MessageReceiptType) => Promise<void>;
|
|
83
112
|
requestPlaceholderResend: (messageKey: WAMessageKey, msgData?: Partial<WAMessage>) => Promise<string | undefined>;
|
|
84
|
-
newsletterCreate: (name: string, description?: string) => Promise<import("
|
|
85
|
-
newsletterMetadata: (jid: string) => Promise<import("
|
|
113
|
+
newsletterCreate: (name: string, description?: string) => Promise<import("../index.js").NewsletterMetadata>;
|
|
114
|
+
newsletterMetadata: (type: 'invite' | 'jid', key: string) => Promise<import("../index.js").NewsletterMetadata | null>;
|
|
115
|
+
newsletterUpdate: (jid: string, updates: import("../index.js").NewsletterUpdate) => Promise<import("../index.js").NewsletterMetadata>;
|
|
116
|
+
newsletterUpdateName: (jid: string, name: string) => Promise<import("../index.js").NewsletterMetadata>;
|
|
117
|
+
newsletterUpdateDescription: (jid: string, description: string) => Promise<import("../index.js").NewsletterMetadata>;
|
|
118
|
+
newsletterUpdatePicture: (jid: string, content: import("../index.js").WAMediaUpload) => Promise<import("../index.js").NewsletterMetadata>;
|
|
119
|
+
newsletterRemovePicture: (jid: string) => Promise<import("../index.js").NewsletterMetadata>;
|
|
120
|
+
newsletterFollow: (jid: string) => Promise<import("../index.js").NewsletterMetadata>;
|
|
121
|
+
newsletterUnfollow: (jid: string) => Promise<void>;
|
|
86
122
|
newsletterSubscribe: (jid: string) => Promise<import("@oxidezap/whatsapp-rust-bridge").NewsletterMetadataResult>;
|
|
87
123
|
newsletterUnsubscribe: (jid: string) => Promise<void>;
|
|
124
|
+
newsletterMute: (jid: string) => Promise<void>;
|
|
125
|
+
newsletterUnmute: (jid: string) => Promise<void>;
|
|
126
|
+
newsletterSubscribers: (jid: string) => Promise<{
|
|
127
|
+
subscribers: number;
|
|
128
|
+
}>;
|
|
88
129
|
newsletterReactMessage: (jid: string, serverId: string, reaction?: string) => Promise<void>;
|
|
89
|
-
|
|
130
|
+
newsletterFetchMessages: (jid: string, count: number, since?: number, after?: number) => Promise<import("@oxidezap/whatsapp-rust-bridge").NewsletterMessageResult[]>;
|
|
131
|
+
subscribeNewsletterUpdates: (jid: string) => Promise<{
|
|
132
|
+
duration: string;
|
|
133
|
+
}>;
|
|
134
|
+
newsletterAdminCount: (jid: string) => Promise<number>;
|
|
135
|
+
newsletterChangeOwner: (jid: string, newOwnerJid: string) => Promise<void>;
|
|
136
|
+
newsletterDemote: (jid: string, userJid: string) => Promise<void>;
|
|
137
|
+
newsletterDelete: (jid: string) => Promise<void>;
|
|
90
138
|
uploadPreKeys: (count?: number) => Promise<void>;
|
|
91
139
|
uploadPreKeysToServerIfRequired: () => Promise<void>;
|
|
92
140
|
digestKeyBundle: () => Promise<void>;
|
|
@@ -94,6 +142,30 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
|
|
|
94
142
|
sendPresence: (status: 'available' | 'unavailable') => Promise<void>;
|
|
95
143
|
presenceSubscribe: (toJid: string) => Promise<void>;
|
|
96
144
|
sendChatState: (jid: string, state: 'composing' | 'recording' | 'paused') => Promise<void>;
|
|
145
|
+
fetchPrivacySettings: (force?: boolean) => Promise<any>;
|
|
146
|
+
updatePrivacySetting: (category: string, value: string) => Promise<void>;
|
|
147
|
+
updateLastSeenPrivacy: (value: import("../index.js").WAPrivacyValue) => Promise<void>;
|
|
148
|
+
updateOnlinePrivacy: (value: import("../index.js").WAPrivacyOnlineValue) => Promise<void>;
|
|
149
|
+
updateProfilePicturePrivacy: (value: import("../index.js").WAPrivacyValue) => Promise<void>;
|
|
150
|
+
updateStatusPrivacy: (value: import("../index.js").WAPrivacyValue) => Promise<void>;
|
|
151
|
+
updateReadReceiptsPrivacy: (value: import("../index.js").WAReadReceiptsValue) => Promise<void>;
|
|
152
|
+
updateGroupsAddPrivacy: (value: import("../index.js").WAPrivacyGroupAddValue) => Promise<void>;
|
|
153
|
+
updateCallPrivacy: (value: import("../index.js").WAPrivacyCallValue) => Promise<void>;
|
|
154
|
+
updateMessagesPrivacy: (value: import("../index.js").WAPrivacyMessagesValue) => Promise<void>;
|
|
155
|
+
issuePrivacyTokens: (jids: string[], timestamp?: number) => Promise<void>;
|
|
156
|
+
refreshMediaConn: (forceGet?: boolean) => Promise<Omit<import("../index.js").MediaConnInfo, 'hosts'> & {
|
|
157
|
+
hosts: {
|
|
158
|
+
hostname: string;
|
|
159
|
+
}[];
|
|
160
|
+
}>;
|
|
161
|
+
getMediaHost: () => string;
|
|
162
|
+
getBotListV2: () => Promise<import("../index.js").BotListInfo[]>;
|
|
163
|
+
fetchNewChatMessageCap: () => Promise<import("../index.js").NewChatMessageCapInfo & {
|
|
164
|
+
remaining_quota?: number;
|
|
165
|
+
}>;
|
|
166
|
+
cleanDirtyBits: (type: 'account_sync' | 'groups', fromTimestamp?: number | string) => Promise<void>;
|
|
167
|
+
sendPeerDataOperationMessage: (_pdoMessage: unknown) => Promise<never>;
|
|
168
|
+
createCallLink: (_type: 'audio' | 'video', _event?: unknown, _timeoutMs?: number) => Promise<never>;
|
|
97
169
|
requestPairingCode: (phoneNumber: string, customPairingCode?: string) => Promise<string>;
|
|
98
170
|
setPushName: (name: string) => Promise<void>;
|
|
99
171
|
updateProfileName: (name: string) => Promise<void>;
|
|
@@ -176,7 +248,14 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
|
|
|
176
248
|
waitForMessage: <T>(msgId: string, timeoutMs?: number | undefined) => Promise<T | undefined>;
|
|
177
249
|
query: (node: BinaryNode, timeoutMs?: number) => Promise<BinaryNode>;
|
|
178
250
|
sendRawMessage: (data: Uint8Array | Buffer) => Promise<void>;
|
|
179
|
-
|
|
251
|
+
/**
|
|
252
|
+
* `dsmMessage` is accepted so the signature matches upstream, and
|
|
253
|
+
* refused rather than ignored. Upstream uses it to encrypt a different
|
|
254
|
+
* plaintext for the caller's own other devices; the engine encrypts one
|
|
255
|
+
* payload for every recipient, so honouring it is not possible here and
|
|
256
|
+
* dropping it would send those devices the wrong message.
|
|
257
|
+
*/
|
|
258
|
+
createParticipantNodes: (jids: string[], message: proto.IMessage, extraAttrs?: BinaryNode['attrs'], dsmMessage?: proto.IMessage) => Promise<{
|
|
180
259
|
nodes: BinaryNode[];
|
|
181
260
|
shouldIncludeDeviceIdentity: boolean;
|
|
182
261
|
}>;
|
|
@@ -203,14 +282,6 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
|
|
|
203
282
|
waUploadToServer: (data: Uint8Array | Buffer, opts: {
|
|
204
283
|
mediaType: MediaType;
|
|
205
284
|
}) => Promise<UploadMediaResult>;
|
|
206
|
-
fetchPrivacySettings: (force?: boolean) => Promise<any>;
|
|
207
|
-
updatePrivacySetting: (category: string, value: string) => Promise<void>;
|
|
208
|
-
updateLastSeenPrivacy: (value: WAPrivacyValue) => Promise<void>;
|
|
209
|
-
updateOnlinePrivacy: (value: WAPrivacyOnlineValue) => Promise<void>;
|
|
210
|
-
updateProfilePicturePrivacy: (value: WAPrivacyValue) => Promise<void>;
|
|
211
|
-
updateStatusPrivacy: (value: WAPrivacyValue) => Promise<void>;
|
|
212
|
-
updateReadReceiptsPrivacy: (value: WAReadReceiptsValue) => Promise<void>;
|
|
213
|
-
updateGroupsAddPrivacy: (value: WAPrivacyGroupAddValue) => Promise<void>;
|
|
214
285
|
updateDefaultDisappearingMode: (duration: number) => Promise<void>;
|
|
215
286
|
rejectCall: (callId: string, callFrom: string) => Promise<void>;
|
|
216
287
|
/**
|
package/lib/Socket/index.js
CHANGED
|
@@ -21,6 +21,7 @@ import { makeNativeCryptoProvider } from '../Utils/native-crypto-provider.js';
|
|
|
21
21
|
import { wrapLegacyStore } from '../Utils/wrap-legacy-store.js';
|
|
22
22
|
import { assertNodeErrorFree } from '../WABinary/generic-utils.js';
|
|
23
23
|
import { makeBlockingMethods } from './blocking.js';
|
|
24
|
+
import { makeBusinessMethods } from './business.js';
|
|
24
25
|
import { makeChatActionMethods } from './chat-actions.js';
|
|
25
26
|
import { makeContactMethods } from './contacts.js';
|
|
26
27
|
import { makeCommunityMethods } from './communities.js';
|
|
@@ -28,10 +29,13 @@ import { makeBridgeClientOwner } from './bridge-client-owner.js';
|
|
|
28
29
|
import { makeTerminalCloseReporter } from './terminal-close-reporter.js';
|
|
29
30
|
import { makeEventHandlers } from './events.js';
|
|
30
31
|
import { makeGroupMethods } from './groups.js';
|
|
32
|
+
import { makeInternalMethods, makeUnexpectedErrorReporter } from './internals.js';
|
|
31
33
|
import { makeMessageMethods } from './messages.js';
|
|
32
34
|
import { makeNewsletterMethods } from './newsletter.js';
|
|
33
35
|
import { makePreKeyMethods } from './prekeys.js';
|
|
34
36
|
import { makePresenceMethods } from './presence.js';
|
|
37
|
+
import { makePrivacyMethods } from './privacy.js';
|
|
38
|
+
import { makeServerQueryMethods } from './server-queries.js';
|
|
35
39
|
import { makeProfileMethods } from './profile.js';
|
|
36
40
|
import { mapReachoutTimelock } from './reachout.js';
|
|
37
41
|
import { makeHttpClient, makeTransport } from './transport.js';
|
|
@@ -249,11 +253,18 @@ const makeWASocket = (config) => {
|
|
|
249
253
|
let autoReconnectEnabled = true;
|
|
250
254
|
/** Owns reporting the terminal close: once, after teardown, never not at all. */
|
|
251
255
|
const terminalClose = makeTerminalCloseReporter({ logger });
|
|
256
|
+
/**
|
|
257
|
+
* Held in a reporter rather than captured, because `sock.onUnexpectedError`
|
|
258
|
+
* is an assignable property: a consumer that replaces it has to be the one
|
|
259
|
+
* the socket's own failure paths reach afterwards.
|
|
260
|
+
*/
|
|
261
|
+
const unexpectedErrors = makeUnexpectedErrorReporter(logger);
|
|
252
262
|
const ctx = {
|
|
253
263
|
ev,
|
|
254
264
|
logger,
|
|
255
265
|
fullConfig,
|
|
256
266
|
ws,
|
|
267
|
+
reportUnexpectedError: unexpectedErrors.report,
|
|
257
268
|
getUser: () => user,
|
|
258
269
|
getMe: () => {
|
|
259
270
|
const me = auth.creds.me;
|
|
@@ -783,7 +794,17 @@ const makeWASocket = (config) => {
|
|
|
783
794
|
sendRawMessage: async (data) => {
|
|
784
795
|
return (await ctx.getClient()).sendRawMessage(data instanceof Uint8Array ? data : new Uint8Array(data));
|
|
785
796
|
},
|
|
786
|
-
|
|
797
|
+
/**
|
|
798
|
+
* `dsmMessage` is accepted so the signature matches upstream, and
|
|
799
|
+
* refused rather than ignored. Upstream uses it to encrypt a different
|
|
800
|
+
* plaintext for the caller's own other devices; the engine encrypts one
|
|
801
|
+
* payload for every recipient, so honouring it is not possible here and
|
|
802
|
+
* dropping it would send those devices the wrong message.
|
|
803
|
+
*/
|
|
804
|
+
createParticipantNodes: async (jids, message, extraAttrs, dsmMessage) => {
|
|
805
|
+
if (dsmMessage) {
|
|
806
|
+
throw new Boom('createParticipantNodes: dsmMessage is not supported, the engine encrypts one payload for every recipient and cannot substitute a different one for your own devices', { statusCode: 501 });
|
|
807
|
+
}
|
|
787
808
|
const bytes = encodeProto('Message', message);
|
|
788
809
|
return (await ctx.getClient()).createParticipantNodesBytes(jids, bytes, extraAttrs ?? {});
|
|
789
810
|
},
|
|
@@ -826,31 +847,7 @@ const makeWASocket = (config) => {
|
|
|
826
847
|
const bytes = data instanceof Uint8Array && !Buffer.isBuffer(data) ? data : new Uint8Array(data);
|
|
827
848
|
return (await ctx.getClient()).uploadMedia(bytes, toBridgeMediaType(opts.mediaType));
|
|
828
849
|
},
|
|
829
|
-
|
|
830
|
-
void force;
|
|
831
|
-
return (await ctx.getClient()).fetchPrivacySettings();
|
|
832
|
-
},
|
|
833
|
-
updatePrivacySetting: async (category, value) => {
|
|
834
|
-
await (await ctx.getClient()).updatePrivacySetting(category, value);
|
|
835
|
-
},
|
|
836
|
-
updateLastSeenPrivacy: async (value) => {
|
|
837
|
-
await (await ctx.getClient()).updatePrivacySetting('last', value);
|
|
838
|
-
},
|
|
839
|
-
updateOnlinePrivacy: async (value) => {
|
|
840
|
-
await (await ctx.getClient()).updatePrivacySetting('online', value);
|
|
841
|
-
},
|
|
842
|
-
updateProfilePicturePrivacy: async (value) => {
|
|
843
|
-
await (await ctx.getClient()).updatePrivacySetting('profile', value);
|
|
844
|
-
},
|
|
845
|
-
updateStatusPrivacy: async (value) => {
|
|
846
|
-
await (await ctx.getClient()).updatePrivacySetting('status', value);
|
|
847
|
-
},
|
|
848
|
-
updateReadReceiptsPrivacy: async (value) => {
|
|
849
|
-
await (await ctx.getClient()).updatePrivacySetting('readreceipts', value);
|
|
850
|
-
},
|
|
851
|
-
updateGroupsAddPrivacy: async (value) => {
|
|
852
|
-
await (await ctx.getClient()).updatePrivacySetting('groupadd', value);
|
|
853
|
-
},
|
|
850
|
+
...makePrivacyMethods(ctx),
|
|
854
851
|
updateDefaultDisappearingMode: async (duration) => {
|
|
855
852
|
await (await ctx.getClient()).updateDefaultDisappearingMode(duration);
|
|
856
853
|
},
|
|
@@ -891,11 +888,14 @@ const makeWASocket = (config) => {
|
|
|
891
888
|
...makeContactMethods(ctx),
|
|
892
889
|
...makeProfileMethods(ctx),
|
|
893
890
|
...makeChatActionMethods(ctx),
|
|
891
|
+
...makeInternalMethods(ctx),
|
|
894
892
|
...usyncMethods,
|
|
895
893
|
...makeStanzaResponseMethods(ctx),
|
|
896
894
|
...makePresenceMethods(ctx),
|
|
897
895
|
...makeBlockingMethods(ctx),
|
|
898
896
|
...makeNewsletterMethods(ctx),
|
|
897
|
+
...makeBusinessMethods(ctx),
|
|
898
|
+
...makeServerQueryMethods(ctx),
|
|
899
899
|
downloadMedia: async (message, type, options = {}) => {
|
|
900
900
|
return downloadMediaMessage(message, type, options, {
|
|
901
901
|
logger,
|
|
@@ -904,6 +904,16 @@ const makeWASocket = (config) => {
|
|
|
904
904
|
});
|
|
905
905
|
}
|
|
906
906
|
};
|
|
907
|
+
// Assigning replaces the handler the socket itself reports through, rather
|
|
908
|
+
// than shadowing it with a second one only a consumer could reach.
|
|
909
|
+
Object.defineProperty(sock, 'onUnexpectedError', {
|
|
910
|
+
get: () => unexpectedErrors.handler,
|
|
911
|
+
set: (handler) => {
|
|
912
|
+
unexpectedErrors.handler = handler;
|
|
913
|
+
},
|
|
914
|
+
enumerable: true,
|
|
915
|
+
configurable: true
|
|
916
|
+
});
|
|
907
917
|
return sock;
|
|
908
918
|
};
|
|
909
919
|
export default makeWASocket;
|