fix+feat: addParticipants + createGroup (#2344)
* added required modules * added sendGroupV4Invite implementation * docs updated accordingly * bug fixed * added usage example * ESLint fix * extended resulting object * docs updated accordingly * added required modules * updated comments * bug fixed * added usage example * fixed to catch unexpected errors * removed unnecessary module * updated usage example * minor fixes * changed to return a string if an error is occupied * fixed usage example * removed unneccessary module * added getAddParticipantsRpcResult * updated addParticipants - added AddParticipnatsOptions to provide values for sleep, autoSendInviteV4, comment - combined addParticipants with sendGroupInviteMessage * removed unneccessary sendGroupV4Invite * docs updated * fixed statement fot autoSendInviteV4 * minor fixes - the returned value of addParticipants is no longer wrapped in an array - docs updated - fixed bug with the returned code value when the code is '200' * added logic of retrieving the group profile picture this allows to send an invitation with a profile picture thumbnail of the group * minor fixes * added fix for the inviteV4 to be sent * updated usage example * minor fix * ESLint fix * fix for code 419 * function name getProfilePictureThumb changed to be more clear * refactor: modules moved to window.Store.GroupParticipants * refactor: edited link of usage examples * refactor: LidManipulations changed to LidUtils * refactor: modules regrouping To keep the modules in order were made some changes: - JoinInviteV4 renamed to GroupInviteV4 and grouped with module sendGroupInviteMessage - GroupParticipants grouped with module sendAddParticipantsRPC * fix: injectToFunction fixed to work properly * revert docs changes for Chat * Merge branch 'main' into fix-add-participants * docs fixed * minor fix in injectToFunction * removed data stringifying/parsing * added random sleep time logic * code refactoring * docs updated * addParticipants method refactored * createGroup method extended - added functionality to send private invitations automatically to missing participants - added ability to provide value for message timer - added ability to link a group to the community parent group at the stage of creating a group - extended the returned data after the method call * docs updated + typo fixed * added ability to create group with myself only * example updated * docs clarified * small code refactoring * window.Store.Invite and window.Store.InviteInfo grouped * window.compareWwebVersions fixed * small update to improve the performance of findImpl fix * gid as wid structure * docs + example updated * parenthesis * avoid sleep after the last iteration * fixed compatibility issue for sendGroupInviteMessage * fixed issue with stale groupmetadata in some cases after the participant has left the group, that participant is still stored in groupmetadata * fixed compatibility issue for sendAddParticipantsRPC * minor fix * jsdocs fixed * fixed issue with group creation * fixed createGroup method - added check for unregistered phone number - extended returning data from method call: added title - code refactored - jsdocs fixed * fixed addParticipants method - added check for unregistered number - code refactored * docs fixed * usage example fixed * removed unnecessary method call * jsdocs fixed * check for group admin fixed
This commit is contained in:
parent
56320c88f8
commit
c0705a2216
5 changed files with 508 additions and 82 deletions
72
example.js
72
example.js
|
|
@ -91,6 +91,78 @@ client.on('message', async msg => {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
msg.reply('That invite code seems to be invalid.');
|
msg.reply('That invite code seems to be invalid.');
|
||||||
}
|
}
|
||||||
|
} else if (msg.body.startsWith('!addmembers')) {
|
||||||
|
const group = await msg.getChat();
|
||||||
|
const result = await group.addParticipants(['number1@c.us', 'number2@c.us', 'number3@c.us']);
|
||||||
|
/**
|
||||||
|
* The example of the {@link result} output:
|
||||||
|
*
|
||||||
|
* {
|
||||||
|
* 'number1@c.us': {
|
||||||
|
* code: 200,
|
||||||
|
* message: 'The participant was added successfully',
|
||||||
|
* isInviteV4Sent: false
|
||||||
|
* },
|
||||||
|
* 'number2@c.us': {
|
||||||
|
* code: 403,
|
||||||
|
* message: 'The participant can be added by sending private invitation only',
|
||||||
|
* isInviteV4Sent: true
|
||||||
|
* },
|
||||||
|
* 'number3@c.us': {
|
||||||
|
* code: 404,
|
||||||
|
* message: 'The phone number is not registered on WhatsApp',
|
||||||
|
* isInviteV4Sent: false
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* For more usage examples:
|
||||||
|
* @see https://github.com/pedroslopez/whatsapp-web.js/pull/2344#usage-example1
|
||||||
|
*/
|
||||||
|
console.log(result);
|
||||||
|
} else if (msg.body === '!creategroup') {
|
||||||
|
const partitipantsToAdd = ['number1@c.us', 'number2@c.us', 'number3@c.us'];
|
||||||
|
const result = await client.createGroup('Group Title', partitipantsToAdd);
|
||||||
|
/**
|
||||||
|
* The example of the {@link result} output:
|
||||||
|
* {
|
||||||
|
* title: 'Group Title',
|
||||||
|
* gid: {
|
||||||
|
* server: 'g.us',
|
||||||
|
* user: '1111111111',
|
||||||
|
* _serialized: '1111111111@g.us'
|
||||||
|
* },
|
||||||
|
* participants: {
|
||||||
|
* 'botNumber@c.us': {
|
||||||
|
* statusCode: 200,
|
||||||
|
* message: 'The participant was added successfully',
|
||||||
|
* isGroupCreator: true,
|
||||||
|
* isInviteV4Sent: false
|
||||||
|
* },
|
||||||
|
* 'number1@c.us': {
|
||||||
|
* statusCode: 200,
|
||||||
|
* message: 'The participant was added successfully',
|
||||||
|
* isGroupCreator: false,
|
||||||
|
* isInviteV4Sent: false
|
||||||
|
* },
|
||||||
|
* 'number2@c.us': {
|
||||||
|
* statusCode: 403,
|
||||||
|
* message: 'The participant can be added by sending private invitation only',
|
||||||
|
* isGroupCreator: false,
|
||||||
|
* isInviteV4Sent: true
|
||||||
|
* },
|
||||||
|
* 'number3@c.us': {
|
||||||
|
* statusCode: 404,
|
||||||
|
* message: 'The phone number is not registered on WhatsApp',
|
||||||
|
* isGroupCreator: false,
|
||||||
|
* isInviteV4Sent: false
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* For more usage examples:
|
||||||
|
* @see https://github.com/pedroslopez/whatsapp-web.js/pull/2344#usage-example2
|
||||||
|
*/
|
||||||
|
console.log(result);
|
||||||
} else if (msg.body === '!groupinfo') {
|
} else if (msg.body === '!groupinfo') {
|
||||||
let chat = await msg.getChat();
|
let chat = await msg.getChat();
|
||||||
if (chat.isGroup) {
|
if (chat.isGroup) {
|
||||||
|
|
|
||||||
107
index.d.ts
vendored
107
index.d.ts
vendored
|
|
@ -35,12 +35,8 @@ declare namespace WAWebJS {
|
||||||
/** Unpins the Chat and returns its new Pin state */
|
/** Unpins the Chat and returns its new Pin state */
|
||||||
unpinChat(chatId: string): Promise<boolean>
|
unpinChat(chatId: string): Promise<boolean>
|
||||||
|
|
||||||
/**
|
/** Creates a new group */
|
||||||
* Create a new group
|
createGroup(title: string, participants?: string | Contact | Contact[] | string[], options?: CreateGroupOptions): Promise<CreateGroupResult|string>
|
||||||
* @param name group title
|
|
||||||
* @param participants an array of Contacts or contact IDs to add to the group
|
|
||||||
*/
|
|
||||||
createGroup(name: string, participants: Contact[] | string[]): Promise<CreateGroupResult>
|
|
||||||
|
|
||||||
/** Closes the client */
|
/** Closes the client */
|
||||||
destroy(): Promise<void>
|
destroy(): Promise<void>
|
||||||
|
|
@ -540,14 +536,47 @@ declare namespace WAWebJS {
|
||||||
plugged: boolean,
|
plugged: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** An object that handles options for group creation */
|
||||||
|
export interface CreateGroupOptions {
|
||||||
|
/**
|
||||||
|
* The number of seconds for the messages to disappear in the group,
|
||||||
|
* won't take an effect if the group is been creating with myself only
|
||||||
|
* @default 0
|
||||||
|
*/
|
||||||
|
messageTimer?: number
|
||||||
|
/**
|
||||||
|
* The ID of a parent community group to link the newly created group with,
|
||||||
|
* won't take an effect if the group is been creating with myself only
|
||||||
|
*/
|
||||||
|
parentGroupId?: string
|
||||||
|
/** If true, the inviteV4 will be sent to those participants
|
||||||
|
* who have restricted others from being automatically added to groups,
|
||||||
|
* otherwise the inviteV4 won't be sent
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
autoSendInviteV4?: boolean,
|
||||||
|
/**
|
||||||
|
* The comment to be added to an inviteV4 (empty string by default)
|
||||||
|
* @default ''
|
||||||
|
*/
|
||||||
|
comment?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** An object that handles the result for createGroup method */
|
||||||
export interface CreateGroupResult {
|
export interface CreateGroupResult {
|
||||||
/** ID for the group that was just created */
|
/** A group title */
|
||||||
gid: string,
|
title: string;
|
||||||
/** participants that were not added to the group.
|
/** An object that handles the newly created group ID */
|
||||||
* Keys represent the ID for participant that was not added and its value is a status code
|
gid: ChatId;
|
||||||
* that represents the reason why participant could not be added.
|
/** An object that handles the result value for each added to the group participant */
|
||||||
* This is usually 403 if the user's privacy settings don't allow you to add them to groups. */
|
participants: {
|
||||||
missingParticipants: Record<string, string>
|
[participantId: string]: {
|
||||||
|
statusCode: number,
|
||||||
|
message: string,
|
||||||
|
isGroupCreator: boolean,
|
||||||
|
isInviteV4Sent: boolean
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GroupNotification {
|
export interface GroupNotification {
|
||||||
|
|
@ -1196,9 +1225,9 @@ declare namespace WAWebJS {
|
||||||
/** Returns the Contact that corresponds to this Chat. */
|
/** Returns the Contact that corresponds to this Chat. */
|
||||||
getContact: () => Promise<Contact>,
|
getContact: () => Promise<Contact>,
|
||||||
/** Marks this Chat as unread */
|
/** Marks this Chat as unread */
|
||||||
markUnread: () => Promise<void>
|
markUnread: () => Promise<void>,
|
||||||
/** Returns array of all Labels assigned to this Chat */
|
/** Returns array of all Labels assigned to this Chat */
|
||||||
getLabels: () => Promise<Label[]>
|
getLabels: () => Promise<Label[]>,
|
||||||
/** Add or remove labels to this Chat */
|
/** Add or remove labels to this Chat */
|
||||||
changeLabels: (labelIds: Array<string | number>) => Promise<void>
|
changeLabels: (labelIds: Array<string | number>) => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
@ -1258,18 +1287,38 @@ declare namespace WAWebJS {
|
||||||
export type ChangeParticipantsPermissions =
|
export type ChangeParticipantsPermissions =
|
||||||
(participantIds: Array<string>) => Promise<{ status: number }>
|
(participantIds: Array<string>) => Promise<{ status: number }>
|
||||||
|
|
||||||
/** Adds or removes a list of participants by ID to the group */
|
/** An object that handles the result for addParticipants method */
|
||||||
export type ChangeGroupParticipants =
|
export interface AddParticipantsResult {
|
||||||
(participantIds: Array<string>) => Promise<{
|
[participantId: string]: {
|
||||||
status: number;
|
code: number;
|
||||||
participants: Array<{
|
message: string;
|
||||||
[key: string]: {
|
isInviteV4Sent: boolean,
|
||||||
code: number
|
};
|
||||||
}
|
};
|
||||||
}>
|
|
||||||
} & {
|
/** An object that handles options for adding participants */
|
||||||
[key: string]: number;
|
export interface AddParticipantsOptions {
|
||||||
}>
|
/**
|
||||||
|
* The number of milliseconds to wait before adding the next participant.
|
||||||
|
* 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
|
||||||
|
* @default [250,500]
|
||||||
|
*/
|
||||||
|
sleep?: Array<number>|number,
|
||||||
|
/**
|
||||||
|
* If true, the inviteV4 will be sent to those participants
|
||||||
|
* who have restricted others from being automatically added to groups,
|
||||||
|
* otherwise the inviteV4 won't be sent
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
autoSendInviteV4?: boolean,
|
||||||
|
/**
|
||||||
|
* The comment to be added to an inviteV4 (empty string by default)
|
||||||
|
* @default ''
|
||||||
|
*/
|
||||||
|
comment?: string
|
||||||
|
};
|
||||||
|
|
||||||
/** An object that handles the information about the group membership request */
|
/** An object that handles the information about the group membership request */
|
||||||
export interface GroupMembershipRequest {
|
export interface GroupMembershipRequest {
|
||||||
|
|
@ -1313,9 +1362,9 @@ declare namespace WAWebJS {
|
||||||
/** Group participants */
|
/** Group participants */
|
||||||
participants: Array<GroupParticipant>;
|
participants: Array<GroupParticipant>;
|
||||||
/** Adds a list of participants by ID to the group */
|
/** Adds a list of participants by ID to the group */
|
||||||
addParticipants: ChangeGroupParticipants;
|
addParticipants: (participantIds: string|string[], options?: AddParticipantsOptions) => Promise<Object.<string, AddParticipantsResult>|string>;
|
||||||
/** Removes a list of participants by ID to the group */
|
/** Removes a list of participants by ID to the group */
|
||||||
removeParticipants: ChangeGroupParticipants;
|
removeParticipants: (participantIds: string[]) => Promise<{ status: number }>;
|
||||||
/** Promotes participants by IDs to admins */
|
/** Promotes participants by IDs to admins */
|
||||||
promoteParticipants: ChangeParticipantsPermissions;
|
promoteParticipants: ChangeParticipantsPermissions;
|
||||||
/** Demotes participants by IDs to regular users */
|
/** Demotes participants by IDs to regular users */
|
||||||
|
|
|
||||||
131
src/Client.js
131
src/Client.js
|
|
@ -987,7 +987,7 @@ class Client extends EventEmitter {
|
||||||
*/
|
*/
|
||||||
async getInviteInfo(inviteCode) {
|
async getInviteInfo(inviteCode) {
|
||||||
return await this.pupPage.evaluate(inviteCode => {
|
return await this.pupPage.evaluate(inviteCode => {
|
||||||
return window.Store.InviteInfo.queryGroupInvite(inviteCode);
|
return window.Store.GroupInvite.queryGroupInvite(inviteCode);
|
||||||
}, inviteCode);
|
}, inviteCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -998,7 +998,7 @@ class Client extends EventEmitter {
|
||||||
*/
|
*/
|
||||||
async acceptInvite(inviteCode) {
|
async acceptInvite(inviteCode) {
|
||||||
const res = await this.pupPage.evaluate(async inviteCode => {
|
const res = await this.pupPage.evaluate(async inviteCode => {
|
||||||
return await window.Store.Invite.joinGroupViaInvite(inviteCode);
|
return await window.Store.GroupInvite.joinGroupViaInvite(inviteCode);
|
||||||
}, inviteCode);
|
}, inviteCode);
|
||||||
|
|
||||||
return res.gid._serialized;
|
return res.gid._serialized;
|
||||||
|
|
@ -1015,7 +1015,7 @@ class Client extends EventEmitter {
|
||||||
return this.pupPage.evaluate(async inviteInfo => {
|
return this.pupPage.evaluate(async inviteInfo => {
|
||||||
let { groupId, fromId, inviteCode, inviteCodeExp } = inviteInfo;
|
let { groupId, fromId, inviteCode, inviteCodeExp } = inviteInfo;
|
||||||
let userWid = window.Store.WidFactory.createWid(fromId);
|
let userWid = window.Store.WidFactory.createWid(fromId);
|
||||||
return await window.Store.JoinInviteV4.joinGroupViaInviteV4(inviteCode, String(inviteCodeExp), groupId, userWid);
|
return await window.Store.GroupInviteV4.joinGroupViaInviteV4(inviteCode, String(inviteCodeExp), groupId, userWid);
|
||||||
}, inviteInfo);
|
}, inviteInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1291,35 +1291,116 @@ class Client extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new group
|
* An object that represents the result for a participant added to a group
|
||||||
* @param {string} name group title
|
* @typedef {Object} ParticipantResult
|
||||||
* @param {Array<Contact|string>} participants an array of Contacts or contact IDs to add to the group
|
* @property {number} statusCode The status code of the result
|
||||||
* @returns {Object} createRes
|
* @property {string} message The result message
|
||||||
* @returns {string} createRes.gid - ID for the group that was just created
|
* @property {boolean} isGroupCreator Indicates if the participant is a group creator
|
||||||
* @returns {Object.<string,string>} createRes.missingParticipants - participants that were not added to the group. Keys represent the ID for participant that was not added and its value is a status code that represents the reason why participant could not be added. This is usually 403 if the user's privacy settings don't allow you to add them to groups.
|
* @property {boolean} isInviteV4Sent Indicates if the inviteV4 was sent to the participant
|
||||||
*/
|
*/
|
||||||
async createGroup(name, participants) {
|
|
||||||
if (!Array.isArray(participants) || participants.length == 0) {
|
/**
|
||||||
throw 'You need to add at least one other participant to the group';
|
* An object that handles the result for {@link createGroup} method
|
||||||
|
* @typedef {Object} CreateGroupResult
|
||||||
|
* @property {string} title A group title
|
||||||
|
* @property {Object} gid An object that handles the newly created group ID
|
||||||
|
* @property {string} gid.server
|
||||||
|
* @property {string} gid.user
|
||||||
|
* @property {string} gid._serialized
|
||||||
|
* @property {Object.<string, ParticipantResult>} participants An object that handles the result value for each added to the group participant
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object that handles options for group creation
|
||||||
|
* @typedef {Object} CreateGroupOptions
|
||||||
|
* @property {number} [messageTimer = 0] The number of seconds for the messages to disappear in the group (0 by default, won't take an effect if the group is been creating with myself only)
|
||||||
|
* @property {string|undefined} parentGroupId The ID of a parent community group to link the newly created group with (won't take an effect if the group is been creating with myself only)
|
||||||
|
* @property {boolean} [autoSendInviteV4 = true] If true, the inviteV4 will be sent to those participants who have restricted others from being automatically added to groups, otherwise the inviteV4 won't be sent (true by default)
|
||||||
|
* @property {string} [comment = ''] The comment to be added to an inviteV4 (empty string by default)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new group
|
||||||
|
* @param {string} title Group title
|
||||||
|
* @param {string|Contact|Array<Contact|string>|undefined} participants A single Contact object or an ID as a string or an array of Contact objects or contact IDs to add to the group
|
||||||
|
* @param {CreateGroupOptions} options An object that handles options for group creation
|
||||||
|
* @returns {Promise<CreateGroupResult|string>} Object with resulting data or an error message as a string
|
||||||
|
*/
|
||||||
|
async createGroup(title, participants = [], options = {}) {
|
||||||
|
!Array.isArray(participants) && (participants = [participants]);
|
||||||
|
participants.map(p => (p instanceof Contact) ? p.id._serialized : p);
|
||||||
|
|
||||||
|
return await this.pupPage.evaluate(async (title, participants, options) => {
|
||||||
|
const { messageTimer = 0, parentGroupId, autoSendInviteV4 = true, comment = '' } = options;
|
||||||
|
const participantData = {}, participantWids = [], failedParticipants = [];
|
||||||
|
let createGroupResult, parentGroupWid;
|
||||||
|
|
||||||
|
const addParticipantResultCodes = {
|
||||||
|
default: 'An unknown error occupied while adding a participant',
|
||||||
|
200: 'The participant was added successfully',
|
||||||
|
403: 'The participant can be added by sending private invitation only',
|
||||||
|
404: 'The phone number is not registered on WhatsApp'
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const participant of participants) {
|
||||||
|
const pWid = window.Store.WidFactory.createWid(participant);
|
||||||
|
if ((await window.Store.QueryExist(pWid))?.wid) participantWids.push(pWid);
|
||||||
|
else failedParticipants.push(participant);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (participants.every(c => c instanceof Contact)) {
|
parentGroupId && (parentGroupWid = window.Store.WidFactory.createWid(parentGroupId));
|
||||||
participants = participants.map(c => c.id._serialized);
|
|
||||||
|
try {
|
||||||
|
createGroupResult = await window.Store.GroupUtils.createGroup(
|
||||||
|
title,
|
||||||
|
participantWids,
|
||||||
|
messageTimer,
|
||||||
|
parentGroupWid
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
return 'CreateGroupError: An unknown error occupied while creating a group';
|
||||||
}
|
}
|
||||||
|
|
||||||
const createRes = await this.pupPage.evaluate(async (name, participantIds) => {
|
for (const participant of createGroupResult.participants) {
|
||||||
const participantWIDs = participantIds.map(p => window.Store.WidFactory.createWid(p));
|
let isInviteV4Sent = false;
|
||||||
return await window.Store.GroupUtils.createGroup(name, participantWIDs, 0);
|
const participantId = participant.wid._serialized;
|
||||||
}, name, participants);
|
const statusCode = participant.error ?? 200;
|
||||||
|
|
||||||
const missingParticipants = createRes.participants.reduce(((missing, c) => {
|
if (autoSendInviteV4 && statusCode === 403) {
|
||||||
const id = c.wid._serialized;
|
window.Store.ContactCollection.gadd(participant.wid, { silent: true });
|
||||||
const statusCode = c.error ? c.error.toString() : '200';
|
const addParticipantResult = await window.Store.GroupInviteV4.sendGroupInviteMessage(
|
||||||
if (statusCode != 200) return Object.assign(missing, { [id]: statusCode });
|
await window.Store.Chat.find(participant.wid),
|
||||||
return missing;
|
createGroupResult.wid._serialized,
|
||||||
}), {});
|
createGroupResult.subject,
|
||||||
|
participant.invite_code,
|
||||||
|
participant.invite_code_exp,
|
||||||
|
comment,
|
||||||
|
await window.WWebJS.getProfilePicThumbToBase64(createGroupResult.wid)
|
||||||
|
);
|
||||||
|
isInviteV4Sent = window.compareWwebVersions(window.Debug.VERSION, '<', '2.2335.6')
|
||||||
|
? addParticipantResult === 'OK'
|
||||||
|
: addParticipantResult.messageSendResult === 'OK';
|
||||||
|
}
|
||||||
|
|
||||||
return { gid: createRes.wid, missingParticipants };
|
participantData[participantId] = {
|
||||||
|
statusCode: statusCode,
|
||||||
|
message: addParticipantResultCodes[statusCode] || addParticipantResultCodes.default,
|
||||||
|
isGroupCreator: participant.type === 'superadmin',
|
||||||
|
isInviteV4Sent: isInviteV4Sent
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const f of failedParticipants) {
|
||||||
|
participantData[f] = {
|
||||||
|
statusCode: 404,
|
||||||
|
message: addParticipantResultCodes[404],
|
||||||
|
isGroupCreator: false,
|
||||||
|
isInviteV4Sent: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { title: title, gid: createGroupResult.wid, participants: participantData };
|
||||||
|
}, title, participants, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -54,27 +54,140 @@ class GroupChat extends Chat {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a list of participants by ID to the group
|
* An object that handles the result for {@link addParticipants} method
|
||||||
* @param {Array<string>} participantIds
|
* @typedef {Object} AddParticipantsResult
|
||||||
* @returns {Promise<Object>}
|
* @property {number} code The code of the result
|
||||||
|
* @property {string} message The result message
|
||||||
|
* @property {boolean} isInviteV4Sent Indicates if the inviteV4 was sent to the partitipant
|
||||||
*/
|
*/
|
||||||
async addParticipants(participantIds) {
|
|
||||||
return await this.client.pupPage.evaluate(async (chatId, participantIds) => {
|
/**
|
||||||
const chatWid = window.Store.WidFactory.createWid(chatId);
|
* An object that handles options for adding participants
|
||||||
const chat = await window.Store.Chat.find(chatWid);
|
* @typedef {Object} AddParticipnatsOptions
|
||||||
const participants = await Promise.all(participantIds.map(async p => {
|
* @property {Array<number>|number} [sleep = [250, 500]] The number of milliseconds to wait before adding the next participant. 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]
|
||||||
const wid = window.Store.WidFactory.createWid(p);
|
* @property {boolean} [autoSendInviteV4 = true] If true, the inviteV4 will be sent to those participants who have restricted others from being automatically added to groups, otherwise the inviteV4 won't be sent (true by default)
|
||||||
return await window.Store.Contact.get(wid);
|
* @property {string} [comment = ''] The comment to be added to an inviteV4 (empty string by default)
|
||||||
}));
|
*/
|
||||||
await window.Store.GroupParticipants.addParticipants(chat, participants);
|
|
||||||
return { status: 200 };
|
/**
|
||||||
}, this.id._serialized, participantIds);
|
* Adds a list of participants by ID to the group
|
||||||
|
* @param {string|Array<string>} participantIds
|
||||||
|
* @param {AddParticipnatsOptions} options An object thay handles options for adding participants
|
||||||
|
* @returns {Promise<Object.<string, AddParticipantsResult>|string>} Returns an object with the resulting data or an error message as a string
|
||||||
|
*/
|
||||||
|
async addParticipants(participantIds, options = {}) {
|
||||||
|
return await this.client.pupPage.evaluate(async (groupId, participantIds, options) => {
|
||||||
|
const { sleep = [250, 500], autoSendInviteV4 = true, comment = '' } = options;
|
||||||
|
const participantData = {};
|
||||||
|
|
||||||
|
!Array.isArray(participantIds) && (participantIds = [participantIds]);
|
||||||
|
const groupWid = window.Store.WidFactory.createWid(groupId);
|
||||||
|
const group = await window.Store.Chat.find(groupWid);
|
||||||
|
const participantWids = participantIds.map((p) => window.Store.WidFactory.createWid(p));
|
||||||
|
|
||||||
|
const errorCodes = {
|
||||||
|
default: 'An unknown error occupied while adding a participant',
|
||||||
|
isGroupEmpty: 'AddParticipantsError: The participant can\'t be added to an empty group',
|
||||||
|
iAmNotAdmin: 'AddParticipantsError: You have no admin rights to add a participant to a group',
|
||||||
|
200: 'The participant was added successfully',
|
||||||
|
403: 'The participant can be added by sending private invitation only',
|
||||||
|
404: 'The phone number is not registered on WhatsApp',
|
||||||
|
408: 'You cannot add this participant because they recently left the group',
|
||||||
|
409: 'The participant is already a group member',
|
||||||
|
417: 'The participant can\'t be added to the community. You can invite them privately to join this group through its invite link',
|
||||||
|
419: 'The participant can\'t be added because the group is full'
|
||||||
|
};
|
||||||
|
|
||||||
|
await window.Store.GroupMetadata.queryAndUpdate(groupWid);
|
||||||
|
const groupMetadata = group.groupMetadata;
|
||||||
|
const groupParticipants = groupMetadata?.participants;
|
||||||
|
|
||||||
|
if (!groupParticipants) {
|
||||||
|
return errorCodes.isGroupEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!group.iAmAdmin()) {
|
||||||
|
return errorCodes.iAmNotAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const pWid of participantWids) {
|
||||||
|
const pId = pWid._serialized;
|
||||||
|
|
||||||
|
participantData[pId] = {
|
||||||
|
code: undefined,
|
||||||
|
message: undefined,
|
||||||
|
isInviteV4Sent: false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (groupParticipants.some(p => p.id._serialized === pId)) {
|
||||||
|
participantData[pId].code = 409;
|
||||||
|
participantData[pId].message = errorCodes[409];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(await window.Store.QueryExist(pWid))?.wid) {
|
||||||
|
participantData[pId].code = 404;
|
||||||
|
participantData[pId].message = errorCodes[404];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rpcResult =
|
||||||
|
await window.WWebJS.getAddParticipantsRpcResult(groupMetadata, groupWid, pWid);
|
||||||
|
const { code: rpcResultCode } = rpcResult;
|
||||||
|
|
||||||
|
participantData[pId].code = rpcResultCode;
|
||||||
|
participantData[pId].message =
|
||||||
|
errorCodes[rpcResultCode] || errorCodes.default;
|
||||||
|
|
||||||
|
if (autoSendInviteV4 && rpcResultCode === 403) {
|
||||||
|
let userChat, isInviteV4Sent = false;
|
||||||
|
window.Store.ContactCollection.gadd(pWid, { silent: true });
|
||||||
|
|
||||||
|
if (rpcResult.name === 'ParticipantRequestCodeCanBeSent' &&
|
||||||
|
(userChat = await window.Store.Chat.find(pWid))) {
|
||||||
|
const groupName = group.formattedTitle || group.name;
|
||||||
|
const res = await window.Store.GroupInviteV4.sendGroupInviteMessage(
|
||||||
|
userChat,
|
||||||
|
group.id._serialized,
|
||||||
|
groupName,
|
||||||
|
rpcResult.inviteV4Code,
|
||||||
|
rpcResult.inviteV4CodeExp,
|
||||||
|
comment,
|
||||||
|
await window.WWebJS.getProfilePicThumbToBase64(groupWid)
|
||||||
|
);
|
||||||
|
isInviteV4Sent = window.compareWwebVersions(window.Debug.VERSION, '<', '2.2335.6')
|
||||||
|
? res === 'OK'
|
||||||
|
: res.messageSendResult === 'OK';
|
||||||
|
}
|
||||||
|
|
||||||
|
participantData[pId].isInviteV4Sent = isInviteV4Sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep &&
|
||||||
|
participantWids.length > 1 &&
|
||||||
|
participantWids.indexOf(pWid) !== participantWids.length - 1 &&
|
||||||
|
(await new Promise((resolve) => setTimeout(resolve, _getSleepTime(sleep))));
|
||||||
|
}
|
||||||
|
|
||||||
|
return participantData;
|
||||||
|
}, this.id._serialized, participantIds, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a list of participants by ID to the group
|
* Removes a list of participants by ID to the group
|
||||||
* @param {Array<string>} participantIds
|
* @param {Array<string>} participantIds
|
||||||
* @returns {Promise<Object>}
|
* @returns {Promise<{ status: number }>}
|
||||||
*/
|
*/
|
||||||
async removeParticipants(participantIds) {
|
async removeParticipants(participantIds) {
|
||||||
return await this.client.pupPage.evaluate(async (chatId, participantIds) => {
|
return await this.client.pupPage.evaluate(async (chatId, participantIds) => {
|
||||||
|
|
@ -246,7 +359,7 @@ class GroupChat extends Chat {
|
||||||
async getInviteCode() {
|
async getInviteCode() {
|
||||||
const codeRes = await this.client.pupPage.evaluate(async chatId => {
|
const codeRes = await this.client.pupPage.evaluate(async chatId => {
|
||||||
const chatWid = window.Store.WidFactory.createWid(chatId);
|
const chatWid = window.Store.WidFactory.createWid(chatId);
|
||||||
return window.Store.Invite.queryGroupInviteCode(chatWid);
|
return window.Store.GroupInvite.queryGroupInviteCode(chatWid);
|
||||||
}, this.id._serialized);
|
}, this.id._serialized);
|
||||||
|
|
||||||
return codeRes.code;
|
return codeRes.code;
|
||||||
|
|
@ -259,7 +372,7 @@ class GroupChat extends Chat {
|
||||||
async revokeInvite() {
|
async revokeInvite() {
|
||||||
const codeRes = await this.client.pupPage.evaluate(chatId => {
|
const codeRes = await this.client.pupPage.evaluate(chatId => {
|
||||||
const chatWid = window.Store.WidFactory.createWid(chatId);
|
const chatWid = window.Store.WidFactory.createWid(chatId);
|
||||||
return window.Store.Invite.resetGroupInviteCode(chatWid);
|
return window.Store.GroupInvite.resetGroupInviteCode(chatWid);
|
||||||
}, this.id._serialized);
|
}, this.id._serialized);
|
||||||
|
|
||||||
return codeRes.code;
|
return codeRes.code;
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,8 @@ exports.ExposeStore = (moduleRaidStr) => {
|
||||||
window.Store.DownloadManager = window.mR.findModule('downloadManager')[0].downloadManager;
|
window.Store.DownloadManager = window.mR.findModule('downloadManager')[0].downloadManager;
|
||||||
window.Store.GroupMetadata = window.mR.findModule('GroupMetadata')[0].default.GroupMetadata;
|
window.Store.GroupMetadata = window.mR.findModule('GroupMetadata')[0].default.GroupMetadata;
|
||||||
window.Store.GroupMetadata.queryAndUpdate = window.mR.findModule('queryAndUpdateGroupMetadataById')[0].queryAndUpdateGroupMetadataById;
|
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;
|
window.Store.Label = window.mR.findModule('LabelCollection')[0].LabelCollection;
|
||||||
|
window.Store.ContactCollection = window.mR.findModule('ContactCollection')[0].ContactCollection;
|
||||||
window.Store.MediaPrep = window.mR.findModule('prepRawMedia')[0];
|
window.Store.MediaPrep = window.mR.findModule('prepRawMedia')[0];
|
||||||
window.Store.MediaObject = window.mR.findModule('getOrCreateMediaObject')[0];
|
window.Store.MediaObject = window.mR.findModule('getOrCreateMediaObject')[0];
|
||||||
window.Store.NumberInfo = window.mR.findModule('formattedPhoneNumber')[0];
|
window.Store.NumberInfo = window.mR.findModule('formattedPhoneNumber')[0];
|
||||||
|
|
@ -26,7 +25,6 @@ exports.ExposeStore = (moduleRaidStr) => {
|
||||||
window.Store.MsgKey = window.mR.findModule((module) => module.default && module.default.fromString)[0].default;
|
window.Store.MsgKey = window.mR.findModule((module) => module.default && module.default.fromString)[0].default;
|
||||||
window.Store.MessageInfo = window.mR.findModule('sendQueryMsgInfo')[0];
|
window.Store.MessageInfo = window.mR.findModule('sendQueryMsgInfo')[0];
|
||||||
window.Store.OpaqueData = window.mR.findModule(module => module.default && module.default.createFromData)[0].default;
|
window.Store.OpaqueData = window.mR.findModule(module => module.default && module.default.createFromData)[0].default;
|
||||||
window.Store.QueryExist = window.mR.findModule('queryExists')[0] ? window.mR.findModule('queryExists')[0].queryExists : window.mR.findModule('queryExist')[0].queryWidExists;
|
|
||||||
window.Store.QueryProduct = window.mR.findModule('queryProduct')[0];
|
window.Store.QueryProduct = window.mR.findModule('queryProduct')[0];
|
||||||
window.Store.QueryOrder = window.mR.findModule('queryOrder')[0];
|
window.Store.QueryOrder = window.mR.findModule('queryOrder')[0];
|
||||||
window.Store.SendClear = window.mR.findModule('sendClear')[0];
|
window.Store.SendClear = window.mR.findModule('sendClear')[0];
|
||||||
|
|
@ -45,23 +43,28 @@ exports.ExposeStore = (moduleRaidStr) => {
|
||||||
window.Store.ProfilePic = window.mR.findModule('profilePicResync')[0];
|
window.Store.ProfilePic = window.mR.findModule('profilePicResync')[0];
|
||||||
window.Store.PresenceUtils = window.mR.findModule('sendPresenceAvailable')[0];
|
window.Store.PresenceUtils = window.mR.findModule('sendPresenceAvailable')[0];
|
||||||
window.Store.ChatState = window.mR.findModule('sendChatStateComposing')[0];
|
window.Store.ChatState = window.mR.findModule('sendChatStateComposing')[0];
|
||||||
window.Store.GroupParticipants = window.mR.findModule('promoteParticipants')[0];
|
|
||||||
window.Store.JoinInviteV4 = window.mR.findModule('queryGroupInviteV4')[0];
|
|
||||||
window.Store.findCommonGroups = window.mR.findModule('findCommonGroups')[0].findCommonGroups;
|
window.Store.findCommonGroups = window.mR.findModule('findCommonGroups')[0].findCommonGroups;
|
||||||
window.Store.StatusUtils = window.mR.findModule('setMyStatus')[0];
|
window.Store.StatusUtils = window.mR.findModule('setMyStatus')[0];
|
||||||
window.Store.ConversationMsgs = window.mR.findModule('loadEarlierMsgs')[0];
|
window.Store.ConversationMsgs = window.mR.findModule('loadEarlierMsgs')[0];
|
||||||
window.Store.sendReactionToMsg = window.mR.findModule('sendReactionToMsg')[0].sendReactionToMsg;
|
window.Store.sendReactionToMsg = window.mR.findModule('sendReactionToMsg')[0].sendReactionToMsg;
|
||||||
window.Store.createOrUpdateReactionsModule = window.mR.findModule('createOrUpdateReactions')[0];
|
window.Store.createOrUpdateReactionsModule = window.mR.findModule('createOrUpdateReactions')[0];
|
||||||
window.Store.EphemeralFields = window.mR.findModule('getEphemeralFields')[0];
|
window.Store.EphemeralFields = window.mR.findModule('getEphemeralFields')[0];
|
||||||
window.Store.ReplyUtils = window.mR.findModule('canReplyMsg').length > 0 && window.mR.findModule('canReplyMsg')[0];
|
|
||||||
window.Store.MsgActionChecks = window.mR.findModule('canSenderRevokeMsg')[0];
|
window.Store.MsgActionChecks = window.mR.findModule('canSenderRevokeMsg')[0];
|
||||||
window.Store.QuotedMsg = window.mR.findModule('getQuotedMsgObj')[0];
|
window.Store.QuotedMsg = window.mR.findModule('getQuotedMsgObj')[0];
|
||||||
window.Store.Socket = window.mR.findModule('deprecatedSendIq')[0];
|
window.Store.Socket = window.mR.findModule('deprecatedSendIq')[0];
|
||||||
window.Store.SocketWap = window.mR.findModule('wap')[0];
|
window.Store.SocketWap = window.mR.findModule('wap')[0];
|
||||||
window.Store.SearchContext = window.mR.findModule('getSearchContext')[0].getSearchContext;
|
window.Store.SearchContext = window.mR.findModule('getSearchContext')[0].getSearchContext;
|
||||||
window.Store.DrawerManager = window.mR.findModule('DrawerManager')[0].DrawerManager;
|
window.Store.DrawerManager = window.mR.findModule('DrawerManager')[0].DrawerManager;
|
||||||
|
window.Store.LidUtils = window.mR.findModule('getCurrentLid')[0];
|
||||||
window.Store.WidToJid = window.mR.findModule('widToUserJid')[0];
|
window.Store.WidToJid = window.mR.findModule('widToUserJid')[0];
|
||||||
window.Store.JidToWid = window.mR.findModule('userJidToUserWid')[0];
|
window.Store.JidToWid = window.mR.findModule('userJidToUserWid')[0];
|
||||||
|
|
||||||
|
/* eslint-disable no-undef, no-cond-assign */
|
||||||
|
window.Store.QueryExist = ((m = window.mR.findModule('queryExists')[0]) ? m.queryExists : window.mR.findModule('queryExist')[0].queryWidExists);
|
||||||
|
window.Store.ReplyUtils = (m = window.mR.findModule('canReplyMsg')).length > 0 && m[0];
|
||||||
|
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;
|
||||||
|
/* eslint-enable no-undef, no-cond-assign */
|
||||||
|
|
||||||
window.Store.StickerTools = {
|
window.Store.StickerTools = {
|
||||||
...window.mR.findModule('toWebpSticker')[0],
|
...window.mR.findModule('toWebpSticker')[0],
|
||||||
...window.mR.findModule('addWebpMetadata')[0]
|
...window.mR.findModule('addWebpMetadata')[0]
|
||||||
|
|
@ -72,6 +75,18 @@ exports.ExposeStore = (moduleRaidStr) => {
|
||||||
...window.mR.findModule('sendExitGroup')[0],
|
...window.mR.findModule('sendExitGroup')[0],
|
||||||
...window.mR.findModule('sendSetPicture')[0]
|
...window.mR.findModule('sendSetPicture')[0]
|
||||||
};
|
};
|
||||||
|
window.Store.GroupParticipants = {
|
||||||
|
...window.mR.findModule('promoteParticipants')[0],
|
||||||
|
...window.mR.findModule('sendAddParticipantsRPC')[0]
|
||||||
|
};
|
||||||
|
window.Store.GroupInvite = {
|
||||||
|
...window.mR.findModule('resetGroupInviteCode')[0],
|
||||||
|
...window.mR.findModule('queryGroupInvite')[0]
|
||||||
|
};
|
||||||
|
window.Store.GroupInviteV4 = {
|
||||||
|
...window.mR.findModule('queryGroupInviteV4')[0],
|
||||||
|
...window.mR.findModule('sendGroupInviteMessage')[0]
|
||||||
|
};
|
||||||
window.Store.MembershipRequestUtils = {
|
window.Store.MembershipRequestUtils = {
|
||||||
...window.mR.findModule('getMembershipApprovalRequests')[0],
|
...window.mR.findModule('getMembershipApprovalRequests')[0],
|
||||||
...window.mR.findModule('sendMembershipRequestsActionRPC')[0]
|
...window.mR.findModule('sendMembershipRequestsActionRPC')[0]
|
||||||
|
|
@ -86,9 +101,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
|
// TODO remove these once everybody has been updated to WWebJS with legacy sessions removed
|
||||||
const _linkPreview = window.mR.findModule('queryLinkPreview');
|
const _linkPreview = window.mR.findModule('queryLinkPreview');
|
||||||
if (_linkPreview && _linkPreview[0] && _linkPreview[0].default) {
|
if (_linkPreview && _linkPreview[0] && _linkPreview[0].default) {
|
||||||
|
|
@ -131,7 +143,7 @@ exports.ExposeStore = (moduleRaidStr) => {
|
||||||
|
|
||||||
window.injectToFunction({ moduleId: 'mediaTypeFromProtobuf', index: 0, property: 'mediaTypeFromProtobuf' }, (func, ...args) => { const [proto] = args; return proto.locationMessage ? null : func(...args); });
|
window.injectToFunction({ moduleId: 'mediaTypeFromProtobuf', index: 0, property: 'mediaTypeFromProtobuf' }, (func, ...args) => { const [proto] = args; return proto.locationMessage ? null : func(...args); });
|
||||||
|
|
||||||
window.injectToFunction({ moduleId: 'typeAttributeFromProtobuf', index: 0, property: 'typeAttributeFromProtobuf' }, (func, ...args) => { const [proto] = args; return proto.locationMessage ? 'text' : func(...args); });
|
window.injectToFunction({ moduleId: 'typeAttributeFromProtobuf', index: 0, property: 'typeAttributeFromProtobuf' }, (func, ...args) => { const [proto] = args; return proto.locationMessage || proto.groupInviteMessage ? 'text' : func(...args); });
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.LoadUtils = () => {
|
exports.LoadUtils = () => {
|
||||||
|
|
@ -866,6 +878,105 @@ exports.LoadUtils = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.WWebJS.getProfilePicThumbToBase64 = async (chatWid) => {
|
||||||
|
const profilePicCollection = await window.Store.ProfilePicThumb.find(chatWid);
|
||||||
|
|
||||||
|
const _readImageAsBase64 = (imageBlob) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onloadend = function () {
|
||||||
|
const base64Image = reader.result;
|
||||||
|
if (base64Image == null) {
|
||||||
|
resolve(undefined);
|
||||||
|
} else {
|
||||||
|
const base64Data = base64Image.toString().split(',')[1];
|
||||||
|
resolve(base64Data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(imageBlob);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (profilePicCollection?.img) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(profilePicCollection.img);
|
||||||
|
if (response.ok) {
|
||||||
|
const imageBlob = await response.blob();
|
||||||
|
if (imageBlob) {
|
||||||
|
const base64Image = await _readImageAsBase64(imageBlob);
|
||||||
|
return base64Image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) { /* empty */ }
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.WWebJS.getAddParticipantsRpcResult = async (groupMetadata, groupWid, participantWid) => {
|
||||||
|
const participantLidArgs = groupMetadata?.isLidAddressingMode
|
||||||
|
? {
|
||||||
|
phoneNumber: participantWid,
|
||||||
|
lid: window.Store.LidUtils.getCurrentLid(participantWid)
|
||||||
|
}
|
||||||
|
: { phoneNumber: participantWid };
|
||||||
|
|
||||||
|
const iqTo = window.Store.WidToJid.widToGroupJid(groupWid);
|
||||||
|
|
||||||
|
const participantArgs =
|
||||||
|
participantLidArgs.lid
|
||||||
|
? [{
|
||||||
|
participantJid: window.Store.WidToJid.widToUserJid(participantLidArgs.lid),
|
||||||
|
phoneNumberMixinArgs: {
|
||||||
|
anyPhoneNumber: window.Store.WidToJid.widToUserJid(participantLidArgs.phoneNumber)
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
: [{
|
||||||
|
participantJid: window.Store.WidToJid.widToUserJid(participantLidArgs.phoneNumber)
|
||||||
|
}];
|
||||||
|
|
||||||
|
let rpcResult, resultArgs;
|
||||||
|
const isOldImpl = window.compareWwebVersions(window.Debug.VERSION, '<=', '2.2335.9');
|
||||||
|
const data = {
|
||||||
|
name: undefined,
|
||||||
|
code: undefined,
|
||||||
|
inviteV4Code: undefined,
|
||||||
|
inviteV4CodeExp: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
rpcResult = await window.Store.GroupParticipants.sendAddParticipantsRPC({ participantArgs, iqTo });
|
||||||
|
resultArgs = isOldImpl
|
||||||
|
? rpcResult.value.addParticipant[0].addParticipantsParticipantMixins
|
||||||
|
: rpcResult.value.addParticipant[0]
|
||||||
|
.addParticipantsParticipantAddedOrNonRegisteredWaUserParticipantErrorLidResponseMixinGroup
|
||||||
|
.value
|
||||||
|
.addParticipantsParticipantMixins;
|
||||||
|
} catch (err) {
|
||||||
|
data.code = 400;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rpcResult.name === 'AddParticipantsResponseSuccess') {
|
||||||
|
const code = resultArgs?.value.error ?? '200';
|
||||||
|
data.name = resultArgs?.name;
|
||||||
|
data.code = +code;
|
||||||
|
data.inviteV4Code = resultArgs?.value.addRequestCode;
|
||||||
|
data.inviteV4CodeExp = resultArgs?.value.addRequestExpiration?.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (rpcResult.name === 'AddParticipantsResponseClientError') {
|
||||||
|
const { code: code } = rpcResult.value.errorAddParticipantsClientErrors.value;
|
||||||
|
data.code = +code;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (rpcResult.name === 'AddParticipantsResponseServerError') {
|
||||||
|
const { code: code } = rpcResult.value.errorServerErrors.value;
|
||||||
|
data.code = +code;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
window.WWebJS.membershipRequestAction = async (groupId, action, requesterIds, sleep) => {
|
window.WWebJS.membershipRequestAction = async (groupId, action, requesterIds, sleep) => {
|
||||||
const groupWid = window.Store.WidFactory.createWid(groupId);
|
const groupWid = window.Store.WidFactory.createWid(groupId);
|
||||||
const group = await window.Store.Chat.find(groupWid);
|
const group = await window.Store.Chat.find(groupWid);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue