@queenanya/baileys 7.4.14 → 7.5.3-0
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 +26 -26
- package/lib/Defaults/baileys-version.json +1 -1
- package/lib/Defaults/index.d.ts +1 -231
- package/lib/Defaults/index.js +11 -23
- package/lib/Socket/Client/index.d.ts +2 -3
- package/lib/Socket/Client/index.js +2 -3
- package/lib/Socket/Client/{web-socket-client.d.ts → websocket.d.ts} +1 -1
- package/lib/Socket/Client/{web-socket-client.js → websocket.js} +2 -2
- package/lib/Socket/business.d.ts +31 -28
- package/lib/Socket/chats.d.ts +17 -9
- package/lib/Socket/chats.js +115 -116
- package/lib/Socket/{registration.d.ts → communities.d.ts} +94 -145
- package/lib/Socket/communities.js +354 -0
- package/lib/Socket/groups.d.ts +23 -10
- package/lib/Socket/groups.js +12 -1
- package/lib/Socket/index.d.ts +69 -38
- package/lib/Socket/index.js +2 -2
- package/lib/Socket/messages-recv.d.ts +30 -28
- package/lib/Socket/messages-recv.js +291 -180
- package/lib/Socket/messages-send.d.ts +25 -19
- package/lib/Socket/messages-send.js +110 -76
- package/lib/Socket/newsletter.d.ts +19 -13
- package/lib/Socket/newsletter.js +67 -54
- package/lib/Socket/socket.d.ts +3 -1
- package/lib/Socket/socket.js +15 -17
- package/lib/Socket/usync.d.ts +38 -0
- package/lib/Socket/usync.js +70 -0
- package/lib/Store/make-cache-manager-store.d.ts +2 -1
- package/lib/Store/make-in-memory-store.js +13 -11
- package/lib/Store/make-ordered-dictionary.js +2 -2
- package/lib/Types/Auth.d.ts +1 -6
- package/lib/Types/Call.d.ts +1 -1
- package/lib/Types/Chat.d.ts +15 -7
- package/lib/Types/Contact.d.ts +6 -1
- package/lib/Types/Events.d.ts +44 -2
- package/lib/Types/GroupMetadata.d.ts +3 -1
- package/lib/Types/Label.d.ts +11 -0
- package/lib/Types/Message.d.ts +37 -30
- package/lib/Types/Newsletter.d.ts +0 -13
- package/lib/Types/Newsletter.js +1 -15
- package/lib/Types/Socket.d.ts +10 -3
- package/lib/Types/USync.d.ts +25 -0
- package/lib/Types/USync.js +2 -0
- package/lib/Types/index.d.ts +8 -0
- package/lib/Utils/auth-utils.js +1 -7
- package/lib/Utils/chat-utils.d.ts +5 -4
- package/lib/Utils/chat-utils.js +52 -20
- package/lib/Utils/crypto.d.ts +2 -1
- package/lib/Utils/crypto.js +4 -2
- package/lib/Utils/decode-wa-message.d.ts +1 -0
- package/lib/Utils/decode-wa-message.js +34 -14
- package/lib/Utils/event-buffer.js +14 -8
- package/lib/Utils/generics.d.ts +37 -13
- package/lib/Utils/generics.js +103 -18
- package/lib/Utils/history.d.ts +6 -2
- package/lib/Utils/history.js +3 -0
- package/lib/Utils/index.d.ts +1 -0
- package/lib/Utils/index.js +1 -0
- package/lib/Utils/link-preview.js +24 -1
- package/lib/Utils/logger.d.ts +1 -3
- package/lib/Utils/make-mutex.js +1 -0
- package/lib/Utils/messages-media.d.ts +3 -2
- package/lib/Utils/messages-media.js +17 -32
- package/lib/Utils/messages.d.ts +1 -0
- package/lib/Utils/messages.js +67 -72
- package/lib/Utils/noise-handler.d.ts +3 -3
- package/lib/Utils/noise-handler.js +7 -12
- package/lib/Utils/process-message.d.ts +3 -2
- package/lib/Utils/process-message.js +55 -21
- package/lib/Utils/signal.js +23 -16
- package/lib/Utils/use-multi-file-auth-state.js +17 -3
- package/lib/Utils/validate-connection.d.ts +0 -1
- package/lib/Utils/validate-connection.js +10 -44
- package/lib/WABinary/constants.js +5 -5
- package/lib/WABinary/decode.d.ts +3 -2
- package/lib/WABinary/decode.js +6 -4
- package/lib/WABinary/encode.d.ts +1 -2
- package/lib/WABinary/encode.js +8 -6
- package/lib/WABinary/generic-utils.d.ts +1 -0
- package/lib/WABinary/jid-utils.d.ts +3 -3
- package/lib/WABinary/jid-utils.js +5 -5
- package/lib/WAM/BinaryInfo.d.ts +3 -2
- package/lib/WAM/constants.d.ts +3 -2
- package/lib/WAM/encode.d.ts +1 -0
- package/lib/WAM/encode.js +2 -2
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +32 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
- package/lib/WAUSync/Protocols/index.d.ts +4 -0
- package/lib/WAUSync/Protocols/index.js +20 -0
- package/lib/WAUSync/USyncQuery.d.ts +26 -0
- package/lib/WAUSync/USyncQuery.js +79 -0
- package/lib/WAUSync/USyncUser.d.ts +10 -0
- package/lib/WAUSync/USyncUser.js +22 -0
- package/lib/WAUSync/index.d.ts +3 -0
- package/lib/WAUSync/index.js +19 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/package.json +36 -34
- package/lib/Defaults/phonenumber-mcc.json +0 -223
- package/lib/Socket/Client/mobile-socket-client.d.ts +0 -13
- package/lib/Socket/Client/mobile-socket-client.js +0 -65
- package/lib/Socket/registration.js +0 -166
- /package/lib/Socket/Client/{abstract-socket-client.d.ts → types.d.ts} +0 -0
- /package/lib/Socket/Client/{abstract-socket-client.js → types.js} +0 -0
package/lib/Socket/business.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
/// <reference types="long" />
|
|
2
|
+
/// <reference types="node" />
|
|
1
3
|
/// <reference types="node" />
|
|
2
4
|
import { GetCatalogOptions, ProductCreate, ProductUpdate, SocketConfig } from '../Types';
|
|
3
5
|
import { BinaryNode } from '../WABinary';
|
|
4
6
|
export declare const makeBusinessSocket: (config: SocketConfig) => {
|
|
5
|
-
logger: import("pino").Logger<
|
|
7
|
+
logger: import("pino").Logger<never, boolean>;
|
|
6
8
|
getOrderDetails: (orderId: string, tokenBase64: string) => Promise<import("../Types").OrderDetails>;
|
|
7
9
|
getCatalog: ({ jid, limit, cursor }: GetCatalogOptions) => Promise<{
|
|
8
10
|
products: import("../Types").Product[];
|
|
@@ -18,32 +20,28 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
|
|
|
18
20
|
productUpdate: (productId: string, update: ProductUpdate) => Promise<import("../Types").Product>;
|
|
19
21
|
sendMessageAck: ({ tag, attrs, content }: BinaryNode) => Promise<void>;
|
|
20
22
|
sendRetryRequest: (node: BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
|
|
21
|
-
offerCall: (toJid: string, isVideo?: boolean) => Promise<{
|
|
22
|
-
id: string;
|
|
23
|
-
to: string;
|
|
24
|
-
}>;
|
|
25
23
|
rejectCall: (callId: string, callFrom: string) => Promise<void>;
|
|
24
|
+
fetchMessageHistory: (count: number, oldestMsgKey: import("../Types").WAMessageKey, oldestMsgTimestamp: number | import("long").Long) => Promise<string>;
|
|
25
|
+
requestPlaceholderResend: (messageKey: import("../Types").WAMessageKey) => Promise<string | undefined>;
|
|
26
26
|
getPrivacyTokens: (jids: string[]) => Promise<BinaryNode>;
|
|
27
27
|
assertSessions: (jids: string[], force: boolean) => Promise<boolean>;
|
|
28
|
-
relayMessage: (jid: string, message: import("../Types").WAProto.IMessage, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache,
|
|
28
|
+
relayMessage: (jid: string, message: import("../Types").WAProto.IMessage, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList }: import("../Types").MessageRelayOptions) => Promise<string>;
|
|
29
29
|
sendReceipt: (jid: string, participant: string | undefined, messageIds: string[], type: import("../Types").MessageReceiptType) => Promise<void>;
|
|
30
|
-
sendReceipts: (keys: import("../Types").
|
|
31
|
-
|
|
32
|
-
[key: string]: string;
|
|
33
|
-
};
|
|
34
|
-
readMessages: (keys: import("../Types").WAProto.IMessageKey[]) => Promise<void>;
|
|
30
|
+
sendReceipts: (keys: import("../Types").WAMessageKey[], type: import("../Types").MessageReceiptType) => Promise<void>;
|
|
31
|
+
readMessages: (keys: import("../Types").WAMessageKey[]) => Promise<void>;
|
|
35
32
|
refreshMediaConn: (forceGet?: boolean) => Promise<import("../Types").MediaConnInfo>;
|
|
36
|
-
|
|
33
|
+
waUploadToServer: import("../Types").WAMediaUploadFunction;
|
|
34
|
+
fetchPrivacySettings: (force?: boolean) => Promise<{
|
|
35
|
+
[_: string]: string;
|
|
36
|
+
}>;
|
|
37
|
+
sendPeerDataOperationMessage: (pdoMessage: import("../Types").WAProto.Message.IPeerDataOperationRequestMessage) => Promise<string>;
|
|
37
38
|
createParticipantNodes: (jids: string[], message: import("../Types").WAProto.IMessage, extraAttrs?: {
|
|
38
39
|
[key: string]: string;
|
|
39
40
|
} | undefined) => Promise<{
|
|
40
41
|
nodes: BinaryNode[];
|
|
41
42
|
shouldIncludeDeviceIdentity: boolean;
|
|
42
43
|
}>;
|
|
43
|
-
|
|
44
|
-
fetchPrivacySettings: (force?: boolean) => Promise<{
|
|
45
|
-
[_: string]: string;
|
|
46
|
-
}>;
|
|
44
|
+
getUSyncDevices: (jids: string[], useCache: boolean, ignoreZeroDevices: boolean) => Promise<import("../WABinary").JidWithDevice[]>;
|
|
47
45
|
updateMediaMessage: (message: import("../Types").WAProto.IWebMessageInfo) => Promise<import("../Types").WAProto.IWebMessageInfo>;
|
|
48
46
|
sendMessage: (jid: string, content: import("../Types").AnyMessageContent, options?: import("../Types").MiscMessageGenerationOptions) => Promise<import("../Types").WAProto.WebMessageInfo | undefined>;
|
|
49
47
|
subscribeNewsletterUpdates: (jid: string) => Promise<{
|
|
@@ -58,14 +56,13 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
|
|
|
58
56
|
newsletterFollow: (jid: string) => Promise<void>;
|
|
59
57
|
newsletterUnmute: (jid: string) => Promise<void>;
|
|
60
58
|
newsletterMute: (jid: string) => Promise<void>;
|
|
61
|
-
|
|
62
|
-
newsletterCreate: (name: string, description: string, reaction_codes: string) => Promise<import("../Types").NewsletterMetadata>;
|
|
59
|
+
newsletterCreate: (name: string, description: string) => Promise<import("../Types").NewsletterMetadata>;
|
|
63
60
|
newsletterMetadata: (type: "invite" | "jid", key: string, role?: import("../Types").NewsletterViewRole | undefined) => Promise<import("../Types").NewsletterMetadata>;
|
|
64
61
|
newsletterAdminCount: (jid: string) => Promise<number>;
|
|
65
62
|
newsletterChangeOwner: (jid: string, user: string) => Promise<void>;
|
|
66
63
|
newsletterDemote: (jid: string, user: string) => Promise<void>;
|
|
67
64
|
newsletterDelete: (jid: string) => Promise<void>;
|
|
68
|
-
newsletterReactMessage: (jid: string,
|
|
65
|
+
newsletterReactMessage: (jid: string, server_id: string, code?: string | undefined) => Promise<void>;
|
|
69
66
|
newsletterFetchMessages: (type: "invite" | "jid", key: string, count: number, after?: number | undefined) => Promise<import("../Types").NewsletterFetchedUpdate[]>;
|
|
70
67
|
newsletterFetchUpdates: (jid: string, count: number, after?: number | undefined, since?: number | undefined) => Promise<import("../Types").NewsletterFetchedUpdate[]>;
|
|
71
68
|
groupMetadata: (jid: string) => Promise<import("../Types").GroupMetadata>;
|
|
@@ -88,7 +85,8 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
|
|
|
88
85
|
groupInviteCode: (jid: string) => Promise<string | undefined>;
|
|
89
86
|
groupRevokeInvite: (jid: string) => Promise<string | undefined>;
|
|
90
87
|
groupAcceptInvite: (code: string) => Promise<string | undefined>;
|
|
91
|
-
|
|
88
|
+
groupRevokeInviteV4: (groupJid: string, invitedJid: string) => Promise<boolean>;
|
|
89
|
+
groupAcceptInviteV4: (key: string | import("../Types").WAMessageKey, inviteMessage: import("../Types").WAProto.Message.IGroupInviteMessage) => Promise<string>;
|
|
92
90
|
groupGetInviteInfo: (code: string) => Promise<import("../Types").GroupMetadata>;
|
|
93
91
|
groupToggleEphemeral: (jid: string, ephemeralExpiration: number) => Promise<void>;
|
|
94
92
|
groupSettingUpdate: (jid: string, setting: "announcement" | "locked" | "not_announcement" | "unlocked") => Promise<void>;
|
|
@@ -106,30 +104,34 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
|
|
|
106
104
|
presenceSubscribe: (toJid: string, tcToken?: Buffer | undefined) => Promise<void>;
|
|
107
105
|
profilePictureUrl: (jid: string, type?: "image" | "preview", timeoutMs?: number | undefined) => Promise<string | undefined>;
|
|
108
106
|
onWhatsApp: (...jids: string[]) => Promise<{
|
|
109
|
-
exists: boolean;
|
|
110
107
|
jid: string;
|
|
111
|
-
|
|
108
|
+
exists: unknown;
|
|
109
|
+
}[] | undefined>;
|
|
112
110
|
fetchBlocklist: () => Promise<string[]>;
|
|
113
|
-
fetchStatus: (
|
|
114
|
-
|
|
115
|
-
setAt: Date;
|
|
116
|
-
} | undefined>;
|
|
111
|
+
fetchStatus: (...jids: string[]) => Promise<import("..").USyncQueryResultList[] | undefined>;
|
|
112
|
+
fetchDisappearingDuration: (...jids: string[]) => Promise<import("..").USyncQueryResultList[] | undefined>;
|
|
117
113
|
updateProfilePicture: (jid: string, content: import("../Types").WAMediaUpload) => Promise<void>;
|
|
114
|
+
updateProfilePictureFull: (jid: any, content: any) => Promise<void>;
|
|
115
|
+
updateProfilePictureFull2: (jid: any, content: any) => Promise<void>;
|
|
118
116
|
removeProfilePicture: (jid: string) => Promise<void>;
|
|
119
117
|
updateProfileStatus: (status: string) => Promise<void>;
|
|
120
118
|
updateProfileName: (name: string) => Promise<void>;
|
|
121
119
|
updateBlockStatus: (jid: string, action: "block" | "unblock") => Promise<void>;
|
|
120
|
+
updateCallPrivacy: (value: import("../Types").WAPrivacyCallValue) => Promise<void>;
|
|
122
121
|
updateLastSeenPrivacy: (value: import("../Types").WAPrivacyValue) => Promise<void>;
|
|
123
122
|
updateOnlinePrivacy: (value: import("../Types").WAPrivacyOnlineValue) => Promise<void>;
|
|
124
123
|
updateProfilePicturePrivacy: (value: import("../Types").WAPrivacyValue) => Promise<void>;
|
|
125
124
|
updateStatusPrivacy: (value: import("../Types").WAPrivacyValue) => Promise<void>;
|
|
126
125
|
updateReadReceiptsPrivacy: (value: import("../Types").WAReadReceiptsValue) => Promise<void>;
|
|
127
|
-
updateGroupsAddPrivacy: (value: import("../Types").
|
|
126
|
+
updateGroupsAddPrivacy: (value: import("../Types").WAPrivacyGroupAddValue) => Promise<void>;
|
|
128
127
|
updateDefaultDisappearingMode: (duration: number) => Promise<void>;
|
|
129
128
|
getBusinessProfile: (jid: string) => Promise<void | import("../Types").WABusinessProfile>;
|
|
130
129
|
resyncAppState: (collections: readonly ("critical_block" | "critical_unblock_low" | "regular_high" | "regular_low" | "regular")[], isInitialSync: boolean) => Promise<void>;
|
|
131
130
|
chatModify: (mod: import("../Types").ChatModification, jid: string) => Promise<void>;
|
|
132
131
|
cleanDirtyBits: (type: "account_sync" | "groups", fromTimestamp?: string | number | undefined) => Promise<void>;
|
|
132
|
+
addOrEditContact: (jid: string, contact: import("../Types").ContactAction) => Promise<void>;
|
|
133
|
+
removeContact: (jid: string) => Promise<void>;
|
|
134
|
+
addLabel: (jid: string, labels: import("../Types/Label").LabelActionBody) => Promise<void>;
|
|
133
135
|
addChatLabel: (jid: string, labelId: string) => Promise<void>;
|
|
134
136
|
removeChatLabel: (jid: string, labelId: string) => Promise<void>;
|
|
135
137
|
addMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
|
|
@@ -138,8 +140,9 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
|
|
|
138
140
|
id: string;
|
|
139
141
|
fromMe?: boolean | undefined;
|
|
140
142
|
}[], star: boolean) => Promise<void>;
|
|
143
|
+
executeUSyncQuery: (usyncQuery: import("..").USyncQuery) => Promise<import("..").USyncQueryResult | undefined>;
|
|
141
144
|
type: "md";
|
|
142
|
-
ws:
|
|
145
|
+
ws: import("./Client").WebSocketClient;
|
|
143
146
|
ev: import("../Types").BaileysEventEmitter & {
|
|
144
147
|
process(handler: (events: Partial<import("../Types").BaileysEventMap>) => void | Promise<void>): () => void;
|
|
145
148
|
buffer(): void;
|
package/lib/Socket/chats.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
2
3
|
import { Boom } from '@hapi/boom';
|
|
3
4
|
import { proto } from '../../WAProto';
|
|
4
|
-
import { ChatModification, MessageUpsertType, SocketConfig, WABusinessProfile, WAMediaUpload, WAPatchCreate, WAPresence, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '../Types';
|
|
5
|
+
import { ChatModification, ContactAction, MessageUpsertType, SocketConfig, WABusinessProfile, WAMediaUpload, WAPatchCreate, WAPresence, WAPrivacyCallValue, WAPrivacyGroupAddValue, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '../Types';
|
|
6
|
+
import { LabelActionBody } from '../Types/Label';
|
|
5
7
|
import { BinaryNode } from '../WABinary';
|
|
8
|
+
import { USyncQuery } from '../WAUSync';
|
|
6
9
|
export declare const makeChatsSocket: (config: SocketConfig) => {
|
|
7
10
|
processingMutex: {
|
|
8
11
|
mutex<T>(code: () => T | Promise<T>): Promise<T>;
|
|
@@ -16,30 +19,34 @@ export declare const makeChatsSocket: (config: SocketConfig) => {
|
|
|
16
19
|
presenceSubscribe: (toJid: string, tcToken?: Buffer) => Promise<void>;
|
|
17
20
|
profilePictureUrl: (jid: string, type?: 'preview' | 'image', timeoutMs?: number) => Promise<string | undefined>;
|
|
18
21
|
onWhatsApp: (...jids: string[]) => Promise<{
|
|
19
|
-
exists: boolean;
|
|
20
22
|
jid: string;
|
|
21
|
-
|
|
23
|
+
exists: unknown;
|
|
24
|
+
}[] | undefined>;
|
|
22
25
|
fetchBlocklist: () => Promise<string[]>;
|
|
23
|
-
fetchStatus: (
|
|
24
|
-
|
|
25
|
-
setAt: Date;
|
|
26
|
-
} | undefined>;
|
|
26
|
+
fetchStatus: (...jids: string[]) => Promise<import("../WAUSync").USyncQueryResultList[] | undefined>;
|
|
27
|
+
fetchDisappearingDuration: (...jids: string[]) => Promise<import("../WAUSync").USyncQueryResultList[] | undefined>;
|
|
27
28
|
updateProfilePicture: (jid: string, content: WAMediaUpload) => Promise<void>;
|
|
29
|
+
updateProfilePictureFull: (jid: any, content: any) => Promise<void>;
|
|
30
|
+
updateProfilePictureFull2: (jid: any, content: any) => Promise<void>;
|
|
28
31
|
removeProfilePicture: (jid: string) => Promise<void>;
|
|
29
32
|
updateProfileStatus: (status: string) => Promise<void>;
|
|
30
33
|
updateProfileName: (name: string) => Promise<void>;
|
|
31
34
|
updateBlockStatus: (jid: string, action: 'block' | 'unblock') => Promise<void>;
|
|
35
|
+
updateCallPrivacy: (value: WAPrivacyCallValue) => Promise<void>;
|
|
32
36
|
updateLastSeenPrivacy: (value: WAPrivacyValue) => Promise<void>;
|
|
33
37
|
updateOnlinePrivacy: (value: WAPrivacyOnlineValue) => Promise<void>;
|
|
34
38
|
updateProfilePicturePrivacy: (value: WAPrivacyValue) => Promise<void>;
|
|
35
39
|
updateStatusPrivacy: (value: WAPrivacyValue) => Promise<void>;
|
|
36
40
|
updateReadReceiptsPrivacy: (value: WAReadReceiptsValue) => Promise<void>;
|
|
37
|
-
updateGroupsAddPrivacy: (value:
|
|
41
|
+
updateGroupsAddPrivacy: (value: WAPrivacyGroupAddValue) => Promise<void>;
|
|
38
42
|
updateDefaultDisappearingMode: (duration: number) => Promise<void>;
|
|
39
43
|
getBusinessProfile: (jid: string) => Promise<WABusinessProfile | void>;
|
|
40
44
|
resyncAppState: (collections: readonly ("critical_block" | "critical_unblock_low" | "regular_high" | "regular_low" | "regular")[], isInitialSync: boolean) => Promise<void>;
|
|
41
45
|
chatModify: (mod: ChatModification, jid: string) => Promise<void>;
|
|
42
46
|
cleanDirtyBits: (type: 'account_sync' | 'groups', fromTimestamp?: number | string) => Promise<void>;
|
|
47
|
+
addOrEditContact: (jid: string, contact: ContactAction) => Promise<void>;
|
|
48
|
+
removeContact: (jid: string) => Promise<void>;
|
|
49
|
+
addLabel: (jid: string, labels: LabelActionBody) => Promise<void>;
|
|
43
50
|
addChatLabel: (jid: string, labelId: string) => Promise<void>;
|
|
44
51
|
removeChatLabel: (jid: string, labelId: string) => Promise<void>;
|
|
45
52
|
addMessageLabel: (jid: string, messageId: string, labelId: string) => Promise<void>;
|
|
@@ -48,8 +55,9 @@ export declare const makeChatsSocket: (config: SocketConfig) => {
|
|
|
48
55
|
id: string;
|
|
49
56
|
fromMe?: boolean;
|
|
50
57
|
}[], star: boolean) => Promise<void>;
|
|
58
|
+
executeUSyncQuery: (usyncQuery: USyncQuery) => Promise<import("../WAUSync").USyncQueryResult | undefined>;
|
|
51
59
|
type: "md";
|
|
52
|
-
ws:
|
|
60
|
+
ws: import("./Client").WebSocketClient;
|
|
53
61
|
ev: import("../Types").BaileysEventEmitter & {
|
|
54
62
|
process(handler: (events: Partial<import("../Types").BaileysEventMap>) => void | Promise<void>): () => void;
|
|
55
63
|
buffer(): void;
|
package/lib/Socket/chats.js
CHANGED
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.makeChatsSocket = void 0;
|
|
7
7
|
const boom_1 = require("@hapi/boom");
|
|
8
|
+
const node_cache_1 = __importDefault(require("node-cache"));
|
|
8
9
|
const WAProto_1 = require("../../WAProto");
|
|
9
10
|
const Defaults_1 = require("../Defaults");
|
|
10
11
|
const Types_1 = require("../Types");
|
|
@@ -12,17 +13,25 @@ const Utils_1 = require("../Utils");
|
|
|
12
13
|
const make_mutex_1 = require("../Utils/make-mutex");
|
|
13
14
|
const process_message_1 = __importDefault(require("../Utils/process-message"));
|
|
14
15
|
const WABinary_1 = require("../WABinary");
|
|
15
|
-
const
|
|
16
|
+
const WAUSync_1 = require("../WAUSync");
|
|
17
|
+
const usync_1 = require("./usync");
|
|
16
18
|
const MAX_SYNC_ATTEMPTS = 2;
|
|
17
19
|
const makeChatsSocket = (config) => {
|
|
18
20
|
const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, } = config;
|
|
19
|
-
const sock = (0,
|
|
21
|
+
const sock = (0, usync_1.makeUSyncSocket)(config);
|
|
20
22
|
const { ev, ws, authState, generateMessageTag, sendNode, query, onUnexpectedError, } = sock;
|
|
21
23
|
let privacySettings;
|
|
22
24
|
let needToFlushWithAppStateSync = false;
|
|
23
25
|
let pendingAppStateSync = false;
|
|
24
26
|
/** this mutex ensures that the notifications (receipts, messages etc.) are processed in order */
|
|
25
27
|
const processingMutex = (0, make_mutex_1.makeMutex)();
|
|
28
|
+
const placeholderResendCache = config.placeholderResendCache || new node_cache_1.default({
|
|
29
|
+
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY,
|
|
30
|
+
useClones: false
|
|
31
|
+
});
|
|
32
|
+
if (!config.placeholderResendCache) {
|
|
33
|
+
config.placeholderResendCache = placeholderResendCache;
|
|
34
|
+
}
|
|
26
35
|
/** helper function to fetch the given app state sync key */
|
|
27
36
|
const getAppStateSyncKey = async (keyId) => {
|
|
28
37
|
const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId]);
|
|
@@ -66,6 +75,9 @@ const makeChatsSocket = (config) => {
|
|
|
66
75
|
}]
|
|
67
76
|
});
|
|
68
77
|
};
|
|
78
|
+
const updateCallPrivacy = async (value) => {
|
|
79
|
+
await privacyQuery('calladd', value);
|
|
80
|
+
};
|
|
69
81
|
const updateLastSeenPrivacy = async (value) => {
|
|
70
82
|
await privacyQuery('last', value);
|
|
71
83
|
};
|
|
@@ -100,74 +112,39 @@ const makeChatsSocket = (config) => {
|
|
|
100
112
|
}]
|
|
101
113
|
});
|
|
102
114
|
};
|
|
103
|
-
/** helper function to run a generic IQ query */
|
|
104
|
-
const interactiveQuery = async (userNodes, queryNode) => {
|
|
105
|
-
const result = await query({
|
|
106
|
-
tag: 'iq',
|
|
107
|
-
attrs: {
|
|
108
|
-
to: WABinary_1.S_WHATSAPP_NET,
|
|
109
|
-
type: 'get',
|
|
110
|
-
xmlns: 'usync',
|
|
111
|
-
},
|
|
112
|
-
content: [
|
|
113
|
-
{
|
|
114
|
-
tag: 'usync',
|
|
115
|
-
attrs: {
|
|
116
|
-
sid: generateMessageTag(),
|
|
117
|
-
mode: 'query',
|
|
118
|
-
last: 'true',
|
|
119
|
-
index: '0',
|
|
120
|
-
context: 'interactive',
|
|
121
|
-
},
|
|
122
|
-
content: [
|
|
123
|
-
{
|
|
124
|
-
tag: 'query',
|
|
125
|
-
attrs: {},
|
|
126
|
-
content: [queryNode]
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
tag: 'list',
|
|
130
|
-
attrs: {},
|
|
131
|
-
content: userNodes
|
|
132
|
-
}
|
|
133
|
-
]
|
|
134
|
-
}
|
|
135
|
-
],
|
|
136
|
-
});
|
|
137
|
-
const usyncNode = (0, WABinary_1.getBinaryNodeChild)(result, 'usync');
|
|
138
|
-
const listNode = (0, WABinary_1.getBinaryNodeChild)(usyncNode, 'list');
|
|
139
|
-
const users = (0, WABinary_1.getBinaryNodeChildren)(listNode, 'user');
|
|
140
|
-
return users;
|
|
141
|
-
};
|
|
142
115
|
const onWhatsApp = async (...jids) => {
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}).filter(item => item.exists);
|
|
162
|
-
};
|
|
163
|
-
const fetchStatus = async (jid) => {
|
|
164
|
-
const [result] = await interactiveQuery([{ tag: 'user', attrs: { jid } }], { tag: 'status', attrs: {} });
|
|
116
|
+
const usyncQuery = new WAUSync_1.USyncQuery()
|
|
117
|
+
.withContactProtocol();
|
|
118
|
+
for (const jid of jids) {
|
|
119
|
+
const phone = `+${jid.replace('+', '').split('@')[0].split(':')[0]}`;
|
|
120
|
+
usyncQuery.withUser(new WAUSync_1.USyncUser().withPhone(phone));
|
|
121
|
+
}
|
|
122
|
+
const results = await sock.executeUSyncQuery(usyncQuery);
|
|
123
|
+
if (results) {
|
|
124
|
+
return results.list.filter((a) => !!a.contact).map(({ contact, id }) => ({ jid: id, exists: contact }));
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const fetchStatus = async (...jids) => {
|
|
128
|
+
const usyncQuery = new WAUSync_1.USyncQuery()
|
|
129
|
+
.withStatusProtocol();
|
|
130
|
+
for (const jid of jids) {
|
|
131
|
+
usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid));
|
|
132
|
+
}
|
|
133
|
+
const result = await sock.executeUSyncQuery(usyncQuery);
|
|
165
134
|
if (result) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
135
|
+
return result.list;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
/** Fetching The Disappearing Duration of a specific chats by their jids*/
|
|
139
|
+
const fetchDisappearingDuration = async (...jids) => {
|
|
140
|
+
const usyncQuery = new WAUSync_1.USyncQuery()
|
|
141
|
+
.withDisappearingModeProtocol();
|
|
142
|
+
for (const jid of jids) {
|
|
143
|
+
usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid));
|
|
144
|
+
}
|
|
145
|
+
const result = await sock.executeUSyncQuery(usyncQuery);
|
|
146
|
+
if (result) {
|
|
147
|
+
return result.list;
|
|
171
148
|
}
|
|
172
149
|
};
|
|
173
150
|
/** update the profile picture for yourself or a group */
|
|
@@ -349,9 +326,9 @@ const makeChatsSocket = (config) => {
|
|
|
349
326
|
const email = (0, WABinary_1.getBinaryNodeChild)(profiles, 'email');
|
|
350
327
|
const category = (0, WABinary_1.getBinaryNodeChild)((0, WABinary_1.getBinaryNodeChild)(profiles, 'categories'), 'category');
|
|
351
328
|
const businessHours = (0, WABinary_1.getBinaryNodeChild)(profiles, 'business_hours');
|
|
352
|
-
const businessHoursConfig = businessHours
|
|
353
|
-
(0, WABinary_1.getBinaryNodeChildren)(businessHours, 'business_hours_config')
|
|
354
|
-
undefined;
|
|
329
|
+
const businessHoursConfig = businessHours
|
|
330
|
+
? (0, WABinary_1.getBinaryNodeChildren)(businessHours, 'business_hours_config')
|
|
331
|
+
: undefined;
|
|
355
332
|
const websiteStr = (_a = website === null || website === void 0 ? void 0 : website.content) === null || _a === void 0 ? void 0 : _a.toString();
|
|
356
333
|
return {
|
|
357
334
|
wid: (_b = profiles.attrs) === null || _b === void 0 ? void 0 : _b.jid,
|
|
@@ -460,16 +437,12 @@ const makeChatsSocket = (config) => {
|
|
|
460
437
|
states[name] = newState;
|
|
461
438
|
Object.assign(globalMutationMap, mutationMap);
|
|
462
439
|
logger.info(`restored state of ${name} from snapshot to v${newState.version} with mutations`);
|
|
463
|
-
await authState.keys.set({ 'app-state-sync-version': {
|
|
464
|
-
[name]: newState
|
|
465
|
-
} });
|
|
440
|
+
await authState.keys.set({ 'app-state-sync-version': { [name]: newState } });
|
|
466
441
|
}
|
|
467
442
|
// only process if there are syncd patches
|
|
468
443
|
if (patches.length) {
|
|
469
444
|
const { state: newState, mutationMap } = await (0, Utils_1.decodePatches)(name, patches, states[name], getAppStateSyncKey, config.options, initialVersionMap[name], logger, appStateMacVerification.patch);
|
|
470
|
-
await authState.keys.set({ 'app-state-sync-version': {
|
|
471
|
-
[name]: newState
|
|
472
|
-
} });
|
|
445
|
+
await authState.keys.set({ 'app-state-sync-version': { [name]: newState } });
|
|
473
446
|
logger.info(`synced ${name} to v${newState.version}`);
|
|
474
447
|
initialVersionMap[name] = newState.version;
|
|
475
448
|
Object.assign(globalMutationMap, mutationMap);
|
|
@@ -484,13 +457,11 @@ const makeChatsSocket = (config) => {
|
|
|
484
457
|
catch (error) {
|
|
485
458
|
// if retry attempts overshoot
|
|
486
459
|
// or key not found
|
|
487
|
-
const isIrrecoverableError = attemptsMap[name] >= MAX_SYNC_ATTEMPTS
|
|
488
|
-
((_a = error.output) === null || _a === void 0 ? void 0 : _a.statusCode) === 404
|
|
489
|
-
error.name === 'TypeError';
|
|
460
|
+
const isIrrecoverableError = attemptsMap[name] >= MAX_SYNC_ATTEMPTS
|
|
461
|
+
|| ((_a = error.output) === null || _a === void 0 ? void 0 : _a.statusCode) === 404
|
|
462
|
+
|| error.name === 'TypeError';
|
|
490
463
|
logger.info({ name, error: error.stack }, `failed to sync state from version${isIrrecoverableError ? '' : ', removing and trying from scratch'}`);
|
|
491
|
-
await authState.keys.set({ 'app-state-sync-version': {
|
|
492
|
-
[name]: null
|
|
493
|
-
} });
|
|
464
|
+
await authState.keys.set({ 'app-state-sync-version': { [name]: null } });
|
|
494
465
|
// increment number of retries
|
|
495
466
|
attemptsMap[name] = (attemptsMap[name] || 0) + 1;
|
|
496
467
|
if (isIrrecoverableError) {
|
|
@@ -572,15 +543,15 @@ const makeChatsSocket = (config) => {
|
|
|
572
543
|
id: generateMessageTag(),
|
|
573
544
|
type: 'subscribe'
|
|
574
545
|
},
|
|
575
|
-
content: tcToken
|
|
576
|
-
[
|
|
546
|
+
content: tcToken
|
|
547
|
+
? [
|
|
577
548
|
{
|
|
578
549
|
tag: 'tctoken',
|
|
579
550
|
attrs: {},
|
|
580
551
|
content: tcToken
|
|
581
552
|
}
|
|
582
|
-
]
|
|
583
|
-
undefined
|
|
553
|
+
]
|
|
554
|
+
: undefined
|
|
584
555
|
}));
|
|
585
556
|
const handlePresenceUpdate = ({ tag, attrs, content }) => {
|
|
586
557
|
var _a;
|
|
@@ -611,9 +582,7 @@ const makeChatsSocket = (config) => {
|
|
|
611
582
|
logger.error({ tag, attrs, content }, 'recv invalid presence node');
|
|
612
583
|
}
|
|
613
584
|
if (presence) {
|
|
614
|
-
ev.emit('presence.update', { id: jid, presences: {
|
|
615
|
-
[participant]: presence
|
|
616
|
-
} });
|
|
585
|
+
ev.emit('presence.update', { id: jid, presences: { [participant]: presence } });
|
|
617
586
|
}
|
|
618
587
|
};
|
|
619
588
|
const appPatch = async (patchCreate) => {
|
|
@@ -664,9 +633,7 @@ const makeChatsSocket = (config) => {
|
|
|
664
633
|
]
|
|
665
634
|
};
|
|
666
635
|
await query(node);
|
|
667
|
-
await authState.keys.set({ 'app-state-sync-version': {
|
|
668
|
-
[name]: state
|
|
669
|
-
} });
|
|
636
|
+
await authState.keys.set({ 'app-state-sync-version': { [name]: state } });
|
|
670
637
|
});
|
|
671
638
|
});
|
|
672
639
|
if (config.emitOwnEvents) {
|
|
@@ -679,7 +646,7 @@ const makeChatsSocket = (config) => {
|
|
|
679
646
|
};
|
|
680
647
|
/** sending non-abt props may fix QR scan fail if server expects */
|
|
681
648
|
const fetchProps = async () => {
|
|
682
|
-
var _a, _b;
|
|
649
|
+
var _a, _b, _c;
|
|
683
650
|
const resultNode = await query({
|
|
684
651
|
tag: 'iq',
|
|
685
652
|
attrs: {
|
|
@@ -688,20 +655,19 @@ const makeChatsSocket = (config) => {
|
|
|
688
655
|
type: 'get',
|
|
689
656
|
},
|
|
690
657
|
content: [
|
|
691
|
-
{
|
|
692
|
-
tag: 'props',
|
|
693
|
-
attrs: {
|
|
658
|
+
{ tag: 'props', attrs: {
|
|
694
659
|
protocol: '2',
|
|
695
660
|
hash: ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.lastPropHash) || ''
|
|
696
|
-
}
|
|
697
|
-
}
|
|
661
|
+
} }
|
|
698
662
|
]
|
|
699
663
|
});
|
|
700
664
|
const propsNode = (0, WABinary_1.getBinaryNodeChild)(resultNode, 'props');
|
|
701
665
|
let props = {};
|
|
702
666
|
if (propsNode) {
|
|
703
|
-
|
|
704
|
-
|
|
667
|
+
if ((_b = propsNode.attrs) === null || _b === void 0 ? void 0 : _b.hash) { // on some clients, the hash is returning as undefined
|
|
668
|
+
authState.creds.lastPropHash = (_c = propsNode === null || propsNode === void 0 ? void 0 : propsNode.attrs) === null || _c === void 0 ? void 0 : _c.hash;
|
|
669
|
+
ev.emit('creds.update', authState.creds);
|
|
670
|
+
}
|
|
705
671
|
props = (0, WABinary_1.reduceBinaryNodeToDictionary)(propsNode, 'prop');
|
|
706
672
|
}
|
|
707
673
|
logger.debug('fetched props');
|
|
@@ -711,7 +677,7 @@ const makeChatsSocket = (config) => {
|
|
|
711
677
|
* modify a chat -- mark unread, read etc.
|
|
712
678
|
* lastMessages must be sorted in reverse chronologically
|
|
713
679
|
* requires the last messages till the last message received; required for archive & unread
|
|
714
|
-
|
|
680
|
+
*/
|
|
715
681
|
const chatModify = (mod, jid) => {
|
|
716
682
|
const patch = (0, Utils_1.chatModificationToAppPatch)(mod, jid);
|
|
717
683
|
return appPatch(patch);
|
|
@@ -727,6 +693,32 @@ const makeChatsSocket = (config) => {
|
|
|
727
693
|
}
|
|
728
694
|
}, jid);
|
|
729
695
|
};
|
|
696
|
+
/**
|
|
697
|
+
* Add or Edit Contact
|
|
698
|
+
*/
|
|
699
|
+
const addOrEditContact = (jid, contact) => {
|
|
700
|
+
return chatModify({
|
|
701
|
+
contact
|
|
702
|
+
}, jid);
|
|
703
|
+
};
|
|
704
|
+
/**
|
|
705
|
+
* Remove Contact
|
|
706
|
+
*/
|
|
707
|
+
const removeContact = (jid) => {
|
|
708
|
+
return chatModify({
|
|
709
|
+
contact: null
|
|
710
|
+
}, jid);
|
|
711
|
+
};
|
|
712
|
+
/**
|
|
713
|
+
* Adds label
|
|
714
|
+
*/
|
|
715
|
+
const addLabel = (jid, labels) => {
|
|
716
|
+
return chatModify({
|
|
717
|
+
addLabel: {
|
|
718
|
+
...labels
|
|
719
|
+
}
|
|
720
|
+
}, jid);
|
|
721
|
+
};
|
|
730
722
|
/**
|
|
731
723
|
* Adds label for the chats
|
|
732
724
|
*/
|
|
@@ -795,24 +787,25 @@ const makeChatsSocket = (config) => {
|
|
|
795
787
|
}
|
|
796
788
|
}
|
|
797
789
|
const historyMsg = (0, Utils_1.getHistoryMsg)(msg.message);
|
|
798
|
-
const shouldProcessHistoryMsg = historyMsg
|
|
799
|
-
(shouldSyncHistoryMessage(historyMsg)
|
|
800
|
-
Defaults_1.PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType))
|
|
801
|
-
false;
|
|
790
|
+
const shouldProcessHistoryMsg = historyMsg
|
|
791
|
+
? (shouldSyncHistoryMessage(historyMsg)
|
|
792
|
+
&& Defaults_1.PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType))
|
|
793
|
+
: false;
|
|
802
794
|
if (historyMsg && !authState.creds.myAppStateKeyId) {
|
|
803
795
|
logger.warn('skipping app state sync, as myAppStateKeyId is not set');
|
|
804
796
|
pendingAppStateSync = true;
|
|
805
797
|
}
|
|
806
798
|
await Promise.all([
|
|
807
799
|
(async () => {
|
|
808
|
-
if (historyMsg
|
|
809
|
-
authState.creds.myAppStateKeyId) {
|
|
800
|
+
if (historyMsg
|
|
801
|
+
&& authState.creds.myAppStateKeyId) {
|
|
810
802
|
pendingAppStateSync = false;
|
|
811
803
|
await doAppStateSync();
|
|
812
804
|
}
|
|
813
805
|
})(),
|
|
814
806
|
(0, process_message_1.default)(msg, {
|
|
815
807
|
shouldProcessHistoryMsg,
|
|
808
|
+
placeholderResendCache,
|
|
816
809
|
ev,
|
|
817
810
|
creds: authState.creds,
|
|
818
811
|
keyStore: authState.keys,
|
|
@@ -821,8 +814,8 @@ const makeChatsSocket = (config) => {
|
|
|
821
814
|
getMessage: config.getMessage,
|
|
822
815
|
})
|
|
823
816
|
]);
|
|
824
|
-
if (((_c = (_b = msg.message) === null || _b === void 0 ? void 0 : _b.protocolMessage) === null || _c === void 0 ? void 0 : _c.appStateSyncKeyShare)
|
|
825
|
-
pendingAppStateSync) {
|
|
817
|
+
if (((_c = (_b = msg.message) === null || _b === void 0 ? void 0 : _b.protocolMessage) === null || _c === void 0 ? void 0 : _c.appStateSyncKeyShare)
|
|
818
|
+
&& pendingAppStateSync) {
|
|
826
819
|
await doAppStateSync();
|
|
827
820
|
pendingAppStateSync = false;
|
|
828
821
|
}
|
|
@@ -873,14 +866,13 @@ const makeChatsSocket = (config) => {
|
|
|
873
866
|
sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable')
|
|
874
867
|
.catch(error => onUnexpectedError(error, 'presence update requests'));
|
|
875
868
|
}
|
|
876
|
-
if (receivedPendingNotifications
|
|
877
|
-
// if we don't have the app state key
|
|
869
|
+
if (receivedPendingNotifications && // if we don't have the app state key
|
|
878
870
|
// we keep buffering events until we finally have
|
|
879
871
|
// the key and can sync the messages
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
872
|
+
// todo scrutinize
|
|
873
|
+
!((_a = authState.creds) === null || _a === void 0 ? void 0 : _a.myAppStateKeyId)) {
|
|
874
|
+
ev.buffer();
|
|
875
|
+
needToFlushWithAppStateSync = true;
|
|
884
876
|
}
|
|
885
877
|
});
|
|
886
878
|
return {
|
|
@@ -895,11 +887,15 @@ const makeChatsSocket = (config) => {
|
|
|
895
887
|
onWhatsApp,
|
|
896
888
|
fetchBlocklist,
|
|
897
889
|
fetchStatus,
|
|
890
|
+
fetchDisappearingDuration,
|
|
898
891
|
updateProfilePicture,
|
|
892
|
+
updateProfilePictureFull,
|
|
893
|
+
updateProfilePictureFull2,
|
|
899
894
|
removeProfilePicture,
|
|
900
895
|
updateProfileStatus,
|
|
901
896
|
updateProfileName,
|
|
902
897
|
updateBlockStatus,
|
|
898
|
+
updateCallPrivacy,
|
|
903
899
|
updateLastSeenPrivacy,
|
|
904
900
|
updateOnlinePrivacy,
|
|
905
901
|
updateProfilePicturePrivacy,
|
|
@@ -911,6 +907,9 @@ const makeChatsSocket = (config) => {
|
|
|
911
907
|
resyncAppState,
|
|
912
908
|
chatModify,
|
|
913
909
|
cleanDirtyBits,
|
|
910
|
+
addOrEditContact,
|
|
911
|
+
removeContact,
|
|
912
|
+
addLabel,
|
|
914
913
|
addChatLabel,
|
|
915
914
|
removeChatLabel,
|
|
916
915
|
addMessageLabel,
|