Socket
Socket
Sign inDemoInstall

@juzi/whatsapp-web.js

Package Overview
Dependencies
Maintainers
2
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@juzi/whatsapp-web.js - npm Package Compare versions

Comparing version 1.16.14 to 1.18.0

src/authStrategies/RemoteAuth.js

4

example.js

@@ -10,2 +10,6 @@ const { Client, Location, List, Buttons, LocalAuth} = require('./index');

client.on('loading_screen', (percent, message) => {
console.log('LOADING SCREEN', percent, message);
});
client.on('qr', (qr) => {

@@ -12,0 +16,0 @@ // NOTE: This event will not be fired if a session is specified.

import { EventEmitter } from 'events'
import { RequestInit } from 'node-fetch'
import puppeteer from 'puppeteer'
import * as puppeteer from 'puppeteer'

@@ -250,2 +250,11 @@ declare namespace WAWebJS {

/** Emitted when a reaction is sent, received, updated or removed */
on(event: 'message_reaction', listener: (
/** The reaction object */
reaction: Reaction
) => void): this
/** Emitted when loading screen is appearing */
on(event: 'loading_screen', listener: (percent: string, message: string) => void): this
/** Emitted when the QR code is received */

@@ -266,2 +275,5 @@ on(event: 'qr', listener: (

on(event: 'ready', listener: () => void): this
/** Emitted when the RemoteAuth session is saved successfully on the external Database */
on(event: 'remote_session_saved', listener: () => void): this
}

@@ -356,2 +368,5 @@

getAuthEventPayload: () => Promise<any>;
afterAuthReady: () => Promise<void>;
disconnect: () => Promise<void>;
destroy: () => Promise<void>;
logout: () => Promise<void>;

@@ -377,3 +392,27 @@ }

}
/**
* Remote-based authentication
*/
export class RemoteAuth extends AuthStrategy {
public clientId?: string;
public dataPath?: string;
constructor(options?: {
store: Store,
clientId?: string,
dataPath?: string,
backupSyncIntervalMs: number
})
}
/**
* Remote store interface
*/
export interface Store {
sessionExists: (options: { session: string }) => Promise<boolean> | boolean,
delete: (options: { session: string }) => Promise<any> | any,
save: (options: { session: string }) => Promise<any> | any,
extract: (options: { session: string, path: string }) => Promise<any> | any,
}
/**

@@ -476,5 +515,7 @@ * Legacy session auth strategy

QR_RECEIVED = 'qr',
LOADING_SCREEN = 'loading_screen',
DISCONNECTED = 'disconnected',
STATE_CHANGED = 'change_state',
BATTERY_CHANGED = 'change_battery',
REMOTE_SESSION_SAVED = 'remote_session_saved'
}

@@ -722,3 +763,3 @@

/**
* Forwards this message to another chat
* Forwards this message to another chat (that you chatted before, otherwise it will fail)
*/

@@ -820,2 +861,4 @@ forward: (chat: Chat | string) => Promise<void>,

filename?: string | null
/** Document file size in bytes. Value can be null. */
filesize?: number | null

@@ -826,4 +869,5 @@ /**

* @param {?string} filename Document file name. Value can be null
* @param {?number} filesize Document file size in bytes. Value can be null.
*/
constructor(mimetype: string, data: string, filename?: string | null)
constructor(mimetype: string, data: string, filename?: string | null, filesize?: number | null)

@@ -1035,2 +1079,6 @@ /** Creates a MessageMedia instance from a local file path */

limit?: number
/**
* Return only messages from the bot number or vise versa. To get all messages, leave the option undefined.
*/
fromMe?: boolean
}

@@ -1318,4 +1366,17 @@

}
/** Message type Reaction */
export class Reaction {
id: MessageId
orphan: number
orphanReason?: string
timestamp: number
reaction: string
read: boolean
msgId: MessageId
senderId: string
ack?: number
}
}
export = WAWebJS

@@ -28,2 +28,3 @@ 'use strict';

LocalAuth: require('./src/authStrategies/LocalAuth'),
RemoteAuth: require('./src/authStrategies/RemoteAuth'),
LegacySessionAuth: require('./src/authStrategies/LegacySessionAuth'),

@@ -30,0 +31,0 @@

117

package.json
{
"name": "@juzi/whatsapp-web.js",
"version": "1.16.14",
"description": "Library for interacting with the WhatsApp Web API ",
"main": "./index.js",
"typings": "./index.d.ts",
"scripts": {
"test": "mocha tests --recursive --timeout 5000",
"test-single": "mocha",
"shell": "node --experimental-repl-await ./shell.js",
"generate-docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --verbose"
},
"repository": {
"type": "git",
"url": "git+https://github.com/juzibot/whatsapp-web.js.git"
},
"keywords": [
"whatsapp",
"whatsapp-web",
"api",
"bot",
"client",
"node"
],
"author": "Pedro Lopez",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/juzibot/whatsapp-web.js/issues"
},
"homepage": "https://wwebjs.dev/",
"dependencies": {
"puppeteer-extra": "^3.2.3",
"puppeteer-extra-plugin-anonymize-ua": "^2.3.3",
"puppeteer-extra-plugin-stealth": "^2.9.0",
"@pedroslopez/moduleraid": "^5.0.2",
"fluent-ffmpeg": "^2.1.2",
"jsqr": "^1.3.1",
"mime": "^3.0.0",
"node-fetch": "^2.6.5",
"node-webpmux": "^3.1.0",
"puppeteer": "^13.0.0"
},
"devDependencies": {
"@types/node-fetch": "^2.5.12",
"chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
"dotenv": "^16.0.0",
"eslint": "^8.4.1",
"eslint-plugin-mocha": "^10.0.3",
"jsdoc": "^3.6.4",
"jsdoc-baseline": "^0.1.5",
"mocha": "^9.0.2",
"sinon": "^13.0.1"
},
"engines": {
"node": ">=12.0.0"
}
"name": "@juzi/whatsapp-web.js",
"version": "1.18.0",
"description": "Library for interacting with the WhatsApp Web API ",
"main": "./index.js",
"typings": "./index.d.ts",
"scripts": {
"test": "mocha tests --recursive --timeout 5000",
"test-single": "mocha",
"shell": "node --experimental-repl-await ./shell.js",
"generate-docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --verbose"
},
"repository": {
"type": "git",
"url": "git+https://github.com/juzibot/whatsapp-web.js.git"
},
"keywords": [
"whatsapp",
"whatsapp-web",
"api",
"bot",
"client",
"node"
],
"author": "Pedro Lopez",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/juzibot/whatsapp-web.js/issues"
},
"homepage": "https://wwebjs.dev/",
"dependencies": {
"puppeteer-extra": "^3.2.3",
"puppeteer-extra-plugin-anonymize-ua": "^2.3.3",
"puppeteer-extra-plugin-stealth": "^2.9.0",
"@pedroslopez/moduleraid": "^5.0.2",
"fluent-ffmpeg": "^2.1.2",
"jsqr": "^1.3.1",
"mime": "^3.0.0",
"node-fetch": "^2.6.5",
"node-webpmux": "^3.1.0",
"puppeteer": "^13.0.0"
},
"devDependencies": {
"@types/node-fetch": "^2.5.12",
"chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
"dotenv": "^16.0.0",
"eslint": "^8.4.1",
"eslint-plugin-mocha": "^10.0.3",
"jsdoc": "^3.6.4",
"jsdoc-baseline": "^0.1.5",
"mocha": "^9.0.2",
"sinon": "^13.0.1"
},
"engines": {
"node": ">=12.0.0"
},
"optionalDependencies": {
"archiver": "^5.3.1",
"fs-extra": "^10.1.0",
"unzipper": "^0.10.11"
}
}

@@ -1,2 +0,2 @@

