UNPKG

@faouzkk/baileys

Version:

A WebSockets library for interacting with WhatsApp Web

438 lines 19.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.extractCommunityMetadata = exports.makeCommunitiesSocket = void 0; const index_js_1 = require("../../WAProto/index.js"); const Types_1 = require("../Types"); const Utils_1 = require("../Utils"); const logger_1 = __importDefault(require("../Utils/logger")); const WABinary_1 = require("../WABinary"); const business_1 = require("./business"); const makeCommunitiesSocket = (config) => { const sock = (0, business_1.makeBusinessSocket)(config); const { authState, ev, query, upsertMessage } = sock; const communityQuery = async (jid, type, content) => query({ tag: 'iq', attrs: { type, xmlns: 'w:g2', to: jid }, content }); const communityMetadata = async (jid) => { const result = await communityQuery(jid, 'get', [{ tag: 'query', attrs: { request: 'interactive' } }]); return (0, exports.extractCommunityMetadata)(result); }; const communityFetchAllParticipating = async () => { const result = await query({ tag: 'iq', attrs: { to: '@g.us', xmlns: 'w:g2', type: 'get' }, content: [ { tag: 'participating', attrs: {}, content: [ { tag: 'participants', attrs: {} }, { tag: 'description', attrs: {} } ] } ] }); const data = {}; const communitiesChild = (0, WABinary_1.getBinaryNodeChild)(result, 'communities'); if (communitiesChild) { const communities = (0, WABinary_1.getBinaryNodeChildren)(communitiesChild, 'community'); for (const communityNode of communities) { const meta = (0, exports.extractCommunityMetadata)({ tag: 'result', attrs: {}, content: [communityNode] }); data[meta.id] = meta; } } sock.ev.emit('groups.update', Object.values(data)); return data; }; async function parseGroupResult(node) { logger_1.default.info({ node }, 'parseGroupResult'); const groupNode = (0, WABinary_1.getBinaryNodeChild)(node, 'group'); if (groupNode) { try { logger_1.default.info({ groupNode }, 'groupNode'); const metadata = await sock.groupMetadata(`${groupNode.attrs.id}@g.us`); return metadata ? metadata : Optional.empty(); } catch (error) { console.error('Error parsing group metadata:', error); return Optional.empty(); } } return Optional.empty(); } const Optional = { empty: () => null, of: (value) => (value !== null ? { value } : null) }; sock.ws.on('CB:ib,,dirty', async (node) => { const { attrs } = (0, WABinary_1.getBinaryNodeChild)(node, 'dirty'); if (attrs.type !== 'communities') { return; } await communityFetchAllParticipating(); await sock.cleanDirtyBits('groups'); }); return { ...sock, communityMetadata, communityCreate: async (subject, body) => { const descriptionId = (0, Utils_1.generateMessageID)().substring(0, 12); const result = await communityQuery('@g.us', 'set', [ { tag: 'create', attrs: { subject }, content: [ { tag: 'description', attrs: { id: descriptionId }, content: [ { tag: 'body', attrs: {}, content: Buffer.from(body || '', 'utf-8') } ] }, { tag: 'parent', attrs: { default_membership_approval_mode: 'request_required' } }, { tag: 'allow_non_admin_sub_group_creation', attrs: {} }, { tag: 'create_general_chat', attrs: {} } ] } ]); return await parseGroupResult(result); }, communityCreateGroup: async (subject, participants, parentCommunityJid) => { const key = (0, Utils_1.generateMessageIDV2)(); const result = await communityQuery('@g.us', 'set', [ { tag: 'create', attrs: { subject, key }, content: [ ...participants.map(jid => ({ tag: 'participant', attrs: { jid } })), { tag: 'linked_parent', attrs: { jid: parentCommunityJid } } ] } ]); return await parseGroupResult(result); }, communityLeave: async (id) => { await communityQuery('@g.us', 'set', [ { tag: 'leave', attrs: {}, content: [{ tag: 'community', attrs: { id } }] } ]); }, communityUpdateSubject: async (jid, subject) => { await communityQuery(jid, 'set', [ { tag: 'subject', attrs: {}, content: Buffer.from(subject, 'utf-8') } ]); }, communityLinkGroup: async (groupJid, parentCommunityJid) => { await communityQuery(parentCommunityJid, 'set', [ { tag: 'links', attrs: {}, content: [ { tag: 'link', attrs: { link_type: 'sub_group' }, content: [{ tag: 'group', attrs: { jid: groupJid } }] } ] } ]); }, communityUnlinkGroup: async (groupJid, parentCommunityJid) => { await communityQuery(parentCommunityJid, 'set', [ { tag: 'unlink', attrs: { unlink_type: 'sub_group' }, content: [{ tag: 'group', attrs: { jid: groupJid } }] } ]); }, communityFetchLinkedGroups: async (jid) => { let communityJid = jid; let isCommunity = false; // Try to determine if it is a subgroup or a community const metadata = await sock.groupMetadata(jid); if (metadata.linkedParent) { // It is a subgroup, get the community jid communityJid = metadata.linkedParent; } else { // It is a community isCommunity = true; } // Fetch all subgroups of the community const result = await communityQuery(communityJid, 'get', [{ tag: 'sub_groups', attrs: {} }]); const linkedGroupsData = []; const subGroupsNode = (0, WABinary_1.getBinaryNodeChild)(result, 'sub_groups'); if (subGroupsNode) { const groupNodes = (0, WABinary_1.getBinaryNodeChildren)(subGroupsNode, 'group'); for (const groupNode of groupNodes) { linkedGroupsData.push({ id: groupNode.attrs.id ? (0, WABinary_1.jidEncode)(groupNode.attrs.id, 'g.us') : undefined, subject: groupNode.attrs.subject || '', creation: groupNode.attrs.creation ? Number(groupNode.attrs.creation) : undefined, owner: groupNode.attrs.creator ? (0, WABinary_1.jidNormalizedUser)(groupNode.attrs.creator) : undefined, size: groupNode.attrs.size ? Number(groupNode.attrs.size) : undefined }); } } return { communityJid, isCommunity, linkedGroups: linkedGroupsData }; }, communityRequestParticipantsList: async (jid) => { const result = await communityQuery(jid, 'get', [ { tag: 'membership_approval_requests', attrs: {} } ]); const node = (0, WABinary_1.getBinaryNodeChild)(result, 'membership_approval_requests'); const participants = (0, WABinary_1.getBinaryNodeChildren)(node, 'membership_approval_request'); return participants.map(v => v.attrs); }, communityRequestParticipantsUpdate: async (jid, participants, action) => { const result = await communityQuery(jid, 'set', [ { tag: 'membership_requests_action', attrs: {}, content: [ { tag: action, attrs: {}, content: participants.map(jid => ({ tag: 'participant', attrs: { jid } })) } ] } ]); const node = (0, WABinary_1.getBinaryNodeChild)(result, 'membership_requests_action'); const nodeAction = (0, WABinary_1.getBinaryNodeChild)(node, action); const participantsAffected = (0, WABinary_1.getBinaryNodeChildren)(nodeAction, 'participant'); return participantsAffected.map(p => { return { status: p.attrs.error || '200', jid: p.attrs.jid }; }); }, communityParticipantsUpdate: async (jid, participants, action) => { const result = await communityQuery(jid, 'set', [ { tag: action, attrs: {}, content: participants.map(jid => ({ tag: 'participant', attrs: { jid } })) } ]); const node = (0, WABinary_1.getBinaryNodeChild)(result, action); const participantsAffected = (0, WABinary_1.getBinaryNodeChildren)(node, 'participant'); return participantsAffected.map(p => { return { status: p.attrs.error || '200', jid: p.attrs.jid, content: p }; }); }, communityUpdateDescription: async (jid, description) => { const metadata = await communityMetadata(jid); const prev = metadata.descId ?? null; await communityQuery(jid, 'set', [ { tag: 'description', attrs: { ...(description ? { id: (0, Utils_1.generateMessageID)() } : { delete: 'true' }), ...(prev ? { prev } : {}) }, content: description ? [{ tag: 'body', attrs: {}, content: Buffer.from(description, 'utf-8') }] : undefined } ]); }, communityInviteCode: async (jid) => { const result = await communityQuery(jid, 'get', [{ tag: 'invite', attrs: {} }]); const inviteNode = (0, WABinary_1.getBinaryNodeChild)(result, 'invite'); return inviteNode?.attrs.code; }, communityRevokeInvite: async (jid) => { const result = await communityQuery(jid, 'set', [{ tag: 'invite', attrs: {} }]); const inviteNode = (0, WABinary_1.getBinaryNodeChild)(result, 'invite'); return inviteNode?.attrs.code; }, communityAcceptInvite: async (code) => { const results = await communityQuery('@g.us', 'set', [{ tag: 'invite', attrs: { code } }]); const result = (0, WABinary_1.getBinaryNodeChild)(results, 'community'); return result?.attrs.jid; }, /** * revoke a v4 invite for someone * @param communityJid community jid * @param invitedJid jid of person you invited * @returns true if successful */ communityRevokeInviteV4: async (communityJid, invitedJid) => { const result = await communityQuery(communityJid, 'set', [ { tag: 'revoke', attrs: {}, content: [{ tag: 'participant', attrs: { jid: invitedJid } }] } ]); return !!result; }, /** * accept a CommunityInviteMessage * @param key the key of the invite message, or optionally only provide the jid of the person who sent the invite * @param inviteMessage the message to accept */ communityAcceptInviteV4: ev.createBufferedFunction(async (key, inviteMessage) => { key = typeof key === 'string' ? { remoteJid: key } : key; const results = await communityQuery(inviteMessage.groupJid, 'set', [ { tag: 'accept', attrs: { code: inviteMessage.inviteCode, expiration: inviteMessage.inviteExpiration.toString(), admin: key.remoteJid } } ]); // if we have the full message key // update the invite message to be expired if (key.id) { // create new invite message that is expired inviteMessage = index_js_1.proto.Message.GroupInviteMessage.create(inviteMessage); inviteMessage.inviteExpiration = 0; inviteMessage.inviteCode = ''; ev.emit('messages.update', [ { key, update: { message: { groupInviteMessage: inviteMessage } } } ]); } // generate the community add message await upsertMessage({ key: { remoteJid: inviteMessage.groupJid, id: (0, Utils_1.generateMessageIDV2)(sock.user?.id), fromMe: false, participant: key.remoteJid }, messageStubType: Types_1.WAMessageStubType.GROUP_PARTICIPANT_ADD, messageStubParameters: [authState.creds.me.id], participant: key.remoteJid, messageTimestamp: (0, Utils_1.unixTimestampSeconds)() }, 'notify'); return results.attrs.from; }), communityGetInviteInfo: async (code) => { const results = await communityQuery('@g.us', 'get', [{ tag: 'invite', attrs: { code } }]); return (0, exports.extractCommunityMetadata)(results); }, communityToggleEphemeral: async (jid, ephemeralExpiration) => { const content = ephemeralExpiration ? { tag: 'ephemeral', attrs: { expiration: ephemeralExpiration.toString() } } : { tag: 'not_ephemeral', attrs: {} }; await communityQuery(jid, 'set', [content]); }, communitySettingUpdate: async (jid, setting) => { await communityQuery(jid, 'set', [{ tag: setting, attrs: {} }]); }, communityMemberAddMode: async (jid, mode) => { await communityQuery(jid, 'set', [{ tag: 'member_add_mode', attrs: {}, content: mode }]); }, communityJoinApprovalMode: async (jid, mode) => { await communityQuery(jid, 'set', [ { tag: 'membership_approval_mode', attrs: {}, content: [{ tag: 'community_join', attrs: { state: mode } }] } ]); }, communityFetchAllParticipating }; }; exports.makeCommunitiesSocket = makeCommunitiesSocket; const extractCommunityMetadata = (result) => { const community = (0, WABinary_1.getBinaryNodeChild)(result, 'community'); const descChild = (0, WABinary_1.getBinaryNodeChild)(community, 'description'); let desc; let descId; if (descChild) { desc = (0, WABinary_1.getBinaryNodeChildString)(descChild, 'body'); descId = descChild.attrs.id; } const communityId = community.attrs.id?.includes('@') ? community.attrs.id : (0, WABinary_1.jidEncode)(community.attrs.id || '', 'g.us'); const eph = (0, WABinary_1.getBinaryNodeChild)(community, 'ephemeral')?.attrs.expiration; const memberAddMode = (0, WABinary_1.getBinaryNodeChildString)(community, 'member_add_mode') === 'all_member_add'; const metadata = { id: communityId, subject: community.attrs.subject || '', subjectOwner: community.attrs.s_o, subjectTime: Number(community.attrs.s_t || 0), size: (0, WABinary_1.getBinaryNodeChildren)(community, 'participant').length, creation: Number(community.attrs.creation || 0), owner: community.attrs.creator ? (0, WABinary_1.jidNormalizedUser)(community.attrs.creator) : undefined, desc, descId, linkedParent: (0, WABinary_1.getBinaryNodeChild)(community, 'linked_parent')?.attrs.jid || undefined, restrict: !!(0, WABinary_1.getBinaryNodeChild)(community, 'locked'), announce: !!(0, WABinary_1.getBinaryNodeChild)(community, 'announcement'), isCommunity: !!(0, WABinary_1.getBinaryNodeChild)(community, 'parent'), isCommunityAnnounce: !!(0, WABinary_1.getBinaryNodeChild)(community, 'default_sub_community'), joinApprovalMode: !!(0, WABinary_1.getBinaryNodeChild)(community, 'membership_approval_mode'), memberAddMode, participants: (0, WABinary_1.getBinaryNodeChildren)(community, 'participant').map(({ attrs }) => { return { id: attrs.jid, admin: (attrs.type || null) }; }), ephemeralDuration: eph ? +eph : undefined, addressingMode: (0, WABinary_1.getBinaryNodeChildString)(community, 'addressing_mode') }; return metadata; }; exports.extractCommunityMetadata = extractCommunityMetadata; //# sourceMappingURL=communities.js.map