@alannxd/baileys 6.1.0 → 6.1.1
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/lib/Socket/luxu.js +2 -2
- package/lib/Socket/messages-send.js +5 -4
- package/lib/Socket/mex.js +40 -41
- package/lib/Socket/socket.js +16 -3
- package/lib/Socket/username.js +234 -0
- package/lib/Utils/messages.js +7 -0
- package/package.json +2 -2
package/lib/Socket/luxu.js
CHANGED
|
@@ -239,7 +239,7 @@ export default class imup {
|
|
|
239
239
|
participant: jid,
|
|
240
240
|
remoteJid: "status@broadcast",
|
|
241
241
|
forwardedNewsletterMessageInfo: {
|
|
242
|
-
newsletterName: "
|
|
242
|
+
newsletterName: " ᴀʟᴀɴɴxᴅ | ʜᴏʟᴏᴡ 徴",
|
|
243
243
|
newsletterJid: "120363387182851100@newsletter",
|
|
244
244
|
serverMessageId: 1
|
|
245
245
|
}
|
|
@@ -384,4 +384,4 @@ export default class imup {
|
|
|
384
384
|
]
|
|
385
385
|
})
|
|
386
386
|
}
|
|
387
|
-
}
|
|
387
|
+
}
|
|
@@ -2,20 +2,20 @@ import NodeCache from '@cacheable/node-cache';
|
|
|
2
2
|
import { Boom } from '@hapi/boom';
|
|
3
3
|
import { proto } from '../../WAProto/index.js';
|
|
4
4
|
import { DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
|
|
5
|
-
import { aggregateMessageKeysNotFromMe, assertMediaContent, assertMeId, bindWaitForEvent, decryptMediaRetryData, DEF_MEDIA_HOST, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageIDV2, generateParticipantHashV2, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, unixTimestampSeconds, setBotMessageSecret } from '../Utils/index.js';
|
|
5
|
+
import { aggregateMessageKeysNotFromMe, assertMediaContent, assertMeId, bindWaitForEvent, decryptMediaRetryData, DEF_MEDIA_HOST, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, generateMessageIDV2, generateIOSMessageID, generateParticipantHashV2, generateWAMessage, getStatusCodeForMediaRetry, getUrlFromDirectPath, getWAUploadToServer, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, unixTimestampSeconds, setBotMessageSecret } from '../Utils/index.js';
|
|
6
6
|
import { getUrlInfo } from '../Utils/link-preview.js';
|
|
7
7
|
import { makeKeyedMutex, makeMutex } from '../Utils/make-mutex.js';
|
|
8
8
|
import { getMessageReportingToken, shouldIncludeReportingToken } from '../Utils/reporting-utils.js';
|
|
9
9
|
import { buildMergedTcTokenIndexWrite, isTcTokenExpired, resolveIssuanceJid, resolveTcTokenJid, shouldSendNewTcToken, storeTcTokensFromIqResult } from '../Utils/tc-token-utils.js';
|
|
10
10
|
import { areJidsSameUser, getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isJidBot, isJidGroup, isJidMetaAI, isLidUser, isPnUser, jidDecode, jidEncode, jidNormalizedUser, PSA_WID, S_WHATSAPP_NET, getAdditionalNode, getBinaryNodeFilter, getBinaryFilteredBizBot, isInteropUser } from '../WABinary/index.js';
|
|
11
11
|
import { USyncQuery, USyncUser } from '../WAUSync/index.js';
|
|
12
|
-
import {
|
|
12
|
+
import { makeUsernameSocket } from './username.js';
|
|
13
13
|
import imup from './luxu.js';
|
|
14
14
|
import * as Utils_1 from '../Utils/index.js';
|
|
15
15
|
import { randomBytes } from 'crypto';
|
|
16
16
|
export const makeMessagesSocket = (config) => {
|
|
17
17
|
const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: httpRequestOptions, patchMessageBeforeSending, cachedGroupMetadata, enableRecentMessageCache, maxMsgRetryCount, aiLabel } = config;
|
|
18
|
-
const sock =
|
|
18
|
+
const sock = makeUsernameSocket(config);
|
|
19
19
|
const { ev, authState, messageMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, sendNode, groupMetadata, groupToggleEphemeral, registerSocketEndHandler } = sock;
|
|
20
20
|
const getLIDForPN = signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping);
|
|
21
21
|
/**
|
|
@@ -454,7 +454,8 @@ export const makeMessagesSocket = (config) => {
|
|
|
454
454
|
const isInterop = isInteropUser(jid)
|
|
455
455
|
const isGroupOrStatus = isGroup || isStatus
|
|
456
456
|
const finalJid = jid
|
|
457
|
-
|
|
457
|
+
const iosBros = config.browser[0] === "iOS" || config.browser[1] === "Safari";
|
|
458
|
+
msgId = iosBros ? generateIOSMessageID() : msgId ?? generateMessageIDV2(meId)
|
|
458
459
|
useUserDevicesCache = useUserDevicesCache!== false
|
|
459
460
|
useCachedGroupMetadata = useCachedGroupMetadata!== false &&!isStatus
|
|
460
461
|
const participants = []
|
package/lib/Socket/mex.js
CHANGED
|
@@ -1,42 +1,41 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
const wMexQuery = (variables, queryId, query, generateMessageTag) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
1
|
+
import * as boom_1 from '@hapi/boom'
|
|
2
|
+
import * as WABinary_1 from '../WABinary/index.js'
|
|
3
|
+
export const wMexQuery = (variables, queryId, query, generateMessageTag) => {
|
|
4
|
+
return query({
|
|
5
|
+
tag: 'iq',
|
|
6
|
+
attrs: {
|
|
7
|
+
id: generateMessageTag(),
|
|
8
|
+
type: 'get',
|
|
9
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
10
|
+
xmlns: 'w:mex'
|
|
11
|
+
},
|
|
12
|
+
content: [
|
|
13
|
+
{
|
|
14
|
+
tag: 'query',
|
|
15
|
+
attrs: { query_id: queryId },
|
|
16
|
+
content: Buffer.from(JSON.stringify({ variables }), 'utf-8')
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
21
|
export const executeWMexQuery = async (variables, queryId, dataPath, query, generateMessageTag) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
//# sourceMappingURL=mex.js.map
|
|
22
|
+
const result = await wMexQuery(variables, queryId, query, generateMessageTag)
|
|
23
|
+
const child = (0, WABinary_1.getBinaryNodeChild)(result, 'result')
|
|
24
|
+
if (child?.content) {
|
|
25
|
+
const data = JSON.parse(child.content.toString())
|
|
26
|
+
if (data.errors && data.errors.length > 0) {
|
|
27
|
+
const errorMessages = data.errors.map(err => err.message || 'Unknown error').join(', ')
|
|
28
|
+
const firstError = data.errors[0]
|
|
29
|
+
const errorCode = firstError.extensions?.error_code || 400
|
|
30
|
+
throw new boom_1.Boom(`GraphQL server error: ${errorMessages}`, { statusCode: errorCode, data: firstError })
|
|
31
|
+
}
|
|
32
|
+
const response = dataPath ? data?.data?.[dataPath] : data?.data
|
|
33
|
+
if (typeof response !== 'undefined') {
|
|
34
|
+
return response
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const action = (dataPath || '').startsWith('xwa2_')
|
|
38
|
+
? dataPath.substring(5).replace(/_/g, ' ')
|
|
39
|
+
: dataPath?.replace(/_/g, ' ')
|
|
40
|
+
throw new boom_1.Boom(`Failed to ${action}, unexpected response structure.`, { statusCode: 400, data: result })
|
|
41
|
+
}
|
package/lib/Socket/socket.js
CHANGED
|
@@ -217,7 +217,9 @@ export const makeSocket = (config) => {
|
|
|
217
217
|
return usyncQuery.parseUSyncQueryResult(result);
|
|
218
218
|
};
|
|
219
219
|
const onWhatsApp = async (...phoneNumber) => {
|
|
220
|
-
let usyncQuery = new USyncQuery()
|
|
220
|
+
let usyncQuery = new USyncQuery()
|
|
221
|
+
.withContactProtocol()
|
|
222
|
+
.withLIDProtocol();
|
|
221
223
|
let contactEnabled = false;
|
|
222
224
|
for (const jid of phoneNumber) {
|
|
223
225
|
if (isLidUser(jid)) {
|
|
@@ -238,7 +240,7 @@ export const makeSocket = (config) => {
|
|
|
238
240
|
}
|
|
239
241
|
const results = await executeUSyncQuery(usyncQuery);
|
|
240
242
|
if (results) {
|
|
241
|
-
return results.list.filter(a => !!a.contact).map(({ contact, id }) => ({ jid: id, exists: contact }));
|
|
243
|
+
return results.list.filter(a => !!a.contact).map(({ contact, id, lid }) => ({ jid: id, lid, exists: contact }));
|
|
242
244
|
}
|
|
243
245
|
};
|
|
244
246
|
const pnFromLIDUSync = async (jids) => {
|
|
@@ -261,6 +263,14 @@ export const makeSocket = (config) => {
|
|
|
261
263
|
}
|
|
262
264
|
return [];
|
|
263
265
|
};
|
|
266
|
+
const toPn = async (jid) => {
|
|
267
|
+
const res = await pnFromLIDUSync([jid]).list[0].id;
|
|
268
|
+
return res
|
|
269
|
+
}
|
|
270
|
+
const toLid = async (jid) => {
|
|
271
|
+
const [res] = await onWhatsApp(jid).lid;
|
|
272
|
+
return res
|
|
273
|
+
}
|
|
264
274
|
const ev = makeEventBuffer(logger);
|
|
265
275
|
const { creds } = authState;
|
|
266
276
|
// add transaction capability
|
|
@@ -952,7 +962,10 @@ export const makeSocket = (config) => {
|
|
|
952
962
|
executeUSyncQuery,
|
|
953
963
|
onWhatsApp,
|
|
954
964
|
fetchAccountReachoutTimelock,
|
|
955
|
-
fetchNewChatMessageCap
|
|
965
|
+
fetchNewChatMessageCap,
|
|
966
|
+
toPn,
|
|
967
|
+
toLid,
|
|
968
|
+
pnFromLIDUSync
|
|
956
969
|
};
|
|
957
970
|
};
|
|
958
971
|
/**
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { executeWMexQuery } from './mex.js'
|
|
2
|
+
import { USyncQuery, USyncUser } from '../WAUSync/index.js'
|
|
3
|
+
import { makeNewsletterSocket } from './newsletter.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* w:mex query IDs for username operations.
|
|
7
|
+
*
|
|
8
|
+
* These numeric IDs are assigned by WhatsApp's Pando/MEX infrastructure.
|
|
9
|
+
* They can be obtained by capturing a real WA session that performs these
|
|
10
|
+
* operations and inspecting the query_id field in the <query> IQ node.
|
|
11
|
+
*
|
|
12
|
+
* Source: Java decompilation of WhatsApp 2.26.17.2 (C1568872p.java)
|
|
13
|
+
* Operations confirmed: UsernameCheck, UsernameSet, UsernameGet, UsernamePinSet
|
|
14
|
+
* Data path confirmed: xwa2_username_check (C164057Wg.java:81)
|
|
15
|
+
*/
|
|
16
|
+
export const USERNAME_QUERY_IDS = {
|
|
17
|
+
CHECK: '26124072630599520', // UsernameCheck
|
|
18
|
+
CHECK_MULTI: '27134626522840290', // UsernameCheckMulti
|
|
19
|
+
SET: '27108705368767936', // UsernameSet
|
|
20
|
+
GET: '32618050064506056', // UsernameGet
|
|
21
|
+
GET_RECOMMENDATIONS: '26077456248616956', // UsernameGetRecommendationsQuery
|
|
22
|
+
PIN_SET: '25529696019976770' // UsernamePinSet
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Source enum values from EnumC141106Vn (UsernameCheck result)
|
|
27
|
+
* and EnumC141056Vi (rejection reasons) confirmed via C164057Wg.java
|
|
28
|
+
*/
|
|
29
|
+
export const USERNAME_CHECK_RESULT = {
|
|
30
|
+
SUCCESS: 'SUCCESS',
|
|
31
|
+
INVALID: 'INVALID'
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const USERNAME_SOURCE = {
|
|
35
|
+
FB: 'FB',
|
|
36
|
+
IG: 'IG',
|
|
37
|
+
USER_INPUT: 'USER_INPUT',
|
|
38
|
+
SUGGESTION: 'SUGGESTION'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const makeUsernameSocket = config => {
|
|
42
|
+
const sock = makeNewsletterSocket(config)
|
|
43
|
+
const { query, generateMessageTag, executeUSyncQuery } = sock
|
|
44
|
+
|
|
45
|
+
const mexQuery = (variables, queryId, dataPath) =>
|
|
46
|
+
executeWMexQuery(variables, queryId, dataPath, query, generateMessageTag)
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Check whether a username is available.
|
|
50
|
+
*
|
|
51
|
+
* @param {string} username - The @username to check (without @)
|
|
52
|
+
* @param {boolean} includeSuggestions - Request alternative suggestions when taken
|
|
53
|
+
* @returns {object}
|
|
54
|
+
* On success: { available: true, username }
|
|
55
|
+
* On taken: { available: false, username, suggestions: string[], rejectionReasons: string[], suggestionsEligible: boolean }
|
|
56
|
+
* On rate-limit: throws Boom with statusCode 429
|
|
57
|
+
*
|
|
58
|
+
* Confirmed fields from C164057Wg.java:
|
|
59
|
+
* data.xwa2_username_check.result → 'SUCCESS' | 'INVALID'
|
|
60
|
+
* data.xwa2_username_check.suggestions
|
|
61
|
+
* data.xwa2_username_check.rejection_reasons
|
|
62
|
+
* data.xwa2_username_check.suggestions_eligible
|
|
63
|
+
*/
|
|
64
|
+
const checkUsername = async (username, includeSuggestions = true) => {
|
|
65
|
+
if (!USERNAME_QUERY_IDS.CHECK) {
|
|
66
|
+
throw new Error('Username CHECK query_id not configured — capture a live WA session to obtain it')
|
|
67
|
+
}
|
|
68
|
+
const data = await mexQuery(
|
|
69
|
+
{ username, include_suggestions: includeSuggestions },
|
|
70
|
+
USERNAME_QUERY_IDS.CHECK,
|
|
71
|
+
'xwa2_username_check'
|
|
72
|
+
)
|
|
73
|
+
if (data?.result === USERNAME_CHECK_RESULT.SUCCESS) {
|
|
74
|
+
return { available: true, username }
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
available: false,
|
|
78
|
+
username,
|
|
79
|
+
suggestions: data?.suggestions?? [],
|
|
80
|
+
rejectionReasons: data?.rejection_reasons?? [],
|
|
81
|
+
suggestionsEligible: data?.suggestions_eligible?? true
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Set your own username.
|
|
87
|
+
*
|
|
88
|
+
* @param {string} username - The username to set (without @)
|
|
89
|
+
* @param {object} options
|
|
90
|
+
* @param {string} [options.source] - 'USER_INPUT' | 'FB' | 'IG' | 'SUGGESTION'
|
|
91
|
+
* @param {string} [options.sessionId] - Optional session tracking ID
|
|
92
|
+
* @param {string} [options.pin] - Optional PIN for protected usernames
|
|
93
|
+
*
|
|
94
|
+
* Confirmed variables from C1568872p.java A00():
|
|
95
|
+
* username, reserved (bool), session_id, source, pin
|
|
96
|
+
*/
|
|
97
|
+
const setUsername = async (username, options = {}) => {
|
|
98
|
+
if (!USERNAME_QUERY_IDS.SET) {
|
|
99
|
+
throw new Error('Username SET query_id not configured — capture a live WA session to obtain it')
|
|
100
|
+
}
|
|
101
|
+
const { source = USERNAME_SOURCE.USER_INPUT, sessionId, pin } = options
|
|
102
|
+
const variables = {
|
|
103
|
+
username,
|
|
104
|
+
reserved: false,
|
|
105
|
+
source,
|
|
106
|
+
...(sessionId? { session_id: sessionId } : {}),
|
|
107
|
+
...(pin? { pin } : {})
|
|
108
|
+
}
|
|
109
|
+
return mexQuery(variables, USERNAME_QUERY_IDS.SET, 'xwa2_username_set')
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Delete (unset) your own username.
|
|
114
|
+
*
|
|
115
|
+
* Confirmed from C1568872p.java:
|
|
116
|
+
* str4 = str == null? "delete" : "set"
|
|
117
|
+
* → sending username=null triggers the delete path on the server.
|
|
118
|
+
*/
|
|
119
|
+
const deleteUsername = async () => {
|
|
120
|
+
if (!USERNAME_QUERY_IDS.SET) {
|
|
121
|
+
throw new Error('Username SET query_id not configured — capture a live WA session to obtain it')
|
|
122
|
+
}
|
|
123
|
+
return mexQuery({ username: null }, USERNAME_QUERY_IDS.SET, 'xwa2_username_delete')
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Get your own current username.
|
|
128
|
+
*
|
|
129
|
+
* Confirmed from C1568872p.java A02():
|
|
130
|
+
* AbstractC41851rT.A0L(AbstractC130045pa.A0T(), C1363664w.class, "UsernameGet", false)
|
|
131
|
+
*/
|
|
132
|
+
const getMyUsername = async () => {
|
|
133
|
+
if (!USERNAME_QUERY_IDS.GET) {
|
|
134
|
+
throw new Error('Username GET query_id not configured — capture a live WA session to obtain it')
|
|
135
|
+
}
|
|
136
|
+
const data = await mexQuery({}, USERNAME_QUERY_IDS.GET, 'xwa2_username_get')
|
|
137
|
+
return data?.username?? null
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Set or delete the PIN that protects your username.
|
|
142
|
+
*
|
|
143
|
+
* @param {string|null} pin - New PIN, or null to delete the PIN
|
|
144
|
+
*
|
|
145
|
+
* Confirmed from MexUsernamePinProtocolApi.java:
|
|
146
|
+
* operation "UsernamePinSet", variable "pin"
|
|
147
|
+
* pin=null triggers the "delete" path on the server.
|
|
148
|
+
*/
|
|
149
|
+
const setUsernamePin = async pin => {
|
|
150
|
+
if (!USERNAME_QUERY_IDS.PIN_SET) {
|
|
151
|
+
throw new Error('Username PIN_SET query_id not configured — capture a live WA session to obtain it')
|
|
152
|
+
}
|
|
153
|
+
return mexQuery({ pin }, USERNAME_QUERY_IDS.PIN_SET, 'xwa2_username_pin_set')
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Look up a contact by their @username via USync.
|
|
158
|
+
*
|
|
159
|
+
* Confirmed via USyncContactProtocol.getUserElement():
|
|
160
|
+
* { tag: 'contact', attrs: { username, pin? } }
|
|
161
|
+
*
|
|
162
|
+
* @param {string} username - The username to look up (without @)
|
|
163
|
+
* @param {string} [pin] - Optional PIN if the username is PIN-protected
|
|
164
|
+
* @returns {{ jid, lid?, contact: boolean }|null}
|
|
165
|
+
*/
|
|
166
|
+
const findUserByUsername = async (username, pin) => {
|
|
167
|
+
const usyncQuery = new USyncQuery().withContactProtocol()
|
|
168
|
+
const user = new USyncUser().withUsername(username)
|
|
169
|
+
if (pin) user.withUsernameKey(pin)
|
|
170
|
+
usyncQuery.withUser(user)
|
|
171
|
+
const result = await executeUSyncQuery(usyncQuery)
|
|
172
|
+
if (!result?.list?.length) return null
|
|
173
|
+
const entry = result.list[0]
|
|
174
|
+
return {
|
|
175
|
+
jid: entry.id,
|
|
176
|
+
contact: entry.contact?? false
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Fetch the username of one or more contacts by their JID.
|
|
182
|
+
* Uses USync with the username protocol.
|
|
183
|
+
*
|
|
184
|
+
* @param {...string} jids - One or more JIDs
|
|
185
|
+
* @returns {Array<{ id, username: string|null }>}
|
|
186
|
+
*/
|
|
187
|
+
const fetchContactUsernames = async (...jids) => {
|
|
188
|
+
const usyncQuery = new USyncQuery().withUsernameProtocol()
|
|
189
|
+
for (const jid of jids) {
|
|
190
|
+
usyncQuery.withUser(new USyncUser().withId(jid))
|
|
191
|
+
}
|
|
192
|
+
const result = await executeUSyncQuery(usyncQuery)
|
|
193
|
+
return result?.list?? []
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Check multiple usernames for availability at once.
|
|
198
|
+
* @param {string[]} usernames - Array of usernames (without @)
|
|
199
|
+
*/
|
|
200
|
+
const checkUsernameMulti = async usernames => {
|
|
201
|
+
const data = await mexQuery(
|
|
202
|
+
{ usernames },
|
|
203
|
+
USERNAME_QUERY_IDS.CHECK_MULTI,
|
|
204
|
+
'xwa2_username_check_multi'
|
|
205
|
+
)
|
|
206
|
+
return data
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Fetch username recommendations for the current user.
|
|
211
|
+
* @param {string} [source] - Source hint: 'FB' | 'IG' | 'USER_INPUT'
|
|
212
|
+
*/
|
|
213
|
+
const getUsernameRecommendations = async (source = null) => {
|
|
214
|
+
const variables = {}
|
|
215
|
+
if (source) variables.source = source
|
|
216
|
+
return mexQuery(variables, USERNAME_QUERY_IDS.GET_RECOMMENDATIONS, 'xwa2_username_get_recommendations')
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
...sock,
|
|
221
|
+
checkUsername,
|
|
222
|
+
checkUsernameMulti,
|
|
223
|
+
setUsername,
|
|
224
|
+
deleteUsername,
|
|
225
|
+
getMyUsername,
|
|
226
|
+
getUsernameRecommendations,
|
|
227
|
+
setUsernamePin,
|
|
228
|
+
findUserByUsername,
|
|
229
|
+
fetchContactUsernames,
|
|
230
|
+
USERNAME_QUERY_IDS,
|
|
231
|
+
USERNAME_CHECK_RESULT,
|
|
232
|
+
USERNAME_SOURCE
|
|
233
|
+
}
|
|
234
|
+
}
|
package/lib/Utils/messages.js
CHANGED
|
@@ -633,6 +633,13 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
633
633
|
}
|
|
634
634
|
})
|
|
635
635
|
}
|
|
636
|
+
else if ('botInvoke' in message && !!message.botInvoke) {
|
|
637
|
+
m = {
|
|
638
|
+
botInvokeMessage: {
|
|
639
|
+
message: message.botInvoke
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
636
643
|
else if (hasNonNullishProperty(message, 'text')) {
|
|
637
644
|
const extContent = { text: message.text };
|
|
638
645
|
let urlInfo = message.linkPreview;
|
package/package.json
CHANGED