[![npm](https://img.shields.io/npm/v/whatsapp-web.js.svg)](https://www.npmjs.com/package/whatsapp-web.js) [![Depfu](https://badges.depfu.com/badges/4a65a0de96ece65fdf39e294e0c8dcba/overview.svg)](https://depfu.com/github/pedroslopez/whatsapp-web.js?project_id=9765) ![WhatsApp_Web 2.2224.8](https://img.shields.io/badge/WhatsApp_Web-2.2224.8-brightgreen.svg) [![Discord Chat](https://img.shields.io/discord/698610475432411196.svg?logo=discord)](https://discord.gg/H7DqQs4)
[![npm](https://img.shields.io/npm/v/whatsapp-web.js.svg)](https://www.npmjs.com/package/whatsapp-web.js) [![Depfu](https://badges.depfu.com/badges/4a65a0de96ece65fdf39e294e0c8dcba/overview.svg)](https://depfu.com/github/pedroslopez/whatsapp-web.js?project_id=9765) ![WhatsApp_Web 2.2240.7](https://img.shields.io/badge/WhatsApp_Web-2.2240.7-brightgreen.svg) [![Discord Chat](https://img.shields.io/discord/698610475432411196.svg?logo=discord)](https://discord.gg/H7DqQs4)

@@ -3,0 +3,0 @@ # whatsapp-web.js

@@ -21,2 +21,5 @@ 'use strict';

async getAuthEventPayload() {}
async afterAuthReady() {}
async disconnect() {}
async destroy() {}
async logout() {}

@@ -23,0 +26,0 @@ }

@@ -18,3 +18,3 @@ 'use strict';

const ContactFactory = require('./factories/ContactFactory');
const { ClientInfo, Message, MessageMedia, Contact, Location, GroupNotification, Label, Call, Buttons, List} = require('./structures');
const { ClientInfo, Message, MessageMedia, Contact, Location, GroupNotification, Label, Call, Buttons, List, Reaction } = require('./structures');
const LegacySessionAuth = require('./authStrategies/LegacySessionAuth');

@@ -124,2 +124,48 @@ const NoAuth = require('./authStrategies/NoAuth');

await page.evaluate(`function getElementByXpath(path) {
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}`);
let lastPercent = null,
lastPercentMessage = null;
await page.exposeFunction('loadingScreen', async (percent, message) => {
if (lastPercent !== percent || lastPercentMessage !== message) {
this.emit(Events.LOADING_SCREEN, percent, message);
lastPercent = percent;
lastPercentMessage = message;
}
});
await page.evaluate(
async function (selectors) {
var observer = new MutationObserver(function () {
let progressBar = window.getElementByXpath(
selectors.PROGRESS
);
let progressMessage = window.getElementByXpath(
selectors.PROGRESS_MESSAGE
);
if (progressBar) {
window.loadingScreen(
progressBar.value,
progressMessage.innerText
);
}
});
observer.observe(document, {
attributes: true,
childList: true,
characterData: true,
subtree: true,
});
},
{
PROGRESS: '//*[@id=\'app\']/div/div/div[2]/progress',
PROGRESS_MESSAGE: '//*[@id=\'app\']/div/div/div[3]',
}
);
const INTRO_IMG_SELECTOR = '[data-testid="intro-md-beta-logo-dark"], [data-testid="intro-md-beta-logo-light"], [data-asset-intro-image-light="true"], [data-asset-intro-image-dark="true"]';

@@ -383,3 +429,3 @@ const INTRO_QRCODE_SELECTOR = 'div[data-ref] canvas';

await page.exposeFunction('onAppStateChangedEvent', (state) => {
await page.exposeFunction('onAppStateChangedEvent', async (state) => {

@@ -411,2 +457,3 @@ /**

*/
await this.authStrategy.disconnect();
this.emit(Events.DISCONNECTED, state);

@@ -451,2 +498,23 @@ this.destroy();

await page.exposeFunction('onReaction', (reactions) => {
for (const reaction of reactions) {
/**
* Emitted when a reaction is sent, received, updated or removed
* @event Client#message_reaction
* @param {object} reaction
* @param {object} reaction.id - Reaction id
* @param {number} reaction.orphan - Orphan
* @param {?string} reaction.orphanReason - Orphan reason
* @param {number} reaction.timestamp - Timestamp
* @param {string} reaction.reaction - Reaction
* @param {boolean} reaction.read - Read
* @param {object} reaction.msgId - Parent message id
* @param {string} reaction.senderId - Sender id
* @param {?number} reaction.ack - Ack
*/
this.emit(Events.MESSAGE_REACTION, new Reaction(this, reaction));
}
});
await page.evaluate(() => {

@@ -471,2 +539,18 @@ window.Store.Msg.on('change', (msg) => { window.onChangeMessageEvent(window.WWebJS.getMessageModel(msg)); });

});
{
const module = window.Store.createOrUpdateReactionsModule;
const ogMethod = module.createOrUpdateReactions;
module.createOrUpdateReactions = ((...args) => {
window.onReaction(args[0].map(reaction => {
const msgKey = window.Store.MsgKey.fromString(reaction.msgKey);
const parentMsgKey = window.Store.MsgKey.fromString(reaction.parentMsgKey);
const timestamp = reaction.timestamp / 1000;
return {...reaction, msgKey, parentMsgKey, timestamp };
}));
return ogMethod(...args);
}).bind(module);
}
});

@@ -484,2 +568,3 @@

if(!appState || appState === WAState.PAIRING) {
await this.authStrategy.disconnect();
this.emit(Events.DISCONNECTED, 'NAVIGATION');

@@ -927,3 +1012,9 @@ await this.destroy();

const commonGroups = await this.pupPage.evaluate(async (contactId) => {
const contact = window.Store.Contact.get(contactId);
let contact = window.Store.Contact.get(contactId);
if (!contact) {
const wid = window.Store.WidFactory.createUserWid(contactId);
const chatConstructor = window.Store.Contact.getModelsArray().find(c=>!c.isGroup).constructor;
contact = new chatConstructor({id: wid});
}
if (contact.commonGroups) {

@@ -930,0 +1021,0 @@ return contact.commonGroups.serialize();

@@ -173,4 +173,5 @@ 'use strict';

* Loads chat messages, sorted from earliest to latest.
* @param {Object} searchOptions Options for searching messages. Right now only limit is supported.
* @param {Object} searchOptions Options for searching messages. Right now only limit and fromMe is supported.
* @param {Number} [searchOptions.limit] The amount of messages to return. If no limit is specified, the available messages will be returned. Note that the actual number of returned messages may be smaller if there aren't enough messages in the conversation. Set this to Infinity to load all messages.
* @param {Boolean} [searchOptions.fromMe] Return only messages from the bot number or vise versa. To get all messages, leave the option undefined.
* @returns {Promise<Array<Message>>}

@@ -180,3 +181,11 @@ */

let messages = await this.client.pupPage.evaluate(async (chatId, searchOptions) => {
const msgFilter = m => !m.isNotification; // dont include notification messages
const msgFilter = (m) => {
if (m.isNotification) {
return false; // dont include notification messages
}
if (searchOptions && searchOptions.fromMe && m.id.fromMe !== searchOptions.fromMe) {
return false;
}
return true;
};

@@ -183,0 +192,0 @@ const chat = window.Store.Chat.get(chatId);

@@ -21,2 +21,3 @@ module.exports = {

Payment: require('./Payment'),
Reaction: require('./Reaction'),
};

@@ -345,2 +345,4 @@ 'use strict';

await this.client.pupPage.evaluate(async (messageId, reaction) => {
if (!messageId) { return undefined; }
const msg = await window.Store.Msg.get(messageId);

@@ -360,3 +362,3 @@ await window.Store.sendReactionToMsg(msg, reaction);

/**
* Forwards this message to another chat
* Forwards this message to another chat (that you chatted before, otherwise it will fail)
*

@@ -413,3 +415,3 @@ * @param {string|Chat} chat Chat model or chat ID to which the message will be forwarded

const data = window.WWebJS.arrayBufferToBase64(decryptedMedia);
const data = await window.WWebJS.arrayBufferToBase64Async(decryptedMedia);

@@ -419,3 +421,4 @@ return {

mimetype: msg.mimetype,
filename: msg.filename
filename: msg.filename,
filesize: msg.size
};

@@ -429,3 +432,3 @@ } catch (e) {

if (!result) return undefined;
return new MessageMedia(result.mimetype, result.data, result.filename);
return new MessageMedia(result.mimetype, result.data, result.filename, result.filesize);
}

@@ -435,3 +438,3 @@

* Deletes a message from the chat
* @param {?boolean} everyone If true and the message is sent by the current user, will delete it for everyone in the chat.
* @param {?boolean} everyone If true and the message is sent by the current user or the user is an admin, will delete it for everyone in the chat.
*/

@@ -442,4 +445,4 @@ async delete(everyone) {

if (everyone && msg.id.fromMe && msg._canRevoke()) {
return window.Store.Cmd.sendRevokeMsgs(msg.chat, [msg], {type: 'Sender'});
if (everyone && msg._canRevoke()) {
return window.Store.Cmd.sendRevokeMsgs(msg.chat, [msg], { type: msg.id.fromMe ? 'Sender' : 'Admin' });
}

@@ -459,3 +462,3 @@

if (msg.canStar()) {
return msg.chat.sendStarMsgs([msg], true);
return window.Store.Cmd.sendStarMsgs(msg.chat, [msg], false);
}

@@ -473,3 +476,3 @@ }, this.id._serialized);

if (msg.canStar()) {
return msg.chat.sendStarMsgs([msg], false);
return window.Store.Cmd.sendUnstarMsgs(msg.chat, [msg], false);
}

@@ -476,0 +479,0 @@ }, this.id._serialized);

@@ -13,6 +13,7 @@ 'use strict';

* @param {string} data Base64-encoded data of the file
* @param {?string} filename Document file name
* @param {?string} filename Document file name. Value can be null
* @param {?number} filesize Document file size in bytes. Value can be null
*/
class MessageMedia {
constructor(mimetype, data, filename) {
constructor(mimetype, data, filename, filesize) {
/**

@@ -31,6 +32,12 @@ * MIME type of the attachment

/**
* Name of the file (for documents)
* Document file name. Value can be null
* @type {?string}
*/
this.filename = filename;
/**
* Document file size in bytes. Value can be null
* @type {?number}
*/
this.filesize = filesize;
}

@@ -73,2 +80,3 @@

const mime = response.headers.get('Content-Type');
const size = response.headers.get('Content-Length');

@@ -89,3 +97,3 @@ const contentDisposition = response.headers.get('Content-Disposition');

return { data, mime, name };
return { data, mime, name, size };
}

@@ -103,3 +111,3 @@

return new MessageMedia(mimetype, res.data, filename);
return new MessageMedia(mimetype, res.data, filename, res.size || null);
}

@@ -106,0 +114,0 @@ }

@@ -14,3 +14,3 @@ 'use strict';

takeoverTimeoutMs: 0,
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36',
ffmpegPath: 'ffmpeg',

@@ -45,2 +45,3 @@ bypassCSP: false

MESSAGE_ACK: 'message_ack',
MESSAGE_REACTION: 'message_reaction',
MEDIA_UPLOADED: 'media_uploaded',

@@ -51,6 +52,8 @@ GROUP_JOIN: 'group_join',

QR_RECEIVED: 'qr',
LOADING_SCREEN: 'loading_screen',
DISCONNECTED: 'disconnected',
STATE_CHANGED: 'change_state',
BATTERY_CHANGED: 'change_battery',
INCOMING_CALL: 'incoming_call'
INCOMING_CALL: 'incoming_call',
REMOTE_SESSION_SAVED: 'remote_session_saved'
};

@@ -57,0 +60,0 @@

@@ -53,2 +53,4 @@ 'use strict';

window.Store.sendReactionToMsg = window.mR.findModule('sendReactionToMsg')[0].sendReactionToMsg;
window.Store.createOrUpdateReactionsModule = window.mR.findModule('createOrUpdateReactions')[0];
window.Store.EphemeralFields = window.mR.findModule('getEphemeralFields')[0];
window.Store.StickerTools = {

@@ -230,7 +232,3 @@ ...window.mR.findModule('toWebpSticker')[0],

const ephemeralSettings = {
ephemeralDuration: chat.isEphemeralSettingOn() ? chat.getEphemeralSetting() : undefined,
ephemeralSettingTimestamp: chat.getEphemeralSettingTimestamp() || undefined,
disappearingModeInitiator: chat.getDisappearingModeInitiator() || undefined,
};
const ephemeralFields = window.Store.EphemeralFields.getEphemeralFields(chat);

@@ -249,3 +247,3 @@ const message = {

type: 'chat',
...ephemeralSettings,
...ephemeralFields,
...locationOptions,

@@ -371,3 +369,3 @@ ...attOptions,

msg.isStatusV3 = message.isStatusV3;
msg.links = (message.getLinks()).map(link => ({
msg.links = (message.getRawLinks()).map(link => ({
link: link.href,

@@ -486,2 +484,16 @@ isSuspicious: Boolean(link.suspiciousCharacters && link.suspiciousCharacters.size)

window.WWebJS.arrayBufferToBase64Async = (arrayBuffer) =>
new Promise((resolve, reject) => {
const blob = new Blob([arrayBuffer], {
type: 'application/octet-stream',
});
const fileReader = new FileReader();
fileReader.onload = () => {
const [, data] = fileReader.result.split(',');
resolve(data);
};
fileReader.onerror = (e) => reject(e);
fileReader.readAsDataURL(blob);
});
window.WWebJS.getFileHash = async (data) => {

@@ -488,0 +500,0 @@ let buffer = await data.arrayBuffer();

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc