@zervonex/baileys 0.0.0-stage → 3.0.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.
Files changed (124) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3206 -3
  3. package/WAProto/WAProtoCompile.js +291 -0
  4. package/WAProto/fetcher.js +69 -0
  5. package/WAProto/index.js +88 -0
  6. package/WAProto/parser.js +313 -0
  7. package/engine-requirements.js +10 -0
  8. package/lib/Builders/AIRich.js +643 -0
  9. package/lib/Builders/base.js +130 -0
  10. package/lib/Builders/builders.js +449 -0
  11. package/lib/Builders/index.js +3 -0
  12. package/lib/Defaults/index.js +225 -0
  13. package/lib/Defaults/phonenumber-mcc.json +223 -0
  14. package/lib/Signal/index.js +2 -0
  15. package/lib/Signal/libsignal.js +523 -0
  16. package/lib/Signal/lid-mapping.js +283 -0
  17. package/lib/Socket/Client/index.js +2 -0
  18. package/lib/Socket/Client/types.js +10 -0
  19. package/lib/Socket/Client/websocket.js +84 -0
  20. package/lib/Socket/business.js +152 -0
  21. package/lib/Socket/chats.js +855 -0
  22. package/lib/Socket/communities.js +147 -0
  23. package/lib/Socket/groups.js +294 -0
  24. package/lib/Socket/index.js +15 -0
  25. package/lib/Socket/messages-recv.js +981 -0
  26. package/lib/Socket/messages-send.js +708 -0
  27. package/lib/Socket/mex.js +34 -0
  28. package/lib/Socket/newsletter.js +781 -0
  29. package/lib/Socket/registration.js +155 -0
  30. package/lib/Socket/socket.js +797 -0
  31. package/lib/Socket/spam-report.js +65 -0
  32. package/lib/Socket/username.js +82 -0
  33. package/lib/Socket/zervonex-handler.js +55 -0
  34. package/lib/Store/index.js +6 -0
  35. package/lib/Store/make-cache-manager-store.js +81 -0
  36. package/lib/Store/make-in-memory-store.js +425 -0
  37. package/lib/Store/make-ordered-dictionary.js +82 -0
  38. package/lib/Store/object-repository.js +31 -0
  39. package/lib/Store/reporting-info-store.js +38 -0
  40. package/lib/Types/Auth.js +2 -0
  41. package/lib/Types/Bussines.js +2 -0
  42. package/lib/Types/Call.js +2 -0
  43. package/lib/Types/Chat.js +8 -0
  44. package/lib/Types/Contact.js +2 -0
  45. package/lib/Types/Events.js +2 -0
  46. package/lib/Types/GroupMetadata.js +2 -0
  47. package/lib/Types/Label.js +25 -0
  48. package/lib/Types/LabelAssociation.js +7 -0
  49. package/lib/Types/Message.js +15 -0
  50. package/lib/Types/Newsletter.js +100 -0
  51. package/lib/Types/Product.js +2 -0
  52. package/lib/Types/Signal.js +2 -0
  53. package/lib/Types/Socket.js +14 -0
  54. package/lib/Types/State.js +26 -0
  55. package/lib/Types/USync.js +2 -0
  56. package/lib/Types/index.js +30 -0
  57. package/lib/Utils/auth-utils.js +142 -0
  58. package/lib/Utils/baileys-event-stream.js +33 -0
  59. package/lib/Utils/bot-capabilities.js +40 -0
  60. package/lib/Utils/bot-planning-replay.js +44 -0
  61. package/lib/Utils/browser-utils.js +26 -0
  62. package/lib/Utils/business.js +75 -0
  63. package/lib/Utils/chat-utils.js +317 -0
  64. package/lib/Utils/companion-reg-client-utils.js +20 -0
  65. package/lib/Utils/consumer-application.js +38 -0
  66. package/lib/Utils/crypto.js +52 -0
  67. package/lib/Utils/decode-wa-message.js +197 -0
  68. package/lib/Utils/event-buffer.js +273 -0
  69. package/lib/Utils/extras.js +186 -0
  70. package/lib/Utils/generics.js +195 -0
  71. package/lib/Utils/history.js +51 -0
  72. package/lib/Utils/identity-change-handler.js +19 -0
  73. package/lib/Utils/index.js +38 -0
  74. package/lib/Utils/link-preview.js +51 -0
  75. package/lib/Utils/logger.js +2 -0
  76. package/lib/Utils/lt-hash.js +3 -0
  77. package/lib/Utils/make-mutex.js +16 -0
  78. package/lib/Utils/message-composer.js +59 -0
  79. package/lib/Utils/message-retry-manager.js +48 -0
  80. package/lib/Utils/messages-media.js +520 -0
  81. package/lib/Utils/messages.js +752 -0
  82. package/lib/Utils/meta-ai-msmsg.js +122 -0
  83. package/lib/Utils/meta-compositing.js +75 -0
  84. package/lib/Utils/modern-messages.js +235 -0
  85. package/lib/Utils/native-flow.js +55 -0
  86. package/lib/Utils/noise-handler.js +161 -0
  87. package/lib/Utils/pre-key-manager.js +76 -0
  88. package/lib/Utils/process-message.js +399 -0
  89. package/lib/Utils/reporting-utils.js +171 -0
  90. package/lib/Utils/signal.js +167 -0
  91. package/lib/Utils/spam-report-utils.js +135 -0
  92. package/lib/Utils/sync-action-utils.js +33 -0
  93. package/lib/Utils/tc-token-utils.js +154 -0
  94. package/lib/Utils/use-multi-file-auth-state.js +307 -0
  95. package/lib/Utils/validate-connection.js +181 -0
  96. package/lib/WABinary/constants.js +1321 -0
  97. package/lib/WABinary/decode.js +152 -0
  98. package/lib/WABinary/encode.js +140 -0
  99. package/lib/WABinary/generic-utils.js +179 -0
  100. package/lib/WABinary/index.js +6 -0
  101. package/lib/WABinary/jid-utils.js +235 -0
  102. package/lib/WABinary/types.js +4 -0
  103. package/lib/WAM/BinaryInfo.js +10 -0
  104. package/lib/WAM/constants.js +22853 -0
  105. package/lib/WAM/encode.js +150 -0
  106. package/lib/WAM/index.js +3 -0
  107. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +30 -0
  108. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +48 -0
  109. package/lib/WAUSync/Protocols/USyncContactProtocol.js +23 -0
  110. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +28 -0
  111. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +15 -0
  112. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +24 -0
  113. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +9 -0
  114. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +21 -0
  115. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +19 -0
  116. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +19 -0
  117. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +22 -0
  118. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +16 -0
  119. package/lib/WAUSync/Protocols/index.js +12 -0
  120. package/lib/WAUSync/USyncQuery.js +100 -0
  121. package/lib/WAUSync/USyncUser.js +20 -0
  122. package/lib/WAUSync/index.js +3 -0
  123. package/lib/index.js +67 -0
  124. package/package.json +220 -5
