@zervonex/baileys 0.0.0-stage → 3.0.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.
Files changed (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3203 -2
  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 +590 -0
  9. package/lib/Builders/base.js +130 -0
  10. package/lib/Builders/builders.js +448 -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 +904 -0
  26. package/lib/Socket/messages-send.js +693 -0
  27. package/lib/Socket/mex.js +34 -0
  28. package/lib/Socket/newsletter.js +752 -0
  29. package/lib/Socket/nexus-handler.js +55 -0
  30. package/lib/Socket/registration.js +155 -0
  31. package/lib/Socket/socket.js +798 -0
  32. package/lib/Socket/spam-report.js +65 -0
  33. package/lib/Socket/username.js +82 -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 +316 -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 +39 -0
  74. package/lib/Utils/key-store.js +3 -0
  75. package/lib/Utils/link-preview.js +51 -0
  76. package/lib/Utils/logger.js +2 -0
  77. package/lib/Utils/lt-hash.js +3 -0
  78. package/lib/Utils/make-mutex.js +16 -0
  79. package/lib/Utils/message-composer.js +59 -0
  80. package/lib/Utils/message-retry-manager.js +48 -0
  81. package/lib/Utils/messages-media.js +520 -0
  82. package/lib/Utils/messages.js +742 -0
  83. package/lib/Utils/meta-ai-msmsg.js +122 -0
  84. package/lib/Utils/meta-compositing.js +75 -0
  85. package/lib/Utils/modern-messages.js +235 -0
  86. package/lib/Utils/native-flow.js +55 -0
  87. package/lib/Utils/noise-handler.js +161 -0
  88. package/lib/Utils/pre-key-manager.js +76 -0
  89. package/lib/Utils/process-message.js +399 -0
  90. package/lib/Utils/reporting-utils.js +171 -0
  91. package/lib/Utils/signal.js +167 -0
  92. package/lib/Utils/spam-report-utils.js +142 -0
  93. package/lib/Utils/sync-action-utils.js +33 -0
  94. package/lib/Utils/tc-token-utils.js +102 -0
  95. package/lib/Utils/use-multi-file-auth-state.js +307 -0
  96. package/lib/Utils/validate-connection.js +181 -0
  97. package/lib/WABinary/constants.js +1321 -0
  98. package/lib/WABinary/decode.js +152 -0
  99. package/lib/WABinary/encode.js +140 -0
  100. package/lib/WABinary/generic-utils.js +179 -0
  101. package/lib/WABinary/index.js +6 -0
  102. package/lib/WABinary/jid-utils.js +235 -0
  103. package/lib/WABinary/types.js +4 -0
  104. package/lib/WAM/BinaryInfo.js +10 -0
  105. package/lib/WAM/constants.js +22853 -0
  106. package/lib/WAM/encode.js +150 -0
  107. package/lib/WAM/index.js +3 -0
  108. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +30 -0
  109. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +48 -0
  110. package/lib/WAUSync/Protocols/USyncContactProtocol.js +23 -0
  111. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +28 -0
  112. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +15 -0
  113. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +24 -0
  114. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +9 -0
  115. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +21 -0
  116. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +19 -0
  117. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +19 -0
  118. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +22 -0
  119. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +16 -0
  120. package/lib/WAUSync/Protocols/index.js +12 -0
  121. package/lib/WAUSync/USyncQuery.js +100 -0
  122. package/lib/WAUSync/USyncUser.js +20 -0
  123. package/lib/WAUSync/index.js +3 -0
  124. package/lib/index.js +68 -0
  125. package/package.json +216 -5
@@ -0,0 +1,147 @@
1
+ import { generateMessageID } from '../Utils/index.js'
2
+ import { getBinaryNodeChild, getBinaryNodeChildren, getBinaryNodeChildString, jidEncode, jidNormalizedUser } from '../WABinary/index.js'
3
+ import { makeBusinessSocket } from './business.js'
4
+
5
+ const extractCommunityParticipants = (group) =>
6
+ getBinaryNodeChildren(group, 'participant').map(({ attrs }) => ({
7
+ id: attrs.jid,
8
+ admin: attrs.type || null
9
+ }))
10
+
11
+ export const extractCommunityMetadata = (result) => {
12
+ const community = getBinaryNodeChild(result, 'community') || getBinaryNodeChild(result, 'group')
13
+ if (!community) throw new Error('Community node not found in result')
14
+ const descChild = getBinaryNodeChild(community, 'description')
15
+ const communityId = community.attrs.id.includes('@') ? community.attrs.id : jidEncode(community.attrs.id, 'g.us')
16
+ return {
17
+ id: communityId,
18
+ subject: community.attrs.subject,
19
+ subjectTime: +community.attrs.s_t,
20
+ creation: +community.attrs.creation,
21
+ owner: community.attrs.creator ? jidNormalizedUser(community.attrs.creator) : undefined,
22
+ desc: descChild ? getBinaryNodeChildString(descChild, 'body') : undefined,
23
+ descId: descChild?.attrs.id,
24
+ participants: extractCommunityParticipants(community)
25
+ }
26
+ }
27
+
28
+ export const makeCommunitiesSocket = (config) => {
29
+ const sock = makeBusinessSocket(config)
30
+ const { ev, query } = sock
31
+
32
+ const communityQuery = (jid, type, content) => query({ tag: 'iq', attrs: { type, xmlns: 'w:g2', to: jid }, content })
33
+
34
+ const communityMetadata = async (jid) => {
35
+ const result = await communityQuery(jid, 'get', [{ tag: 'query', attrs: { request: 'interactive' } }])
36
+ return extractCommunityMetadata(result)
37
+ }
38
+
39
+ const communityFetchAllParticipating = async () => {
40
+ const result = await query({
41
+ tag: 'iq',
42
+ attrs: { to: '@g.us', xmlns: 'w:g2', type: 'get' },
43
+ content: [{ tag: 'participating', attrs: {}, content: [{ tag: 'participants', attrs: {} }, { tag: 'description', attrs: {} }] }]
44
+ })
45
+ const data = {}
46
+ const communitiesChild = getBinaryNodeChild(result, 'communities')
47
+ if (communitiesChild) {
48
+ for (const communityNode of getBinaryNodeChildren(communitiesChild, 'community')) {
49
+ const meta = extractCommunityMetadata({ tag: 'result', attrs: {}, content: [communityNode] })
50
+ data[meta.id] = meta
51
+ }
52
+ }
53
+ ev.emit('groups.update', Object.values(data))
54
+ return data
55
+ }
56
+
57
+ sock.ws.on('CB:ib,,dirty', async (node) => {
58
+ const { attrs } = getBinaryNodeChild(node, 'dirty')
59
+ if (attrs.type !== 'communities') return
60
+ await communityFetchAllParticipating()
61
+ await sock.cleanDirtyBits('groups')
62
+ })
63
+
64
+ return {
65
+ ...sock,
66
+ communityMetadata,
67
+ communityCreate: async (subject, body) => {
68
+ const descriptionId = generateMessageID().substring(0, 12)
69
+ const result = await communityQuery('@g.us', 'set', [{
70
+ tag: 'create',
71
+ attrs: { subject },
72
+ content: [
73
+ { tag: 'description', attrs: { id: descriptionId }, content: [{ tag: 'body', attrs: {}, content: Buffer.from(body || '', 'utf-8') }] },
74
+ { tag: 'parent', attrs: { default_membership_approval_mode: 'request_required' } },
75
+ { tag: 'allow_non_admin_sub_group_creation', attrs: {} },
76
+ { tag: 'create_general_chat', attrs: {} }
77
+ ]
78
+ }])
79
+ const groupNode = getBinaryNodeChild(result, 'group')
80
+ if (!groupNode) return null
81
+ try { return await sock.groupMetadata(`${groupNode.attrs.id}@g.us`) } catch { return null }
82
+ },
83
+ communityCreateGroup: async (subject, participants, parentCommunityJid) => {
84
+ const key = generateMessageID()
85
+ const result = await communityQuery('@g.us', 'set', [{
86
+ tag: 'create',
87
+ attrs: { subject, key },
88
+ content: [
89
+ ...participants.map(jid => ({ tag: 'participant', attrs: { jid } })),
90
+ { tag: 'linked_parent', attrs: { jid: parentCommunityJid } }
91
+ ]
92
+ }])
93
+ const groupNode = getBinaryNodeChild(result, 'group')
94
+ if (!groupNode) return null
95
+ try { return await sock.groupMetadata(`${groupNode.attrs.id}@g.us`) } catch { return null }
96
+ },
97
+ communityLeave: async (id) => {
98
+ await communityQuery('@g.us', 'set', [{ tag: 'leave', attrs: {}, content: [{ tag: 'community', attrs: { id } }] }])
99
+ },
100
+ communityUpdateSubject: async (jid, subject) => {
101
+ await communityQuery(jid, 'set', [{ tag: 'subject', attrs: {}, content: Buffer.from(subject, 'utf-8') }])
102
+ },
103
+ communityLinkGroup: async (groupJid, parentCommunityJid) => {
104
+ await communityQuery(parentCommunityJid, 'set', [{
105
+ tag: 'links',
106
+ attrs: {},
107
+ content: [{ tag: 'link', attrs: { link_type: 'sub_group' }, content: [{ tag: 'group', attrs: { jid: groupJid } }] }]
108
+ }])
109
+ },
110
+ communityUnlinkGroup: async (groupJid, parentCommunityJid) => {
111
+ await communityQuery(parentCommunityJid, 'set', [{ tag: 'unlink', attrs: { unlink_type: 'sub_group' }, content: [{ tag: 'group', attrs: { jid: groupJid } }] }])
112
+ },
113
+ communityFetchLinkedGroups: async (jid) => {
114
+ const metadata = await sock.groupMetadata(jid)
115
+ const communityJid = metadata.linkedParent || jid
116
+ const result = await communityQuery(communityJid, 'get', [{ tag: 'sub_groups', attrs: {} }])
117
+ const subGroupsNode = getBinaryNodeChild(result, 'sub_groups')
118
+ if (!subGroupsNode) return []
119
+ return getBinaryNodeChildren(subGroupsNode, 'group').map(g => ({
120
+ id: g.attrs.id.includes('@') ? g.attrs.id : jidEncode(g.attrs.id, 'g.us'),
121
+ subject: g.attrs.subject
122
+ }))
123
+ },
124
+ communityFetchAllParticipating,
125
+ communityParticipantsUpdate: async (jid, participants, action) => {
126
+ const result = await communityQuery(jid, 'set', [{
127
+ tag: action,
128
+ attrs: {},
129
+ content: participants.map(jid => ({ tag: 'participant', attrs: { jid } }))
130
+ }])
131
+ const node = getBinaryNodeChild(result, action)
132
+ return getBinaryNodeChildren(node, 'participant').map(p => ({ status: p.attrs.error || '200', jid: p.attrs.jid }))
133
+ },
134
+ communityAcceptInvite: async (code) => {
135
+ const results = await communityQuery('@g.us', 'set', [{ tag: 'invite', attrs: { code } }])
136
+ return getBinaryNodeChild(results, 'group')?.attrs.jid
137
+ },
138
+ communityInviteCode: async (jid) => {
139
+ const result = await communityQuery(jid, 'get', [{ tag: 'invite', attrs: {} }])
140
+ return getBinaryNodeChild(result, 'invite')?.attrs.code
141
+ },
142
+ communityRevokeInvite: async (jid) => {
143
+ const result = await communityQuery(jid, 'set', [{ tag: 'invite', attrs: {} }])
144
+ return getBinaryNodeChild(result, 'invite')?.attrs.code
145
+ }
146
+ }
147
+ }
@@ -0,0 +1,294 @@
1
+ import { proto } from '../../WAProto/index.js'
2
+ import { generateMessageIDV2, unixTimestampSeconds } from '../Utils/index.js'
3
+ import { getBinaryNodeChild, getBinaryNodeChildren, getBinaryNodeChildString, isLidUser, isPnUser, jidEncode, jidNormalizedUser } from '../WABinary/index.js'
4
+ import { makeChatsSocket } from './chats.js'
5
+
6
+ // ─── Metadata extraction ──────────────────────────────────────────────────────
7
+
8
+ const extractParticipants = (group) =>
9
+ getBinaryNodeChildren(group, 'participant').map(({ attrs }) => ({
10
+ id: attrs.jid,
11
+ jid: attrs.phone_number || attrs.jid,
12
+ phoneNumber: isLidUser(attrs.jid) && isPnUser(attrs.phone_number) ? attrs.phone_number : undefined,
13
+ lid: isPnUser(attrs.jid) && isLidUser(attrs.lid) ? attrs.lid : undefined,
14
+ admin: attrs.type || null
15
+ }))
16
+
17
+ const extractDescriptionFields = (group) => {
18
+ const descChild = getBinaryNodeChild(group, 'description')
19
+ if (!descChild) return {}
20
+ return {
21
+ desc: getBinaryNodeChildString(descChild, 'body'),
22
+ descId: descChild.attrs.id,
23
+ descOwner: descChild.attrs.participant ? jidNormalizedUser(descChild.attrs.participant) : undefined,
24
+ descOwnerPn: descChild.attrs.participant_pn ? jidNormalizedUser(descChild.attrs.participant_pn) : undefined,
25
+ descTime: +descChild.attrs.t,
26
+ }
27
+ }
28
+
29
+ export const extractGroupMetadata = (result) => {
30
+ const group = getBinaryNodeChild(result, 'group')
31
+ if (!group) throw new Error('Group node not found in result')
32
+ const groupId = group.attrs.id.includes('@') ? group.attrs.id : jidEncode(group.attrs.id, 'g.us')
33
+ const eph = getBinaryNodeChild(group, 'ephemeral')?.attrs.expiration
34
+ return {
35
+ id: groupId,
36
+ notify: group.attrs.notify,
37
+ addressingMode: group.attrs.addressing_mode === 'lid' ? 'lid' : 'pn',
38
+ subject: group.attrs.subject,
39
+ subjectOwner: group.attrs.s_o,
40
+ subjectOwnerPn: group.attrs.s_o_pn,
41
+ subjectTime: +group.attrs.s_t,
42
+ size: group.attrs.size ? +group.attrs.size : getBinaryNodeChildren(group, 'participant').length,
43
+ creation: +group.attrs.creation,
44
+ owner: group.attrs.creator ? jidNormalizedUser(group.attrs.creator) : undefined,
45
+ ownerPn: group.attrs.creator_pn ? jidNormalizedUser(group.attrs.creator_pn) : undefined,
46
+ owner_country_code: group.attrs.creator_country_code,
47
+ ...extractDescriptionFields(group),
48
+ linkedParent: getBinaryNodeChild(group, 'linked_parent')?.attrs.jid || undefined,
49
+ restrict: !!getBinaryNodeChild(group, 'locked'),
50
+ announce: !!getBinaryNodeChild(group, 'announcement'),
51
+ isCommunity: !!getBinaryNodeChild(group, 'parent'),
52
+ isCommunityAnnounce: !!getBinaryNodeChild(group, 'default_sub_group'),
53
+ joinApprovalMode: !!getBinaryNodeChild(group, 'membership_approval_mode'),
54
+ memberAddMode: getBinaryNodeChildString(group, 'member_add_mode') === 'all_member_add',
55
+ participants: extractParticipants(group),
56
+ ephemeralDuration: eph ? +eph : undefined
57
+ }
58
+ }
59
+
60
+ // Variant for AI groups — parses from a `create` wrapper or bare group node.
61
+ export const extractAIGroupMetadata = (result) => {
62
+ const createNode = getBinaryNodeChild(result, 'create')
63
+ const group = getBinaryNodeChild(createNode || result, 'group') || getBinaryNodeChild(result, 'group')
64
+ const groupId = group.attrs.id.includes('@') ? group.attrs.id : jidEncode(group.attrs.id, 'g.us')
65
+ const eph = getBinaryNodeChild(group, 'ephemeral')?.attrs.expiration
66
+ return {
67
+ id: groupId,
68
+ subject: group.attrs.subject,
69
+ subjectTime: +group.attrs.s_t,
70
+ creation: +group.attrs.creation,
71
+ owner: group.attrs.creator ? jidNormalizedUser(group.attrs.creator) : undefined,
72
+ ownerPn: group.attrs.creator_pn ? jidNormalizedUser(group.attrs.creator_pn) : undefined,
73
+ owner_country_code: group.attrs.creator_country_code,
74
+ size: group.attrs.size ? +group.attrs.size : getBinaryNodeChildren(group, 'participant').length,
75
+ ...extractDescriptionFields(group),
76
+ isAIGroup: true,
77
+ addressingMode: group.attrs.addressing_mode === 'lid' ? 'lid' : 'pn',
78
+ participants: extractParticipants(group),
79
+ ephemeralDuration: eph ? +eph : undefined
80
+ }
81
+ }
82
+
83
+ // ─── Socket layer ─────────────────────────────────────────────────────────────
84
+
85
+ export const makeGroupsSocket = (config) => {
86
+ const sock = makeChatsSocket(config)
87
+ const { authState, ev, query, upsertMessage, logger } = sock
88
+
89
+ // Single group query helper — used for both regular and AI groups.
90
+ const groupQuery = (jid, type, content) => query({ tag: 'iq', attrs: { type, xmlns: 'w:g2', to: jid }, content })
91
+
92
+ const groupMetadata = async (jid) => {
93
+ for (let i = 0; i < 20; i++) {
94
+ try {
95
+ const result = await groupQuery(jid, 'get', [{ tag: 'query', attrs: { request: 'interactive' } }])
96
+ return extractGroupMetadata(result)
97
+ } catch (error) {
98
+ if (error?.data === 429 || error?.isRateLimit) {
99
+ await new Promise(r => setTimeout(r, 300 + Math.random() * 700))
100
+ continue
101
+ }
102
+ throw error
103
+ }
104
+ }
105
+ }
106
+
107
+ const aiGroupMetadata = async (jid) =>
108
+ extractAIGroupMetadata(await groupQuery(jid, 'get', [{ tag: 'query', attrs: { request: 'interactive' } }]))
109
+
110
+ sock.ws.on('CB:notification,w:gp2', async node => {
111
+ const { attrs, content } = node
112
+ if (!Array.isArray(content) || content.length === 0) return
113
+ const inner = content[0]
114
+ const tag = inner.tag
115
+ const groupId = typeof attrs.from === 'string' ? attrs.from : attrs.from?.$1?.user ? jidEncode(attrs.from.$1.user, 'g.us') : undefined
116
+ if (!groupId) return
117
+ if (tag === 'create') {
118
+ try { ev.emit('groups.upsert', [await aiGroupMetadata(groupId)]) } catch { ev.emit('groups.upsert', [{ id: groupId }]) }
119
+ } else if (['promote', 'demote', 'remove', 'add'].includes(tag)) {
120
+ const participants = getBinaryNodeChildren(inner, 'participant').map(p => {
121
+ const jid = p.attrs.jid
122
+ if (typeof jid === 'string') return jid
123
+ if (jid?.$1) return jidEncode(jid.$1.user, jid.$1.server || 's.whatsapp.net')
124
+ return undefined
125
+ }).filter(Boolean)
126
+ ev.emit('group-participants.update', { id: groupId, participants, action: tag })
127
+ } else if (tag === 'subject') {
128
+ ev.emit('groups.update', [{ id: groupId, subject: inner.attrs?.subject }])
129
+ }
130
+ await sock.sendMessageAck(node)
131
+ })
132
+
133
+ const groupFetchAllParticipating = async () => {
134
+ const result = await query({
135
+ tag: 'iq',
136
+ attrs: { to: '@g.us', xmlns: 'w:g2', type: 'get' },
137
+ content: [{ tag: 'participating', attrs: {}, content: [{ tag: 'participants', attrs: {} }, { tag: 'description', attrs: {} }] }]
138
+ })
139
+ const data = {}
140
+ const groupsChild = getBinaryNodeChild(result, 'groups')
141
+ if (groupsChild) {
142
+ for (const groupNode of getBinaryNodeChildren(groupsChild, 'group')) {
143
+ const meta = extractGroupMetadata({ tag: 'result', attrs: {}, content: [groupNode] })
144
+ data[meta.id] = meta
145
+ }
146
+ }
147
+ sock.ev.emit('groups.update', Object.values(data))
148
+ return data
149
+ }
150
+
151
+ sock.ws.on('CB:ib,,dirty', async (node) => {
152
+ const { attrs } = getBinaryNodeChild(node, 'dirty')
153
+ if (attrs.type !== 'groups') return
154
+ await groupFetchAllParticipating()
155
+ await sock.cleanDirtyBits('groups')
156
+ })
157
+
158
+ return {
159
+ ...sock,
160
+ groupMetadata,
161
+ groupCreate: async (subject, participants) => {
162
+ const key = generateMessageIDV2()
163
+ const result = await groupQuery('@g.us', 'set', [{ tag: 'create', attrs: { subject, key }, content: participants.map(jid => ({ tag: 'participant', attrs: { jid } })) }])
164
+ return extractGroupMetadata(result)
165
+ },
166
+ groupLeave: async (id) => {
167
+ await groupQuery('@g.us', 'set', [{ tag: 'leave', attrs: {}, content: [{ tag: 'group', attrs: { id } }] }])
168
+ },
169
+ groupUpdateSubject: async (jid, subject) => {
170
+ await groupQuery(jid, 'set', [{ tag: 'subject', attrs: {}, content: Buffer.from(subject, 'utf-8') }])
171
+ },
172
+ groupRequestParticipantsList: async (jid) => {
173
+ const result = await groupQuery(jid, 'get', [{ tag: 'membership_approval_requests', attrs: {} }])
174
+ const node = getBinaryNodeChild(result, 'membership_approval_requests')
175
+ return getBinaryNodeChildren(node, 'membership_approval_request').map(v => v.attrs)
176
+ },
177
+ groupRequestParticipantsUpdate: async (jid, participants, action) => {
178
+ const result = await groupQuery(jid, 'set', [{
179
+ tag: 'membership_requests_action',
180
+ attrs: {},
181
+ content: [{ tag: action, attrs: {}, content: participants.map(jid => ({ tag: 'participant', attrs: { jid } })) }]
182
+ }])
183
+ const node = getBinaryNodeChild(result, 'membership_requests_action')
184
+ const nodeAction = getBinaryNodeChild(node, action)
185
+ return getBinaryNodeChildren(nodeAction, 'participant').map(p => ({ status: p.attrs.error || '200', jid: p.attrs.jid }))
186
+ },
187
+ groupParticipantsUpdate: async (jid, participants, action) => {
188
+ const result = await groupQuery(jid, 'set', [{ tag: action, attrs: {}, content: participants.map(jid => ({ tag: 'participant', attrs: { jid } })) }])
189
+ const node = getBinaryNodeChild(result, action)
190
+ return getBinaryNodeChildren(node, 'participant').map(p => ({ status: p.attrs.error || '200', jid: p.attrs.jid, content: p }))
191
+ },
192
+ groupUpdateDescription: async (jid, description) => {
193
+ const metadata = await groupMetadata(jid)
194
+ const prev = metadata.descId ?? null
195
+ await groupQuery(jid, 'set', [{
196
+ tag: 'description',
197
+ attrs: {
198
+ ...(description ? { id: generateMessageIDV2() } : { delete: 'true' }),
199
+ ...(prev ? { prev } : {})
200
+ },
201
+ content: description ? [{ tag: 'body', attrs: {}, content: Buffer.from(description, 'utf-8') }] : undefined
202
+ }])
203
+ },
204
+ groupInviteCode: async (jid) => {
205
+ const result = await groupQuery(jid, 'get', [{ tag: 'invite', attrs: {} }])
206
+ return getBinaryNodeChild(result, 'invite')?.attrs.code
207
+ },
208
+ groupRevokeInvite: async (jid) => {
209
+ const result = await groupQuery(jid, 'set', [{ tag: 'invite', attrs: {} }])
210
+ return getBinaryNodeChild(result, 'invite')?.attrs.code
211
+ },
212
+ groupAcceptInvite: async (code) => {
213
+ const results = await groupQuery('@g.us', 'set', [{ tag: 'invite', attrs: { code } }])
214
+ return getBinaryNodeChild(results, 'group')?.attrs.jid
215
+ },
216
+ groupRevokeInviteV4: async (groupJid, invitedJid) => {
217
+ const result = await groupQuery(groupJid, 'set', [{ tag: 'revoke', attrs: {}, content: [{ tag: 'participant', attrs: { jid: invitedJid } }] }])
218
+ return !!result
219
+ },
220
+ groupAcceptInviteV4: ev.createBufferedFunction(async (key, inviteMessage) => {
221
+ key = typeof key === 'string' ? { remoteJid: key } : key
222
+ const results = await groupQuery(inviteMessage.groupJid, 'set', [{
223
+ tag: 'accept',
224
+ attrs: { code: inviteMessage.inviteCode, expiration: inviteMessage.inviteExpiration.toString(), admin: key.remoteJid }
225
+ }])
226
+ if (key.id) {
227
+ const expired = proto.Message.GroupInviteMessage.fromObject(inviteMessage)
228
+ expired.inviteExpiration = 0
229
+ expired.inviteCode = ''
230
+ ev.emit('messages.update', [{ key, update: { message: { groupInviteMessage: expired } } }])
231
+ }
232
+ await upsertMessage({
233
+ key: { remoteJid: inviteMessage.groupJid, id: generateMessageIDV2(sock.user?.id), fromMe: false, participant: key.remoteJid },
234
+ messageStubType: proto.WebMessageInfo.StubType.GROUP_PARTICIPANT_ADD,
235
+ messageStubParameters: [JSON.stringify(authState.creds.me)],
236
+ participant: key.remoteJid,
237
+ messageTimestamp: unixTimestampSeconds()
238
+ }, 'notify')
239
+ return results.attrs.from
240
+ }),
241
+ groupGetInviteInfo: async (code) => {
242
+ const results = await groupQuery('@g.us', 'get', [{ tag: 'invite', attrs: { code } }])
243
+ return extractGroupMetadata(results)
244
+ },
245
+ groupToggleEphemeral: async (jid, ephemeralExpiration) => {
246
+ const content = ephemeralExpiration
247
+ ? { tag: 'ephemeral', attrs: { expiration: ephemeralExpiration.toString() } }
248
+ : { tag: 'not_ephemeral', attrs: {} }
249
+ await groupQuery(jid, 'set', [content])
250
+ },
251
+ groupSettingUpdate: async (jid, setting) => {
252
+ await groupQuery(jid, 'set', [{ tag: setting, attrs: {} }])
253
+ },
254
+ groupMemberAddMode: async (jid, mode) => {
255
+ await groupQuery(jid, 'set', [{ tag: 'member_add_mode', attrs: {}, content: mode }])
256
+ },
257
+ groupJoinApprovalMode: async (jid, mode) => {
258
+ await groupQuery(jid, 'set', [{ tag: 'membership_approval_mode', attrs: {}, content: [{ tag: 'group_join', attrs: { state: mode } }] }])
259
+ },
260
+ groupFetchAllParticipating,
261
+ aiGroupMetadata,
262
+ aiGroupCreate: async (subject, participants = [], options = {}) => {
263
+ const key = generateMessageIDV2()
264
+ const { autoAddBot = true, botUser = '867051314767696' } = options
265
+ const groupNode = await groupQuery('@g.us', 'set', [{ tag: 'create', attrs: { subject, key }, content: participants.map(jid => ({ tag: 'participant', attrs: { jid } })) }])
266
+ const metadata = extractAIGroupMetadata(groupNode)
267
+ if (autoAddBot !== false && metadata?.id) {
268
+ try {
269
+ await groupQuery(metadata.id, 'set', [{ tag: 'add', attrs: {}, content: [{ tag: 'participant', attrs: { jid: `${botUser}@bot` } }] }])
270
+ } catch (err) {
271
+ logger.warn({ err, jid: metadata.id }, 'failed to auto-add AI bot after group creation')
272
+ }
273
+ }
274
+ return metadata
275
+ },
276
+ aiGroupAddBot: async (jid, botUser = '867051314767696') => {
277
+ const result = await groupQuery(jid, 'set', [{ tag: 'add', attrs: {}, content: [{ tag: 'participant', attrs: { jid: `${botUser}@bot` } }] }])
278
+ const node = getBinaryNodeChild(result, 'add')
279
+ return getBinaryNodeChildren(node, 'participant').map(p => ({ status: p.attrs.error || '200', jid: p.attrs.jid }))
280
+ },
281
+ aiGroupLeave: async (id) => groupQuery('@g.us', 'set', [{ tag: 'leave', attrs: {}, content: [{ tag: 'group', attrs: { id } }] }]),
282
+ aiGroupParticipantsUpdate: async (jid, participants, action) => {
283
+ const result = await groupQuery(jid, 'set', [{ tag: action, attrs: {}, content: participants.map(jid => ({ tag: 'participant', attrs: { jid } })) }])
284
+ const node = getBinaryNodeChild(result, action)
285
+ return getBinaryNodeChildren(node, 'participant').map(p => ({ status: p.attrs.error || '200', jid: p.attrs.jid }))
286
+ },
287
+ aiGroupUpdateSubject: async (jid, subject) => groupQuery(jid, 'set', [{ tag: 'subject', attrs: {}, content: Buffer.from(subject, 'utf-8') }]),
288
+ aiGroupInviteCode: async (jid) => getBinaryNodeChild(await groupQuery(jid, 'get', [{ tag: 'invite', attrs: {} }]), 'invite')?.attrs.code,
289
+ aiGroupRevokeInvite: async (jid) => getBinaryNodeChild(await groupQuery(jid, 'set', [{ tag: 'invite', attrs: {} }]), 'invite')?.attrs.code,
290
+ aiGroupAcceptInvite: async (code) => getBinaryNodeChild(await groupQuery('@g.us', 'set', [{ tag: 'invite', attrs: { code } }]), 'group')?.attrs.jid,
291
+ aiGroupSettingUpdate: async (jid, setting) => groupQuery(jid, 'set', [{ tag: setting, attrs: {} }]),
292
+ aiGroupToggleEphemeral: async (jid, ephemeralExpiration) => groupQuery(jid, 'set', [ephemeralExpiration ? { tag: 'ephemeral', attrs: { expiration: ephemeralExpiration.toString() } } : { tag: 'not_ephemeral', attrs: {} }]),
293
+ }
294
+ }
@@ -0,0 +1,15 @@
1
+ import { DEFAULT_CONNECTION_CONFIG } from '../Defaults/index.js'
2
+ import { makeMessageBuilderSocket } from './nexus-handler.js'
3
+
4
+ const makeWASocket = (config) => {
5
+ const newConfig = { ...DEFAULT_CONNECTION_CONFIG, ...config }
6
+ if (config.shouldSyncHistoryMessage === undefined) {
7
+ newConfig.shouldSyncHistoryMessage = () => !!newConfig.syncFullHistory
8
+ }
9
+ return makeMessageBuilderSocket(newConfig)
10
+ }
11
+
12
+ export * from './chats.js'
13
+ export * from './nexus-handler.js'
14
+ export { makeWASocket }
15
+ export default makeWASocket