chore(): generate docs
This commit is contained in:
parent
b296ea8d5a
commit
30b3f5e82e
77 changed files with 1732 additions and 368 deletions
|
|
@ -4,7 +4,7 @@
|
|||
<head>
|
||||
<meta name="generator" content="JSDoc 3.6.11">
|
||||
<meta charset="utf-8">
|
||||
<title>whatsapp-web.js 1.31.1-alpha.0 » Source: Client.js</title>
|
||||
<title>whatsapp-web.js 1.32.0 » Source: Client.js</title>
|
||||
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Karla:400,400i,700,700i" type="text/css">
|
||||
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Noto+Serif:400,400i,700,700i" type="text/css">
|
||||
<link rel="stylesheet" href="https://brick.a.ssl.fastly.net/Inconsolata:500" type="text/css">
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
<nav id="jsdoc-navbar" role="navigation" class="jsdoc-navbar">
|
||||
<div id="jsdoc-navbar-container">
|
||||
<div id="jsdoc-navbar-content">
|
||||
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>31.<wbr>1-alpha.<wbr>0</a>
|
||||
<a href="index.html" class="jsdoc-navbar-package-name">whatsapp-web.<wbr>js 1.<wbr>32.<wbr>0</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
@ -46,7 +46,7 @@ const { LoadUtils } = require('./util/Injected/Utils');
|
|||
const ChatFactory = require('./factories/ChatFactory');
|
||||
const ContactFactory = require('./factories/ContactFactory');
|
||||
const WebCacheFactory = require('./webCache/WebCacheFactory');
|
||||
const { Broadcast, Buttons, Call, ClientInfo, Contact, GroupNotification, Label, List, Location, Message, MessageMedia, Poll, PollVote, Reaction } = require('./structures');
|
||||
const { ClientInfo, Message, MessageMedia, Contact, Location, Poll, PollVote, GroupNotification, Label, Call, Buttons, List, Reaction, Broadcast, ScheduledEvent } = require('./structures');
|
||||
const NoAuth = require('./authStrategies/NoAuth');
|
||||
const {exposeFunctionIfAbsent} = require('./util/Puppeteer');
|
||||
|
||||
|
|
@ -67,6 +67,8 @@ const {exposeFunctionIfAbsent} = require('./util/Puppeteer');
|
|||
* @param {string} options.userAgent - User agent to use in puppeteer
|
||||
* @param {string} options.ffmpegPath - Ffmpeg path to use when formatting videos to webp while sending stickers
|
||||
* @param {boolean} options.bypassCSP - Sets bypassing of page's Content-Security-Policy.
|
||||
* @param {string} options.deviceName - Sets the device name of a current linked device., i.e.: 'TEST'.
|
||||
* @param {string} options.browserName - Sets the browser name of a current linked device, i.e.: 'Firefox'.
|
||||
* @param {object} options.proxyAuthentication - Proxy Authentication object.
|
||||
*
|
||||
* @fires Client#qr
|
||||
|
|
@ -125,7 +127,8 @@ class Client extends EventEmitter {
|
|||
*/
|
||||
async inject() {
|
||||
await this.pupPage.waitForFunction('window.Debug?.VERSION != undefined', {timeout: this.options.authTimeoutMs});
|
||||
|
||||
await this.setDeviceName(this.options.deviceName, this.options.browserName);
|
||||
const pairWithPhoneNumber = this.options.pairWithPhoneNumber;
|
||||
const version = await this.getWWebVersion();
|
||||
const isCometOrAbove = parseInt(version.split('.')?.[1]) >= 3000;
|
||||
|
||||
|
|
@ -171,41 +174,55 @@ class Client extends EventEmitter {
|
|||
return;
|
||||
}
|
||||
|
||||
// Register qr events
|
||||
let qrRetries = 0;
|
||||
await exposeFunctionIfAbsent(this.pupPage, 'onQRChangedEvent', async (qr) => {
|
||||
/**
|
||||
* Emitted when a QR code is received
|
||||
* @event Client#qr
|
||||
* @param {string} qr QR Code
|
||||
*/
|
||||
this.emit(Events.QR_RECEIVED, qr);
|
||||
if (this.options.qrMaxRetries > 0) {
|
||||
qrRetries++;
|
||||
if (qrRetries > this.options.qrMaxRetries) {
|
||||
this.emit(Events.DISCONNECTED, 'Max qrcode retries reached');
|
||||
await this.destroy();
|
||||
// Register qr/code events
|
||||
if (pairWithPhoneNumber.phoneNumber) {
|
||||
await exposeFunctionIfAbsent(this.pupPage, 'onCodeReceivedEvent', async (code) => {
|
||||
/**
|
||||
* Emitted when a pairing code is received
|
||||
* @event Client#code
|
||||
* @param {string} code Code
|
||||
* @returns {string} Code that was just received
|
||||
*/
|
||||
this.emit(Events.CODE_RECEIVED, code);
|
||||
return code;
|
||||
});
|
||||
this.requestPairingCode(pairWithPhoneNumber.phoneNumber, pairWithPhoneNumber.showNotification, pairWithPhoneNumber.intervalMs);
|
||||
} else {
|
||||
let qrRetries = 0;
|
||||
await exposeFunctionIfAbsent(this.pupPage, 'onQRChangedEvent', async (qr) => {
|
||||
/**
|
||||
* Emitted when a QR code is received
|
||||
* @event Client#qr
|
||||
* @param {string} qr QR Code
|
||||
*/
|
||||
this.emit(Events.QR_RECEIVED, qr);
|
||||
if (this.options.qrMaxRetries > 0) {
|
||||
qrRetries++;
|
||||
if (qrRetries > this.options.qrMaxRetries) {
|
||||
this.emit(Events.DISCONNECTED, 'Max qrcode retries reached');
|
||||
await this.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
await this.pupPage.evaluate(async () => {
|
||||
const registrationInfo = await window.AuthStore.RegistrationUtils.waSignalStore.getRegistrationInfo();
|
||||
const noiseKeyPair = await window.AuthStore.RegistrationUtils.waNoiseInfo.get();
|
||||
const staticKeyB64 = window.AuthStore.Base64Tools.encodeB64(noiseKeyPair.staticKeyPair.pubKey);
|
||||
const identityKeyB64 = window.AuthStore.Base64Tools.encodeB64(registrationInfo.identityKeyPair.pubKey);
|
||||
const advSecretKey = await window.AuthStore.RegistrationUtils.getADVSecretKey();
|
||||
const platform = window.AuthStore.RegistrationUtils.DEVICE_PLATFORM;
|
||||
const getQR = (ref) => ref + ',' + staticKeyB64 + ',' + identityKeyB64 + ',' + advSecretKey + ',' + platform;
|
||||
|
||||
window.onQRChangedEvent(getQR(window.AuthStore.Conn.ref)); // initial qr
|
||||
window.AuthStore.Conn.on('change:ref', (_, ref) => { window.onQRChangedEvent(getQR(ref)); }); // future QR changes
|
||||
});
|
||||
await this.pupPage.evaluate(async () => {
|
||||
const registrationInfo = await window.AuthStore.RegistrationUtils.waSignalStore.getRegistrationInfo();
|
||||
const noiseKeyPair = await window.AuthStore.RegistrationUtils.waNoiseInfo.get();
|
||||
const staticKeyB64 = window.AuthStore.Base64Tools.encodeB64(noiseKeyPair.staticKeyPair.pubKey);
|
||||
const identityKeyB64 = window.AuthStore.Base64Tools.encodeB64(registrationInfo.identityKeyPair.pubKey);
|
||||
const advSecretKey = await window.AuthStore.RegistrationUtils.getADVSecretKey();
|
||||
const platform = window.AuthStore.RegistrationUtils.DEVICE_PLATFORM;
|
||||
const getQR = (ref) => ref + ',' + staticKeyB64 + ',' + identityKeyB64 + ',' + advSecretKey + ',' + platform;
|
||||
|
||||
window.onQRChangedEvent(getQR(window.AuthStore.Conn.ref)); // initial qr
|
||||
window.AuthStore.Conn.on('change:ref', (_, ref) => { window.onQRChangedEvent(getQR(ref)); }); // future QR changes
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await exposeFunctionIfAbsent(this.pupPage, 'onAuthAppStateChangedEvent', async (state) => {
|
||||
if (state == 'UNPAIRED_IDLE') {
|
||||
if (state == 'UNPAIRED_IDLE' &amp;&amp; !pairWithPhoneNumber.phoneNumber) {
|
||||
// refresh qr code
|
||||
window.Store.Cmd.refreshQR();
|
||||
}
|
||||
|
|
@ -374,15 +391,32 @@ class Client extends EventEmitter {
|
|||
/**
|
||||
* Request authentication via pairing code instead of QR code
|
||||
* @param {string} phoneNumber - Phone number in international, symbol-free format (e.g. 12025550108 for US, 551155501234 for Brazil)
|
||||
* @param {boolean} showNotification - Show notification to pair on phone number
|
||||
* @param {boolean} [showNotification = true] - Show notification to pair on phone number
|
||||
* @param {number} [intervalMs = 180000] - The interval in milliseconds on how frequent to generate pairing code (WhatsApp default to 3 minutes)
|
||||
* @returns {Promise&lt;string>} - Returns a pairing code in format "ABCDEFGH"
|
||||
*/
|
||||
async requestPairingCode(phoneNumber, showNotification = true) {
|
||||
return await this.pupPage.evaluate(async (phoneNumber, showNotification) => {
|
||||
window.AuthStore.PairingCodeLinkUtils.setPairingType('ALT_DEVICE_LINKING');
|
||||
await window.AuthStore.PairingCodeLinkUtils.initializeAltDeviceLinking();
|
||||
return window.AuthStore.PairingCodeLinkUtils.startAltLinkingFlow(phoneNumber, showNotification);
|
||||
}, phoneNumber, showNotification);
|
||||
async requestPairingCode(phoneNumber, showNotification = true, intervalMs = 180000) {
|
||||
return await this.pupPage.evaluate(async (phoneNumber, showNotification, intervalMs) => {
|
||||
const getCode = async () => {
|
||||
while (!window.AuthStore.PairingCodeLinkUtils) {
|
||||
await new Promise(resolve => setTimeout(resolve, 250));
|
||||
}
|
||||
window.AuthStore.PairingCodeLinkUtils.setPairingType('ALT_DEVICE_LINKING');
|
||||
await window.AuthStore.PairingCodeLinkUtils.initializeAltDeviceLinking();
|
||||
return window.AuthStore.PairingCodeLinkUtils.startAltLinkingFlow(phoneNumber, showNotification);
|
||||
};
|
||||
if (window.codeInterval) {
|
||||
clearInterval(window.codeInterval); // remove existing interval
|
||||
}
|
||||
window.codeInterval = setInterval(async () => {
|
||||
if (window.AuthStore.AppState.state != 'UNPAIRED' &amp;&amp; window.AuthStore.AppState.state != 'UNPAIRED_IDLE') {
|
||||
clearInterval(window.codeInterval);
|
||||
return;
|
||||
}
|
||||
window.onCodeReceivedEvent(await getCode());
|
||||
}, intervalMs);
|
||||
return window.onCodeReceivedEvent(await getCode());
|
||||
}, phoneNumber, showNotification, intervalMs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -844,6 +878,19 @@ class Client extends EventEmitter {
|
|||
});
|
||||
}
|
||||
|
||||
async setDeviceName(deviceName, browserName) {
|
||||
(deviceName || browserName) &amp;&amp; await this.pupPage.evaluate((deviceName, browserName) => {
|
||||
const func = window.require('WAWebMiscBrowserUtils').info;
|
||||
window.require('WAWebMiscBrowserUtils').info = () => {
|
||||
return {
|
||||
...func(),
|
||||
...(deviceName ? { os: deviceName } : {}),
|
||||
...(browserName ? { name: browserName } : {})
|
||||
};
|
||||
};
|
||||
}, deviceName, browserName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark as seen for the Chat
|
||||
* @param {string} chatId
|
||||
|
|
@ -954,6 +1001,9 @@ class Client extends EventEmitter {
|
|||
} else if (content instanceof Poll) {
|
||||
internalOptions.poll = content;
|
||||
content = '';
|
||||
} else if (content instanceof ScheduledEvent) {
|
||||
internalOptions.event = content;
|
||||
content = '';
|
||||
} else if (content instanceof Contact) {
|
||||
internalOptions.contactCard = content.id._serialized;
|
||||
content = '';
|
||||
|
|
@ -1158,6 +1208,29 @@ class Client extends EventEmitter {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets instances of all pinned messages in a chat
|
||||
* @param {string} chatId The chat ID
|
||||
* @returns {Promise&lt;[Message]|[]>}
|
||||
*/
|
||||
async getPinnedMessages(chatId) {
|
||||
const pinnedMsgs = await this.pupPage.evaluate(async (chatId) => {
|
||||
const chatWid = window.Store.WidFactory.createWid(chatId);
|
||||
const chat = window.Store.Chat.get(chatWid) ?? await window.Store.Chat.find(chatWid);
|
||||
if (!chat) return [];
|
||||
|
||||
const msgs = await window.Store.PinnedMsgUtils.getTable().equals(['chatId'], chatWid.toString());
|
||||
|
||||
const pinnedMsgs = msgs.map((msg) => window.Store.Msg.get(msg.parentMsgKey));
|
||||
|
||||
return !pinnedMsgs.length
|
||||
? []
|
||||
: pinnedMsgs.map((msg) => window.WWebJS.getMessageModel(msg));
|
||||
}, chatId);
|
||||
|
||||
return pinnedMsgs.map((msg) => new Message(this, msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object with information about the invite code's group
|
||||
* @param {string} inviteCode
|
||||
|
|
@ -1559,6 +1632,10 @@ class Client extends EventEmitter {
|
|||
* @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)
|
||||
* @property {boolean} [memberAddMode = false] If true, only admins can add members to the group (false by default)
|
||||
* @property {boolean} [membershipApprovalMode = false] If true, group admins will be required to approve anyone who wishes to join the group (false by default)
|
||||
* @property {boolean} [isRestrict = true] If true, only admins can change group group info (true by default)
|
||||
* @property {boolean} [isAnnounce = false] If true, only admins can send messages (false by default)
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -1573,7 +1650,12 @@ class Client extends EventEmitter {
|
|||
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 {
|
||||
messageTimer = 0,
|
||||
parentGroupId,
|
||||
autoSendInviteV4 = true,
|
||||
comment = '',
|
||||
} = options;
|
||||
const participantData = {}, participantWids = [], failedParticipants = [];
|
||||
let createGroupResult, parentGroupWid;
|
||||
|
||||
|
|
@ -1586,7 +1668,9 @@ class Client extends EventEmitter {
|
|||
|
||||
for (const participant of participants) {
|
||||
const pWid = window.Store.WidFactory.createWid(participant);
|
||||
if ((await window.Store.QueryExist(pWid))?.wid) participantWids.push(pWid);
|
||||
if ((await window.Store.QueryExist(pWid))?.wid) {
|
||||
participantWids.push({ phoneNumber: pWid });
|
||||
}
|
||||
else failedParticipants.push(participant);
|
||||
}
|
||||
|
||||
|
|
@ -1595,14 +1679,13 @@ class Client extends EventEmitter {
|
|||
try {
|
||||
createGroupResult = await window.Store.GroupUtils.createGroup(
|
||||
{
|
||||
'memberAddMode': options.memberAddMode === undefined ? true : options.memberAddMode,
|
||||
'membershipApprovalMode': options.membershipApprovalMode === undefined ? false : options.membershipApprovalMode,
|
||||
'announce': options.announce === undefined ? true : options.announce,
|
||||
'addressingModeOverride': 'lid',
|
||||
'memberAddMode': options.memberAddMode ?? false,
|
||||
'membershipApprovalMode': options.membershipApprovalMode ?? false,
|
||||
'announce': options.announce ?? false,
|
||||
'restrict': options.isRestrict !== undefined ? !options.isRestrict : false,
|
||||
'ephemeralDuration': messageTimer,
|
||||
'full': undefined,
|
||||
'parentGroupId': parentGroupWid,
|
||||
'restrict': options.restrict === undefined ? true : options.restrict,
|
||||
'thumb': undefined,
|
||||
'title': title,
|
||||
},
|
||||
participantWids
|
||||
|
|
@ -1613,13 +1696,14 @@ class Client extends EventEmitter {
|
|||
|
||||
for (const participant of createGroupResult.participants) {
|
||||
let isInviteV4Sent = false;
|
||||
participant.wid.server == 'lid' &amp;&amp; (participant.wid = window.Store.LidUtils.getPhoneNumber(participant.wid));
|
||||
const participantId = participant.wid._serialized;
|
||||
const statusCode = participant.error || 200;
|
||||
|
||||
if (autoSendInviteV4 &amp;&amp; statusCode === 403) {
|
||||
window.Store.Contact.gadd(participant.wid, { silent: true });
|
||||
const addParticipantResult = await window.Store.GroupInviteV4.sendGroupInviteMessage(
|
||||
await window.Store.Chat.find(participant.wid),
|
||||
window.Store.Chat.get(participant.wid) || await window.Store.Chat.find(participant.wid),
|
||||
createGroupResult.wid._serialized,
|
||||
createGroupResult.subject,
|
||||
participant.invite_code,
|
||||
|
|
@ -1627,9 +1711,7 @@ class Client extends EventEmitter {
|
|||
comment,
|
||||
await window.WWebJS.getProfilePicThumbToBase64(createGroupResult.wid)
|
||||
);
|
||||
isInviteV4Sent = window.compareWwebVersions(window.Debug.VERSION, '&lt;', '2.2335.6')
|
||||
? addParticipantResult === 'OK'
|
||||
: addParticipantResult.messageSendResult === 'OK';
|
||||
isInviteV4Sent = addParticipantResult.messageSendResult === 'OK';
|
||||
}
|
||||
|
||||
participantData[participantId] = {
|
||||
|
|
@ -2179,6 +2261,45 @@ class Client extends EventEmitter {
|
|||
}, chatId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a WhatsApp call link (video call or voice call)
|
||||
* @param {Date} startTime The start time of the call
|
||||
* @param {string} callType The type of a WhatsApp call link to generate, valid values are: `video` | `voice`
|
||||
* @returns {Promise&lt;string>} The WhatsApp call link (https://call.whatsapp.com/video/XxXxXxXxXxXxXx) or an empty string if a generation failed.
|
||||
*/
|
||||
async createCallLink(startTime, callType) {
|
||||
if (!['video', 'voice'].includes(callType)) {
|
||||
throw new class CreateCallLinkError extends Error {
|
||||
constructor(m) { super(m); }
|
||||
}('Invalid \'callType\' parameter value is provided. Valid values are: \'voice\' | \'video\'.');
|
||||
}
|
||||
|
||||
startTime = Math.floor(startTime.getTime() / 1000);
|
||||
|
||||
return await this.pupPage.evaluate(async (startTimeTs, callType) => {
|
||||
const response = await window.Store.ScheduledEventMsgUtils.createEventCallLink(startTimeTs, callType);
|
||||
return response ?? '';
|
||||
}, startTime, callType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a response to the scheduled event message, indicating whether a user is going to attend the event or not
|
||||
* @param {number} response The response code to the scheduled event message. Valid values are: `0` for NONE response (removes a previous response) | `1` for GOING | `2` for NOT GOING | `3` for MAYBE going
|
||||
* @param {string} eventMessageId The scheduled event message ID
|
||||
* @returns {Promise&lt;boolean>}
|
||||
*/
|
||||
async sendResponseToScheduledEvent(response, eventMessageId) {
|
||||
if (![0, 1, 2, 3].includes(response)) return false;
|
||||
|
||||
return await this.pupPage.evaluate(async (response, msgId) => {
|
||||
const eventMsg = window.Store.Msg.get(msgId) || (await window.Store.Msg.getMessagesById([msgId]))?.messages?.[0];
|
||||
if (!eventMsg) return false;
|
||||
|
||||
await window.Store.ScheduledEventMsgUtils.sendEventResponseMsg(response, eventMsg);
|
||||
return true;
|
||||
}, response, eventMessageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save new contact to user's addressbook or edit the existing one
|
||||
* @param {string} phoneNumber The contact's phone number in a format "17182222222", where "1" is a country code
|
||||
|
|
@ -2211,6 +2332,28 @@ class Client extends EventEmitter {
|
|||
return await window.Store.AddressbookContactUtils.deleteContactAction(phoneNumber);
|
||||
}, phoneNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lid and phone number for multiple users
|
||||
* @param {string[]} userIds - Array of user IDs
|
||||
* @returns {Promise&lt;Array&lt;{ lid: string, pn: string }>>}
|
||||
*/
|
||||
async getContactLidAndPhone(userIds) {
|
||||
return await this.pupPage.evaluate((userIds) => {
|
||||
!Array.isArray(userIds) &amp;&amp; (userIds = [userIds]);
|
||||
return userIds.map(userId => {
|
||||
const wid = window.Store.WidFactory.createWid(userId);
|
||||
const isLid = wid.server === 'lid';
|
||||
const lid = isLid ? wid : window.Store.LidUtils.getCurrentLid(wid);
|
||||
const phone = isLid ? window.Store.LidUtils.getPhoneNumber(wid) : wid;
|
||||
|
||||
return {
|
||||
lid: lid._serialized,
|
||||
pn: phone._serialized
|
||||
};
|
||||
});
|
||||
}, userIds);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Client;
|
||||
|
|
@ -2224,7 +2367,7 @@ module.exports = Client;
|
|||
<footer id="jsdoc-footer" class="jsdoc-footer">
|
||||
<div id="jsdoc-footer-container">
|
||||
<p>
|
||||
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.11 on June 30, 2025.
|
||||
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc</a> 3.6.11 on August 8, 2025.
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
|
|
|||
Loading…
Reference in a new issue