@@ -0,0 +1,65 @@
1
+ import { createReportingInfoStore } from '../Store/index.js'
2
+ import { SPAM_FLOWS, resolveReportJid, normalizeReportingTag, buildSpamReportIq, buildSimpleReportNode, parseSpamReportResponse } from '../Utils/index.js'
3
+ import { isJidGroup, isPnUser, isLidUser, jidNormalizedUser, S_WHATSAPP_NET } from '../WABinary/index.js'
4
+
5
+ export const makeSpamReportSocket = (sock, config) => {
6
+ const { query, signalRepository, updateBlockStatus, logger } = sock
7
+
8
+ if (!config.reportingInfoStore) config.reportingInfoStore = createReportingInfoStore()
9
+ const store = config.reportingInfoStore
10
+
11
+ const simpleReportQuery = (jid, messageKeys) => query({
12
+ tag: 'iq',
13
+ attrs: { type: 'set', xmlns: 'spam', to: S_WHATSAPP_NET },
14
+ content: [buildSimpleReportNode(jid, messageKeys)]
15
+ })
16
+
17
+ const reportSpam = async (jid, options = {}) => {
18
+ const { spamFlow = SPAM_FLOWS.ACCOUNT_INFO_REPORT, messages: manualMessages, maxMessages = 5 } = options
19
+ const reportJid = await resolveReportJid(jid, signalRepository?.lidMapping)
20
+ let messages = manualMessages
21
+ if (!messages?.length) {
22
+ messages = store.getForJid(reportJid, maxMessages)
23
+ if (!messages.length) messages = store.getForJid(jid, maxMessages)
24
+ }
25
+ if (!messages?.length) throw new Error(`reportSpam: no reporting_tag stored for ${jid}. Receive at least one message first.`)
26
+ const normalized = messages.slice(0, maxMessages).map(m => ({
27
+ stanzaId: m.stanzaId || m.id,
28
+ timestamp: Number(m.timestamp || m.sendTimestamp || m.t),
29
+ reportingTag: normalizeReportingTag(m.reportingTag || m.tag),
30
+ text: m.text ?? m.raw ?? '',
31
+ pushName: m.pushName || m.reportedPushName || '',
32
+ messageType: m.messageType || m.type || 'text',
33
+ fromJid: m.fromJid || m.from || reportJid
34
+ }))
35
+ logger?.debug?.({ jid: reportJid, spamFlow, count: normalized.length }, 'sending spam report IQ')
36
+ const result = await query(buildSpamReportIq(reportJid, normalized, spamFlow))
37
+ return { ...parseSpamReportResponse(result), messageCount: normalized.length }
38
+ }
39
+
40
+ const reportContact = async (jid, messageKeys = []) => {
41
+ const normalized = jidNormalizedUser(jid)
42
+ if (!isPnUser(normalized) && !isLidUser(normalized)) throw new Error('reportContact requires a valid contact JID')
43
+ const result = await simpleReportQuery(normalized, messageKeys)
44
+ await updateBlockStatus(normalized, 'block')
45
+ return parseSpamReportResponse(result)
46
+ }
47
+
48
+ const reportGroup = async (jid, messageKeys = []) => {
49
+ if (!isJidGroup(jid)) throw new Error('reportGroup requires a valid group JID')
50
+ const result = await simpleReportQuery(jid, messageKeys)
51
+ await query({ tag: 'iq', attrs: { type: 'set', xmlns: 'w:g2', to: '@g.us' }, content: [{ tag: 'leave', attrs: {}, content: [{ tag: 'group', attrs: { id: jid } }] }] })
52
+ return parseSpamReportResponse(result)
53
+ }
54
+
55
+ return {
56
+ ...sock,
57
+ reportSpam,
58
+ reportContact,
59
+ reportGroup,
60
+ getStoredReportingInfo: (jid, max = 5) => store.getForJid(jid, max),
61
+ clearStoredReportingInfo: jid => store.clear(jid),
62
+ reportingInfoStore: store,
63
+ SPAM_FLOWS
64
+ }
65
+ }
@@ -0,0 +1,82 @@
1
+ import { randomUUID } from 'crypto';
2
+ import { executeWMexQuery } from './mex.js';
3
+ import { USyncQuery, USyncUser } from '../WAUSync/index.js';
4
+ import { makeRegistrationSocket } from './registration.js';
5
+ import { makeSpamReportSocket } from './spam-report.js';
6
+ import { USERNAME_QUERY_IDS, USERNAME_CHECK_RESULT, USERNAME_SOURCE } from '../Defaults/index.js';
7
+
8
+ export const makeUsernameSocket = config => {
9
+ const sock = makeRegistrationSocket(config);
10
+ const { query, generateMessageTag, executeUSyncQuery } = sock;
11
+
12
+ const mexQuery = (variables, queryId, dataPath) => executeWMexQuery(variables, queryId, dataPath, query, generateMessageTag);
13
+
14
+ const checkUsername = async (username, includeSuggestions = true, sessionId) => {
15
+ const session_id = sessionId || randomUUID();
16
+ const data = await mexQuery({ username, include_suggestions: includeSuggestions, session_id, source: USERNAME_SOURCE.USER_INPUT }, USERNAME_QUERY_IDS.CHECK, 'xwa2_username_check');
17
+ if (data?.result === USERNAME_CHECK_RESULT.SUCCESS) return { available: true, username, session_id };
18
+ return { available: false, username, session_id, suggestions: data?.suggestions ?? [], rejectionReasons: data?.rejection_reasons ?? [], suggestionsEligible: data?.suggestions_eligible ?? true };
19
+ };
20
+
21
+ const setUsername = async (username, options = {}) => {
22
+ const { source = USERNAME_SOURCE.USER_INPUT, sessionId, pin } = options;
23
+ const session_id = sessionId || randomUUID();
24
+ return mexQuery({ username, reserved: true, source, session_id, ...(pin ? { pin } : {}) }, USERNAME_QUERY_IDS.SET, 'xwa2_username_set');
25
+ };
26
+
27
+ const checkAndSetUsername = async username => {
28
+ const r = await checkUsername(username);
29
+ if (r.available) return setUsername(username);
30
+ return r;
31
+ };
32
+
33
+ const deleteUsername = async () => mexQuery({ username: null }, USERNAME_QUERY_IDS.SET, 'xwa2_username_delete');
34
+
35
+ const getMyUsername = async () => {
36
+ const data = await mexQuery({}, USERNAME_QUERY_IDS.GET, 'xwa2_username_get');
37
+ return data?.username ?? null;
38
+ };
39
+
40
+ const setUsernamePin = async pin => mexQuery(pin != null ? { pin } : {}, USERNAME_QUERY_IDS.PIN_SET, 'xwa2_username_pin_set');
41
+
42
+ const findUserByUsername = async (username, pin) => {
43
+ const usyncQuery = new USyncQuery().withContactProtocol();
44
+ const user = new USyncUser().withUsername(username);
45
+ if (pin) user.withUsernameKey(pin);
46
+ usyncQuery.withUser(user);
47
+ const result = await executeUSyncQuery(usyncQuery);
48
+ if (!result?.list?.length) return null;
49
+ const entry = result.list[0];
50
+ return { jid: entry.id, contact: entry.contact ?? false };
51
+ };
52
+
53
+ const fetchContactUsernames = async (...jids) => {
54
+ const usyncQuery = new USyncQuery().withUsernameProtocol();
55
+ for (const jid of jids) usyncQuery.withUser(new USyncUser().withId(jid));
56
+ const result = await executeUSyncQuery(usyncQuery);
57
+ return result?.list ?? [];
58
+ };
59
+
60
+ const checkUsernameMulti = async usernames => mexQuery({ usernames }, USERNAME_QUERY_IDS.CHECK_MULTI, 'xwa2_username_check_multi');
61
+
62
+ const getUsernameRecommendations = async (source = null) => mexQuery(source ? { source } : {}, USERNAME_QUERY_IDS.GET_RECOMMENDATIONS, 'xwa2_username_get_recommendations');
63
+
64
+ const base = {
65
+ ...sock,
66
+ checkUsername,
67
+ checkUsernameMulti,
68
+ setUsername,
69
+ checkAndSetUsername,
70
+ deleteUsername,
71
+ getMyUsername,
72
+ getUsernameRecommendations,
73
+ setUsernamePin,
74
+ findUserByUsername,
75
+ fetchContactUsernames,
76
+ USERNAME_QUERY_IDS,
77
+ USERNAME_CHECK_RESULT,
78
+ USERNAME_SOURCE
79
+ };
80
+
81
+ return makeSpamReportSocket(base, config);
82
+ };
@@ -0,0 +1,55 @@
1
+ import crypto from 'crypto'
2
+ import * as Builders from '../Builders/index.js'
3
+ import { buildDispatch, buildPlugins, norm, handleGroupStatus, handleStatusMention, handlePollResult, PRIMITIVE_SHORTCUTS, HANDLER_SHORTCUTS, attachAIRich } from '../Builders/index.js'
4
+ import { makeUsernameSocket } from './username.js'
5
+
6
+ export const makeMessageBuilderSocket = (config) => {
7
+ const sock = makeUsernameSocket(config)
8
+ const _send = sock.sendMessage.bind(sock)
9
+
10
+ const ALL_BUILDERS = Object.values(Builders).filter(B => typeof B === 'function' && (B.dispatchKeys || B.shortcuts || B.name))
11
+
12
+ const DISPATCH = buildDispatch(ALL_BUILDERS, {
13
+ groupStatus: (sock, jid, content, opts, config) => handleGroupStatus(sock, jid, norm(content.groupStatus), config),
14
+ statusMentionMessage: (sock, jid, content, opts, config) => handleStatusMention(sock, jid, norm(content.statusMentionMessage), config),
15
+ pollResultMessage: (sock, jid, content) => handlePollResult(sock, jid, norm(content.pollResultMessage))
16
+ })
17
+
18
+ const PLUGINS = buildPlugins(ALL_BUILDERS, { ...PRIMITIVE_SHORTCUTS, ...HANDLER_SHORTCUTS })
19
+
20
+ const result = { ...sock }
21
+
22
+ for (const [name, factory] of Object.entries(PLUGINS)) result[name] = factory(result, config)
23
+
24
+ result.sendMessage = async (jid, content, options = {}) => {
25
+ // aiRich shorthand — multiple aliases supported
26
+ const aiData = content.aiRich ?? content.airich ?? content.richResponse ?? content.AIRich
27
+ if (aiData) return result.sendRichFromObject(jid, aiData, options)
28
+
29
+ // dispatch to registered builder handlers
30
+ for (const [key, handler] of Object.entries(DISPATCH)) {
31
+ if (key in content) return handler(result, jid, content, options, config)
32
+ }
33
+
34
+ // bare nativeFlow array/object — wrap into interactiveMessage before sending
35
+ if (content.nativeFlow && !content.interactiveMessage) {
36
+ const buttons = Array.isArray(content.nativeFlow) ? content.nativeFlow : [content.nativeFlow]
37
+ const { generateWAMessageFromContent } = await import('../Utils/index.js')
38
+ const msg = await generateWAMessageFromContent(jid, {
39
+ interactiveMessage: { body: { text: content.text || '' }, footer: { text: content.footer || '' }, header: { hasMediaAttachment: false }, nativeFlowMessage: { buttons } }
40
+ }, { userJid: sock.user?.id })
41
+ await result.relayMessage(jid, msg.message, { messageId: msg.key.id, aiLabel: !!(content.ai ?? content.aiLabel ?? options.aiLabel ?? options.ai ?? config.aiLabel ?? config.ai) })
42
+ return msg
43
+ }
44
+
45
+ const { ai, aiLabel: contentAiLabel, ...cleanContent } = content
46
+ const isAi = !!(ai ?? contentAiLabel ?? options.aiLabel ?? options.ai ?? config.aiLabel)
47
+ if (isAi) {
48
+ const secret = cleanContent.messageContextInfo?.messageSecret || crypto.randomBytes(32)
49
+ cleanContent.messageContextInfo = { ...(cleanContent.messageContextInfo || {}), messageSecret: secret, supportPayload: JSON.stringify({ version: 2, is_ai_message: true, should_show_system_message: true, ticket_id: crypto.randomBytes(16).toString('hex') }) }
50
+ }
51
+ return _send(jid, isAi ? cleanContent : content, { ...options, aiLabel: isAi })
52
+ }
53
+
54
+ return attachAIRich(result, config)
55
+ }
@@ -0,0 +1,6 @@
1
+ export * from './make-cache-manager-store.js'
2
+ export * from './make-in-memory-store.js'
3
+ export * from './make-ordered-dictionary.js'
4
+ export * from './reporting-info-store.js'
5
+ export { makeInMemoryStore as default } from './make-in-memory-store.js'
6
+ export * from './object-repository.js'
@@ -0,0 +1,81 @@
1
+ import * as cacheManager from 'cache-manager';
2
+ import * as WAProto from '../../WAProto/index.js';
3
+ import { BufferJSON, initAuthCreds } from '../Utils/index.js';
4
+ import logger from '../Utils/logger.js';
5
+
6
+ const makeCacheManagerAuthState = async (store, sessionKey) => {
7
+ const defaultKey = (file) => `${sessionKey}:${file}`;
8
+ const databaseConn = await cacheManager.caching(store);
9
+
10
+ const writeData = async (file, data) => {
11
+ let ttl = undefined;
12
+ if (file === 'creds') {
13
+ ttl = 63115200; // 2 years
14
+ }
15
+ await databaseConn.set(defaultKey(file), JSON.stringify(data, BufferJSON.replacer), ttl);
16
+ };
17
+
18
+ const readData = async (file) => {
19
+ try {
20
+ const data = await databaseConn.get(defaultKey(file));
21
+ if (data) {
22
+ return JSON.parse(data, BufferJSON.reviver);
23
+ }
24
+ return null;
25
+ } catch (error) {
26
+ logger.error(error);
27
+ return null;
28
+ }
29
+ };
30
+
31
+ const removeData = async (file) => {
32
+ try {
33
+ return await databaseConn.del(defaultKey(file));
34
+ } catch {
35
+ logger.error(`Error removing ${file} from session ${sessionKey}`);
36
+ }
37
+ };
38
+
39
+ const clearState = async () => {
40
+ try {
41
+ const result = await databaseConn.store.keys(`${sessionKey}*`);
42
+ await Promise.all(result.map(async (key) => await databaseConn.del(key)));
43
+ } catch {}
44
+ };
45
+
46
+ const creds = (await readData('creds')) || initAuthCreds();
47
+
48
+ return {
49
+ clearState,
50
+ saveCreds: () => writeData('creds', creds),
51
+ state: {
52
+ creds,
53
+ keys: {
54
+ get: async (type, ids) => {
55
+ const data = {};
56
+ await Promise.all(ids.map(async (id) => {
57
+ let value = await readData(`${type}-${id}`);
58
+ if (type === 'app-state-sync-key' && value) {
59
+ value = WAProto.proto.Message.AppStateSyncKeyData.fromObject(value);
60
+ }
61
+ data[id] = value;
62
+ }));
63
+ return data;
64
+ },
65
+ set: async (data) => {
66
+ const tasks = [];
67
+ for (const category in data) {
68
+ for (const id in data[category]) {
69
+ const value = data[category][id];
70
+ const key = `${category}-${id}`;
71
+ tasks.push(value ? writeData(key, value) : removeData(key));
72
+ }
73
+ }
74
+ await Promise.all(tasks);
75
+ },
76
+ },
77
+ },
78
+ };
79
+ };
80
+
81
+ export { makeCacheManagerAuthState };