feat: group membership requests (#2516)
* added event for group membership request * small update to improve the performance of findImpl fix * window.compareWwebVersions fixed * added getGroupMembershipRequests method * added approveGroupMembershipRequest method * correct module for getGroupMembershipRequests * membershipRequestAction separated to Injected.js * docs clarification for approveGroupMembershipRequest * added rejectGroupMembershipRequest method * module fixed * methods extension * docs clarification * force to update group membership requests * docs fixed * added usage example * avoid sleep after the last iteration * fix: added missing modules * improve forcing to update group membership requests * usage example clarification * module refactored * optional parameters * usage example modified * remove default values for membershipRequestAction * added error description for memb req action * usage example fixed * return result even if ServerStatusCodeError * default error message was missing * removed line break
This commit is contained in:
parent
ecf19eb9a5
commit
56320c88f8
6 changed files with 373 additions and 16 deletions
72
example.js
72
example.js
|
|
@ -239,6 +239,52 @@ client.on('message', async msg => {
|
|||
} else if (msg.body === '!removelabels') {
|
||||
const chat = await msg.getChat();
|
||||
await chat.changeLabels([]);
|
||||
} else if (msg.body === '!approverequest') {
|
||||
/**
|
||||
* Presented an example for membership request approvals, the same examples are for the request rejections.
|
||||
* To approve the membership request from a specific user:
|
||||
*/
|
||||
await client.approveGroupMembershipRequests(msg.from, { requesterIds: 'number@c.us' });
|
||||
/** The same for execution on group object (no need to provide the group ID): */
|
||||
const group = await msg.getChat();
|
||||
await group.approveGroupMembershipRequests({ requesterIds: 'number@c.us' });
|
||||
/** To approve several membership requests: */
|
||||
const approval = await client.approveGroupMembershipRequests(msg.from, {
|
||||
requesterIds: ['number1@c.us', 'number2@c.us']
|
||||
});
|
||||
/**
|
||||
* The example of the {@link approval} output:
|
||||
* [
|
||||
* {
|
||||
* requesterId: 'number1@c.us',
|
||||
* message: 'Rejected successfully'
|
||||
* },
|
||||
* {
|
||||
* requesterId: 'number2@c.us',
|
||||
* error: 404,
|
||||
* message: 'ParticipantRequestNotFoundError'
|
||||
* }
|
||||
* ]
|
||||
*
|
||||
*/
|
||||
console.log(approval);
|
||||
/** To approve all the existing membership requests (simply don't provide any user IDs): */
|
||||
await client.approveGroupMembershipRequests(msg.from);
|
||||
/** To change the sleep value to 300 ms: */
|
||||
await client.approveGroupMembershipRequests(msg.from, {
|
||||
requesterIds: ['number1@c.us', 'number2@c.us'],
|
||||
sleep: 300
|
||||
});
|
||||
/** To change the sleep value to random value between 100 and 300 ms: */
|
||||
await client.approveGroupMembershipRequests(msg.from, {
|
||||
requesterIds: ['number1@c.us', 'number2@c.us'],
|
||||
sleep: [100, 300]
|
||||
});
|
||||
/** To explicitly disable the sleep: */
|
||||
await client.approveGroupMembershipRequests(msg.from, {
|
||||
requesterIds: ['number1@c.us', 'number2@c.us'],
|
||||
sleep: null
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -360,3 +406,29 @@ client.on('group_admin_changed', (notification) => {
|
|||
/** Emitted when a current user is demoted to a regular user. */
|
||||
console.log(`You were demoted by ${notification.author}`);
|
||||
});
|
||||
|
||||
client.on('group_membership_request', async (notification) => {
|
||||
/**
|
||||
* The example of the {@link notification} output:
|
||||
* {
|
||||
* id: {
|
||||
* fromMe: false,
|
||||
* remote: 'groupId@g.us',
|
||||
* id: '123123123132132132',
|
||||
* participant: 'number@c.us',
|
||||
* _serialized: 'false_groupId@g.us_123123123132132132_number@c.us'
|
||||
* },
|
||||
* body: '',
|
||||
* type: 'created_membership_requests',
|
||||
* timestamp: 1694456538,
|
||||
* chatId: 'groupId@g.us',
|
||||
* author: 'number@c.us',
|
||||
* recipientIds: []
|
||||
* }
|
||||
*
|
||||
*/
|
||||
console.log(notification);
|
||||
/** You can approve or reject the newly appeared membership request: */
|
||||
await client.approveGroupMembershipRequestss(notification.chatId, notification.author);
|
||||
await client.rejectGroupMembershipRequests(notification.chatId, notification.author);
|
||||
});
|
||||
68
index.d.ts
vendored
68
index.d.ts
vendored
|
|
@ -160,6 +160,15 @@ declare namespace WAWebJS {
|
|||
/** Deletes the current user's profile picture */
|
||||
deleteProfilePicture(): Promise<boolean>
|
||||
|
||||
/** Gets an array of membership requests */
|
||||
getGroupMembershipRequests: (groupId: string) => Promise<Array<GroupMembershipRequest>>
|
||||
|
||||
/** Approves membership requests if any */
|
||||
approveGroupMembershipRequests: (groupId: string, options: MembershipRequestActionOptions) => Promise<Array<MembershipRequestActionResult>>;
|
||||
|
||||
/** Rejects membership requests if any */
|
||||
rejectGroupMembershipRequests: (groupId: string, options: MembershipRequestActionOptions) => Promise<Array<MembershipRequestActionResult>>;
|
||||
|
||||
/** Generic event */
|
||||
on(event: string, listener: (...args: any) => void): this
|
||||
|
||||
|
|
@ -210,6 +219,15 @@ declare namespace WAWebJS {
|
|||
notification: GroupNotification
|
||||
) => void): this
|
||||
|
||||
/**
|
||||
* Emitted when some user requested to join the group
|
||||
* that has the membership approval mode turned on
|
||||
*/
|
||||
on(event: 'group_membership_request', listener: (
|
||||
/** GroupNotification with more information about the action */
|
||||
notification: GroupNotification
|
||||
) => void): this
|
||||
|
||||
/** Emitted when group settings are updated, such as subject, description or picture */
|
||||
on(event: 'group_update', listener: (
|
||||
/** GroupNotification with more information about the action */
|
||||
|
|
@ -589,6 +607,7 @@ declare namespace WAWebJS {
|
|||
GROUP_JOIN = 'group_join',
|
||||
GROUP_LEAVE = 'group_leave',
|
||||
GROUP_ADMIN_CHANGED = 'group_admin_changed',
|
||||
GROUP_MEMBERSHIP_REQUEST = 'group_membership_request',
|
||||
GROUP_UPDATE = 'group_update',
|
||||
QR_RECEIVED = 'qr',
|
||||
LOADING_SCREEN = 'loading_screen',
|
||||
|
|
@ -1252,6 +1271,38 @@ declare namespace WAWebJS {
|
|||
[key: string]: number;
|
||||
}>
|
||||
|
||||
/** An object that handles the information about the group membership request */
|
||||
export interface GroupMembershipRequest {
|
||||
/** The wid of a user who requests to enter the group */
|
||||
id: Object;
|
||||
/** The wid of a user who created that request */
|
||||
addedBy: Object;
|
||||
/** The wid of a community parent group to which the current group is linked */
|
||||
parentGroupId: Object | null;
|
||||
/** The method used to create the request: NonAdminAdd/InviteLink/LinkedGroupJoin */
|
||||
requestMethod: string,
|
||||
/** The timestamp the request was created at */
|
||||
t: number
|
||||
}
|
||||
|
||||
/** An object that handles the result for membership request action */
|
||||
export interface MembershipRequestActionResult {
|
||||
/** User ID whos membership request was approved/rejected */
|
||||
requesterId: Array<string> | string | null;
|
||||
/** An error code that occurred during the operation for the participant */
|
||||
error?: number;
|
||||
/** A message with a result of membership request action */
|
||||
message: string;
|
||||
}
|
||||
|
||||
/** Options for performing a membership request action */
|
||||
export interface MembershipRequestActionOptions {
|
||||
/** User ID/s who requested to join the group, if no value is provided, the method will search for all membership requests for that group */
|
||||
requesterIds: Array<string> | string | null;
|
||||
/** The number of milliseconds to wait before performing an operation for the next requester. If it is an array, a random sleep time between the sleep[0] and sleep[1] values will be added (the difference must be >=100 ms, otherwise, a random sleep time between sleep[1] and sleep[1] + 100 will be added). If sleep is a number, a sleep time equal to its value will be added. By default, sleep is an array with a value of [250, 500] */
|
||||
sleep: Array<number> | number | null;
|
||||
}
|
||||
|
||||
export interface GroupChat extends Chat {
|
||||
/** Group owner */
|
||||
owner: ContactId;
|
||||
|
|
@ -1284,6 +1335,23 @@ declare namespace WAWebJS {
|
|||
* @returns {Promise<boolean>} Returns true if the setting was properly updated. This can return false if the user does not have the necessary permissions.
|
||||
*/
|
||||
setInfoAdminsOnly: (adminsOnly?: boolean) => Promise<boolean>;
|
||||
/**
|
||||
* Gets an array of membership requests
|
||||
* @returns {Promise<Array<GroupMembershipRequest>>} An array of membership requests
|
||||
*/
|
||||
getGroupMembershipRequests: () => Promise<Array<GroupMembershipRequest>>;
|
||||
/**
|
||||
* Approves membership requests if any
|
||||
* @param {MembershipRequestActionOptions} options Options for performing a membership request action
|
||||
* @returns {Promise<Array<MembershipRequestActionResult>>} Returns an array of requester IDs whose membership requests were approved and an error for each requester, if any occurred during the operation. If there are no requests, an empty array will be returned
|
||||
*/
|
||||
approveGroupMembershipRequests: (options: MembershipRequestActionOptions) => Promise<Array<MembershipRequestActionResult>>;
|
||||
/**
|
||||
* Rejects membership requests if any
|
||||
* @param {MembershipRequestActionOptions} options Options for performing a membership request action
|
||||
* @returns {Promise<Array<MembershipRequestActionResult>>} Returns an array of requester IDs whose membership requests were rejected and an error for each requester, if any occurred during the operation. If there are no requests, an empty array will be returned
|
||||
*/
|
||||
rejectGroupMembershipRequests: (options: MembershipRequestActionOptions) => Promise<Array<MembershipRequestActionResult>>;
|
||||
/** Gets the invite code for a specific group */
|
||||
getInviteCode: () => Promise<string>;
|
||||
/** Invalidates the current group invite code and generates a new one */
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ const NoAuth = require('./authStrategies/NoAuth');
|
|||
* @fires Client#change_state
|
||||
* @fires Client#contact_changed
|
||||
* @fires Client#group_admin_changed
|
||||
* @fires Client#group_membership_request
|
||||
*/
|
||||
class Client extends EventEmitter {
|
||||
constructor(options = {}) {
|
||||
|
|
@ -379,6 +380,17 @@ class Client extends EventEmitter {
|
|||
* @param {GroupNotification} notification GroupNotification with more information about the action
|
||||
*/
|
||||
this.emit(Events.GROUP_ADMIN_CHANGED, notification);
|
||||
} else if (msg.subtype === 'created_membership_requests') {
|
||||
/**
|
||||
* Emitted when some user requested to join the group
|
||||
* that has the membership approval mode turned on
|
||||
* @event Client#group_membership_request
|
||||
* @param {GroupNotification} notification GroupNotification with more information about the action
|
||||
* @param {string} notification.chatId The group ID the request was made for
|
||||
* @param {string} notification.author The user ID that made a request
|
||||
* @param {number} notification.timestamp The timestamp the request was made at
|
||||
*/
|
||||
this.emit(Events.GROUP_MEMBERSHIP_REQUEST, notification);
|
||||
} else {
|
||||
/**
|
||||
* Emitted when group settings are updated, such as subject, description or picture.
|
||||
|
|
@ -1434,6 +1446,69 @@ class Client extends EventEmitter {
|
|||
return await window.Store.Label.addOrRemoveLabels(actions, chats);
|
||||
}, labelIds, chatIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* An object that handles the information about the group membership request
|
||||
* @typedef {Object} GroupMembershipRequest
|
||||
* @property {Object} id The wid of a user who requests to enter the group
|
||||
* @property {Object} addedBy The wid of a user who created that request
|
||||
* @property {Object|null} parentGroupId The wid of a community parent group to which the current group is linked
|
||||
* @property {string} requestMethod The method used to create the request: NonAdminAdd/InviteLink/LinkedGroupJoin
|
||||
* @property {number} t The timestamp the request was created at
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets an array of membership requests
|
||||
* @param {string} groupId The ID of a group to get membership requests for
|
||||
* @returns {Promise<Array<GroupMembershipRequest>>} An array of membership requests
|
||||
*/
|
||||
async getGroupMembershipRequests(groupId) {
|
||||
return await this.pupPage.evaluate(async (gropId) => {
|
||||
const groupWid = window.Store.WidFactory.createWid(gropId);
|
||||
return await window.Store.MembershipRequestUtils.getMembershipApprovalRequests(groupWid);
|
||||
}, groupId);
|
||||
}
|
||||
|
||||
/**
|
||||
* An object that handles the result for membership request action
|
||||
* @typedef {Object} MembershipRequestActionResult
|
||||
* @property {string} requesterId User ID whos membership request was approved/rejected
|
||||
* @property {number|undefined} error An error code that occurred during the operation for the participant
|
||||
* @property {string} message A message with a result of membership request action
|
||||
*/
|
||||
|
||||
/**
|
||||
* An object that handles options for {@link approveGroupMembershipRequests} and {@link rejectGroupMembershipRequests} methods
|
||||
* @typedef {Object} MembershipRequestActionOptions
|
||||
* @property {Array<string>|string|null} requesterIds User ID/s who requested to join the group, if no value is provided, the method will search for all membership requests for that group
|
||||
* @property {Array<number>|number|null} sleep The number of milliseconds to wait before performing an operation for the next requester. If it is an array, a random sleep time between the sleep[0] and sleep[1] values will be added (the difference must be >=100 ms, otherwise, a random sleep time between sleep[1] and sleep[1] + 100 will be added). If sleep is a number, a sleep time equal to its value will be added. By default, sleep is an array with a value of [250, 500]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Approves membership requests if any
|
||||
* @param {string} groupId The group ID to get the membership request for
|
||||
* @param {MembershipRequestActionOptions} options Options for performing a membership request action
|
||||
* @returns {Promise<Array<MembershipRequestActionResult>>} Returns an array of requester IDs whose membership requests were approved and an error for each requester, if any occurred during the operation. If there are no requests, an empty array will be returned
|
||||
*/
|
||||
async approveGroupMembershipRequests(groupId, options = {}) {
|
||||
return await this.pupPage.evaluate(async (groupId, options) => {
|
||||
const { requesterIds = null, sleep = [250, 500] } = options;
|
||||
return await window.WWebJS.membershipRequestAction(groupId, 'Approve', requesterIds, sleep);
|
||||
}, groupId, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rejects membership requests if any
|
||||
* @param {string} groupId The group ID to get the membership request for
|
||||
* @param {MembershipRequestActionOptions} options Options for performing a membership request action
|
||||
* @returns {Promise<Array<MembershipRequestActionResult>>} Returns an array of requester IDs whose membership requests were rejected and an error for each requester, if any occurred during the operation. If there are no requests, an empty array will be returned
|
||||
*/
|
||||
async rejectGroupMembershipRequests(groupId, options = {}) {
|
||||
return await this.pupPage.evaluate(async (groupId, options) => {
|
||||
const { requesterIds = null, sleep = [250, 500] } = options;
|
||||
return await window.WWebJS.membershipRequestAction(groupId, 'Reject', requesterIds, sleep);
|
||||
}, groupId, options);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Client;
|
||||
|
|
|
|||
|
|
@ -265,6 +265,57 @@ class GroupChat extends Chat {
|
|||
return codeRes.code;
|
||||
}
|
||||
|
||||
/**
|
||||
* An object that handles the information about the group membership request
|
||||
* @typedef {Object} GroupMembershipRequest
|
||||
* @property {Object} id The wid of a user who requests to enter the group
|
||||
* @property {Object} addedBy The wid of a user who created that request
|
||||
* @property {Object|null} parentGroupId The wid of a community parent group to which the current group is linked
|
||||
* @property {string} requestMethod The method used to create the request: NonAdminAdd/InviteLink/LinkedGroupJoin
|
||||
* @property {number} t The timestamp the request was created at
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets an array of membership requests
|
||||
* @returns {Promise<Array<GroupMembershipRequest>>} An array of membership requests
|
||||
*/
|
||||
async getGroupMembershipRequests() {
|
||||
return await this.client.getGroupMembershipRequests(this.id._serialized);
|
||||
}
|
||||
|
||||
/**
|
||||
* An object that handles the result for membership request action
|
||||
* @typedef {Object} MembershipRequestActionResult
|
||||
* @property {string} requesterId User ID whos membership request was approved/rejected
|
||||
* @property {number} error An error code that occurred during the operation for the participant
|
||||
* @property {string} message A message with a result of membership request action
|
||||
*/
|
||||
|
||||
/**
|
||||
* An object that handles options for {@link approveGroupMembershipRequests} and {@link rejectGroupMembershipRequests} methods
|
||||
* @typedef {Object} MembershipRequestActionOptions
|
||||
* @property {Array<string>|string|null} requesterIds User ID/s who requested to join the group, if no value is provided, the method will search for all membership requests for that group
|
||||
* @property {Array<number>|number|null} sleep The number of milliseconds to wait before performing an operation for the next requester. If it is an array, a random sleep time between the sleep[0] and sleep[1] values will be added (the difference must be >=100 ms, otherwise, a random sleep time between sleep[1] and sleep[1] + 100 will be added). If sleep is a number, a sleep time equal to its value will be added. By default, sleep is an array with a value of [250, 500]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Approves membership requests if any
|
||||
* @param {MembershipRequestActionOptions} options Options for performing a membership request action
|
||||
* @returns {Promise<Array<MembershipRequestActionResult>>} Returns an array of requester IDs whose membership requests were approved and an error for each requester, if any occurred during the operation. If there are no requests, an empty array will be returned
|
||||
*/
|
||||
async approveGroupMembershipRequests(options = {}) {
|
||||
return await this.client.approveGroupMembershipRequests(this.id._serialized, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rejects membership requests if any
|
||||
* @param {MembershipRequestActionOptions} options Options for performing a membership request action
|
||||
* @returns {Promise<Array<MembershipRequestActionResult>>} Returns an array of requester IDs whose membership requests were rejected and an error for each requester, if any occurred during the operation. If there are no requests, an empty array will be returned
|
||||
*/
|
||||
async rejectGroupMembershipRequests(options = {}) {
|
||||
return await this.client.rejectGroupMembershipRequests(this.id._serialized, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the bot leave the group
|
||||
* @returns {Promise}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ exports.Events = {
|
|||
GROUP_JOIN: 'group_join',
|
||||
GROUP_LEAVE: 'group_leave',
|
||||
GROUP_ADMIN_CHANGED: 'group_admin_changed',
|
||||
GROUP_MEMBERSHIP_REQUEST: 'group_membership_request',
|
||||
GROUP_UPDATE: 'group_update',
|
||||
QR_RECEIVED: 'qr',
|
||||
LOADING_SCREEN: 'loading_screen',
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ exports.ExposeStore = (moduleRaidStr) => {
|
|||
window.Store.CryptoLib = window.mR.findModule('decryptE2EMedia')[0];
|
||||
window.Store.DownloadManager = window.mR.findModule('downloadManager')[0].downloadManager;
|
||||
window.Store.GroupMetadata = window.mR.findModule('GroupMetadata')[0].default.GroupMetadata;
|
||||
window.Store.GroupMetadata.queryAndUpdate = window.mR.findModule('queryAndUpdateGroupMetadataById')[0].queryAndUpdateGroupMetadataById;
|
||||
window.Store.Invite = window.mR.findModule('resetGroupInviteCode')[0];
|
||||
window.Store.InviteInfo = window.mR.findModule('queryGroupInvite')[0];
|
||||
window.Store.Label = window.mR.findModule('LabelCollection')[0].LabelCollection;
|
||||
|
|
@ -59,17 +60,22 @@ exports.ExposeStore = (moduleRaidStr) => {
|
|||
window.Store.SocketWap = window.mR.findModule('wap')[0];
|
||||
window.Store.SearchContext = window.mR.findModule('getSearchContext')[0].getSearchContext;
|
||||
window.Store.DrawerManager = window.mR.findModule('DrawerManager')[0].DrawerManager;
|
||||
window.Store.WidToJid = window.mR.findModule('widToUserJid')[0];
|
||||
window.Store.JidToWid = window.mR.findModule('userJidToUserWid')[0];
|
||||
window.Store.StickerTools = {
|
||||
...window.mR.findModule('toWebpSticker')[0],
|
||||
...window.mR.findModule('addWebpMetadata')[0]
|
||||
};
|
||||
|
||||
window.Store.GroupUtils = {
|
||||
...window.mR.findModule('createGroup')[0],
|
||||
...window.mR.findModule('setGroupDescription')[0],
|
||||
...window.mR.findModule('sendExitGroup')[0],
|
||||
...window.mR.findModule('sendSetPicture')[0]
|
||||
};
|
||||
window.Store.MembershipRequestUtils = {
|
||||
...window.mR.findModule('getMembershipApprovalRequests')[0],
|
||||
...window.mR.findModule('sendMembershipRequestsActionRPC')[0]
|
||||
};
|
||||
|
||||
if (!window.Store.Chat._find) {
|
||||
window.Store.Chat._find = e => {
|
||||
|
|
@ -83,7 +89,6 @@ exports.ExposeStore = (moduleRaidStr) => {
|
|||
// eslint-disable-next-line no-undef
|
||||
if ((m = window.mR.findModule('ChatCollection')[0]) && m.ChatCollection && typeof m.ChatCollection.findImpl === 'undefined' && typeof m.ChatCollection._find !== 'undefined') m.ChatCollection.findImpl = m.ChatCollection._find;
|
||||
|
||||
|
||||
// TODO remove these once everybody has been updated to WWebJS with legacy sessions removed
|
||||
const _linkPreview = window.mR.findModule('queryLinkPreview');
|
||||
if (_linkPreview && _linkPreview[0] && _linkPreview[0].default) {
|
||||
|
|
@ -112,8 +117,6 @@ exports.ExposeStore = (moduleRaidStr) => {
|
|||
|
||||
/**
|
||||
* Function to modify functions
|
||||
* Referenced from and modified:
|
||||
* @see https://github.com/pedroslopez/whatsapp-web.js/pull/1636/commits/81111faa058d8e715285a2bfc9a42636074f7c3d#diff-de25cb4b9105890088bb033eac000d1dd2104d3498a8523082dc7eaf319738b8R75-R78
|
||||
* @param {TargetOptions} target Options specifying the target function to search for modifying
|
||||
* @param {Function} callback Modified function
|
||||
*/
|
||||
|
|
@ -126,16 +129,8 @@ exports.ExposeStore = (moduleRaidStr) => {
|
|||
module[target.index][target.property] = modifiedFunction;
|
||||
};
|
||||
|
||||
/**
|
||||
* Referenced from and modified:
|
||||
* @see https://github.com/wppconnect-team/wa-js/blob/e19164e83cfa68b828493e6ff046c0a3d46a4942/src/chat/functions/sendLocationMessage.ts#L156
|
||||
*/
|
||||
window.injectToFunction({ moduleId: 'mediaTypeFromProtobuf', index: 0, property: 'mediaTypeFromProtobuf' }, (func, ...args) => { const [proto] = args; return proto.locationMessage ? null : func(...args); });
|
||||
|
||||
/**
|
||||
* Referenced from and modified:
|
||||
* @see https://github.com/wppconnect-team/wa-js/blob/e19164e83cfa68b828493e6ff046c0a3d46a4942/src/chat/functions/sendLocationMessage.ts#L164
|
||||
*/
|
||||
window.injectToFunction({ moduleId: 'typeAttributeFromProtobuf', index: 0, property: 'typeAttributeFromProtobuf' }, (func, ...args) => { const [proto] = args; return proto.locationMessage ? 'text' : func(...args); });
|
||||
};
|
||||
|
||||
|
|
@ -870,4 +865,99 @@ exports.LoadUtils = () => {
|
|||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
window.WWebJS.membershipRequestAction = async (groupId, action, requesterIds, sleep) => {
|
||||
const groupWid = window.Store.WidFactory.createWid(groupId);
|
||||
const group = await window.Store.Chat.find(groupWid);
|
||||
const toApprove = action === 'Approve';
|
||||
let membershipRequests;
|
||||
let response;
|
||||
let result = [];
|
||||
|
||||
await window.Store.GroupMetadata.queryAndUpdate(groupWid);
|
||||
|
||||
if (!requesterIds?.length) {
|
||||
membershipRequests = group.groupMetadata.membershipApprovalRequests._models.map(({ id }) => id);
|
||||
} else {
|
||||
!Array.isArray(requesterIds) && (requesterIds = [requesterIds]);
|
||||
membershipRequests = requesterIds.map(r => window.Store.WidFactory.createWid(r));
|
||||
}
|
||||
|
||||
if (!membershipRequests.length) return [];
|
||||
|
||||
const participantArgs = membershipRequests.map(m => ({
|
||||
participantArgs: [
|
||||
{
|
||||
participantJid: window.Store.WidToJid.widToUserJid(m)
|
||||
}
|
||||
]
|
||||
}));
|
||||
|
||||
const groupJid = window.Store.WidToJid.widToGroupJid(groupWid);
|
||||
|
||||
const _getSleepTime = (sleep) => {
|
||||
if (!Array.isArray(sleep) || (sleep.length === 2 && sleep[0] === sleep[1])) {
|
||||
return sleep;
|
||||
}
|
||||
if (sleep.length === 1) {
|
||||
return sleep[0];
|
||||
}
|
||||
sleep[1] - sleep[0] < 100 && (sleep[0] = sleep[1]) && (sleep[1] += 100);
|
||||
return Math.floor(Math.random() * (sleep[1] - sleep[0] + 1)) + sleep[0];
|
||||
};
|
||||
|
||||
const membReqResCodes = {
|
||||
default: `An unknown error occupied while ${toApprove ? 'approving' : 'rejecting'} the participant membership request`,
|
||||
400: 'ParticipantNotFoundError',
|
||||
401: 'ParticipantNotAuthorizedError',
|
||||
403: 'ParticipantForbiddenError',
|
||||
404: 'ParticipantRequestNotFoundError',
|
||||
408: 'ParticipantTemporarilyBlockedError',
|
||||
409: 'ParticipantConflictError',
|
||||
412: 'ParticipantParentLinkedGroupsResourceConstraintError',
|
||||
500: 'ParticipantResourceConstraintError'
|
||||
};
|
||||
|
||||
try {
|
||||
for (const participant of participantArgs) {
|
||||
response = await window.Store.MembershipRequestUtils.sendMembershipRequestsActionRPC({
|
||||
iqTo: groupJid,
|
||||
[toApprove ? 'approveArgs' : 'rejectArgs']: participant
|
||||
});
|
||||
|
||||
if (response.name === 'MembershipRequestsActionResponseSuccess') {
|
||||
const value = toApprove
|
||||
? response.value.membershipRequestsActionApprove
|
||||
: response.value.membershipRequestsActionReject;
|
||||
if (value?.participant) {
|
||||
const [_] = value.participant.map(p => {
|
||||
const error = toApprove
|
||||
? value.participant[0].membershipRequestsActionAcceptParticipantMixins?.value.error
|
||||
: value.participant[0].membershipRequestsActionRejectParticipantMixins?.value.error;
|
||||
return {
|
||||
requesterId: window.Store.WidFactory.createWid(p.jid)._serialized,
|
||||
...(error
|
||||
? { error: +error, message: membReqResCodes[error] || membReqResCodes.default }
|
||||
: { message: `${toApprove ? 'Approved' : 'Rejected'} successfully` })
|
||||
};
|
||||
});
|
||||
_ && result.push(_);
|
||||
}
|
||||
} else {
|
||||
result.push({
|
||||
requesterId: window.Store.JidToWid.userJidToUserWid(participant.participantArgs[0].participantJid)._serialized,
|
||||
message: 'ServerStatusCodeError'
|
||||
});
|
||||
}
|
||||
|
||||
sleep &&
|
||||
participantArgs.length > 1 &&
|
||||
participantArgs.indexOf(participant) !== participantArgs.length - 1 &&
|
||||
(await new Promise((resolve) => setTimeout(resolve, _getSleepTime(sleep))));
|
||||
}
|
||||
return result;
|
||||
} catch (err) {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue