wppconnect-api / dist /api /layers /host.layer.js
AUXteam's picture
Upload folder using huggingface_hub
9844ee9 verified
"use strict";
/*
* This file is part of WPPConnect.
*
* WPPConnect is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* WPPConnect is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with WPPConnect. If not, see <https://www.gnu.org/licenses/>.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.HostLayer = void 0;
const create_config_1 = require("../../config/create-config");
const auth_1 = require("../../controllers/auth");
const browser_1 = require("../../controllers/browser");
const logger_1 = require("../../utils/logger");
const sleep_1 = require("../../utils/sleep");
const helpers_1 = require("../helpers");
class HostLayer {
constructor(page, session, options) {
this.page = page;
this.autoCloseInterval = null;
this.autoCloseCalled = false;
this.isInitialized = false;
this.isInjected = false;
this.isStarted = false;
this.isLogged = false;
this.isInChat = false;
this.checkStartInterval = null;
this.urlCode = '';
this.attempt = 0;
this.catchQR = null;
this.statusFind = null;
this.onLoadingScreen = null;
this.catchLinkCode = null;
this.session = session;
this.options = { ...create_config_1.defaultOptions, ...options };
this.logger = this.options.logger || logger_1.defaultLogger;
this.log('info', 'Initializing...');
this.initialize();
}
log(level, message, meta = {}) {
this.logger.log({
level,
message,
session: this.session,
type: 'client',
...meta,
});
}
async initialize() {
this.page.on('close', () => {
this.cancelAutoClose();
this.log('verbose', 'Page Closed', { type: 'page' });
});
this.page.on('load', () => {
this.log('verbose', 'Page loaded', { type: 'page' });
this.afterPageLoad();
});
this.isInitialized = true;
}
async afterPageLoad() {
this.log('verbose', 'Injecting wapi.js');
const options = {
deviceName: this.options.deviceName,
disableGoogleAnalytics: this.options.disableGoogleAnalytics,
googleAnalyticsId: this.options.googleAnalyticsId,
linkPreviewApiServers: this.options.linkPreviewApiServers,
poweredBy: this.options.poweredBy,
};
await (0, helpers_1.evaluateAndReturn)(this.page, (options) => {
window.WPPConfig = options;
}, options);
this.isInjected = false;
await (0, browser_1.injectApi)(this.page, this.onLoadingScreen)
.then(() => {
this.isInjected = true;
this.log('verbose', 'wapi.js injected');
this.afterPageScriptInjected();
})
.catch((e) => {
console.log(e);
this.log('verbose', 'wapi.js failed');
this.log('error', e);
});
}
async afterPageScriptInjected() {
this.getWAVersion()
.then((version) => {
this.log('info', `WhatsApp WEB version: ${version}`);
})
.catch(() => null);
this.getWAJSVersion()
.then((version) => {
this.log('info', `WA-JS version: ${version}`);
})
.catch(() => null);
(0, helpers_1.evaluateAndReturn)(this.page, () => {
WPP.on('conn.auth_code_change', window.checkQrCode);
}).catch(() => null);
(0, helpers_1.evaluateAndReturn)(this.page, () => {
WPP.on('conn.main_ready', window.checkInChat);
}).catch(() => null);
this.checkInChat();
this.checkQrCode();
}
async start() {
if (this.isStarted) {
return;
}
this.isStarted = true;
await (0, browser_1.initWhatsapp)(this.page, null, false, this.options.whatsappVersion, this.options.proxy, this.log.bind(this));
await this.page.exposeFunction('checkQrCode', () => this.checkQrCode());
/*await this.page.exposeFunction('loginByCode', (phone: string) =>
this.loginByCode(phone)
);*/
await this.page.exposeFunction('checkInChat', () => this.checkInChat());
this.checkStartInterval = setInterval(() => this.checkStart(), 5000);
this.page.on('close', () => {
clearInterval(this.checkStartInterval);
});
}
async checkStart() {
(0, auth_1.needsToScan)(this.page)
.then((need) => { })
.catch(() => null);
}
async checkQrCode() {
var _a;
const needScan = await (0, auth_1.needsToScan)(this.page).catch(() => null);
this.isLogged = !needScan;
if (!needScan) {
this.attempt = 0;
return;
}
const result = await this.getQrCode();
if (!(result === null || result === void 0 ? void 0 : result.urlCode) || this.urlCode === result.urlCode) {
return;
}
if (typeof this.options.phoneNumber === 'string') {
return this.loginByCode(this.options.phoneNumber);
}
this.urlCode = result.urlCode;
this.attempt++;
let qr = '';
if (this.options.logQR || this.catchQR) {
qr = await (0, auth_1.asciiQr)(this.urlCode);
}
if (this.options.logQR) {
this.log('info', `Waiting for QRCode Scan (Attempt ${this.attempt})...:\n${qr}`, { code: this.urlCode });
}
else {
this.log('verbose', `Waiting for QRCode Scan: Attempt ${this.attempt}`);
}
(_a = this.catchQR) === null || _a === void 0 ? void 0 : _a.call(this, result.base64Image, qr, this.attempt, result.urlCode);
}
async loginByCode(phone) {
var _a;
const code = await (0, helpers_1.evaluateAndReturn)(this.page, async ({ phone }) => {
return JSON.parse(JSON.stringify(await WPP.conn.genLinkDeviceCodeForPhoneNumber(phone)));
}, { phone });
if (this.options.logQR) {
this.log('info', `Waiting for Login By Code (Code: ${code})\n`);
}
else {
this.log('verbose', `Waiting for Login By Code`);
}
(_a = this.catchLinkCode) === null || _a === void 0 ? void 0 : _a.call(this, code);
}
async checkInChat() {
var _a;
const inChat = await (0, auth_1.isInsideChat)(this.page).catch(() => null);
this.isInChat = !!inChat;
if (!inChat) {
return;
}
this.log('http', 'Connected');
(_a = this.statusFind) === null || _a === void 0 ? void 0 : _a.call(this, 'inChat', this.session);
}
tryAutoClose() {
if (this.autoCloseInterval) {
this.cancelAutoClose();
}
if ((this.options.autoClose > 0 || this.options.deviceSyncTimeout > 0) &&
!this.autoCloseInterval &&
!this.page.isClosed()) {
this.log('info', 'Closing the page');
this.autoCloseCalled = true;
this.statusFind && this.statusFind('autocloseCalled', this.session);
try {
this.page.close();
}
catch (error) { }
}
}
startAutoClose(time = null) {
if (time === null || time === undefined) {
time = this.options.autoClose;
}
if (time > 0 && !this.autoCloseInterval) {
const seconds = Math.round(time / 1000);
this.log('info', `Auto close configured to ${seconds}s`);
let remain = seconds;
this.autoCloseInterval = setInterval(() => {
if (this.page.isClosed()) {
this.cancelAutoClose();
return;
}
remain -= 1;
if (remain % 10 === 0 || remain <= 5) {
this.log('http', `Auto close remain: ${remain}s`);
}
if (remain <= 0) {
this.tryAutoClose();
}
}, 1000);
}
}
cancelAutoClose() {
clearInterval(this.autoCloseInterval);
this.autoCloseInterval = null;
}
async getQrCode() {
let qrResult;
qrResult = await (0, helpers_1.scrapeImg)(this.page).catch(() => undefined);
return qrResult;
}
async waitForQrCodeScan() {
if (!this.isStarted) {
throw new Error('waitForQrCodeScan error: Session not started');
}
while (!this.page.isClosed() && !this.isLogged) {
await (0, sleep_1.sleep)(200);
const needScan = await (0, auth_1.needsToScan)(this.page).catch(() => null);
this.isLogged = !needScan;
}
}
async waitForInChat() {
if (!this.isStarted) {
throw new Error('waitForInChat error: Session not started');
}
if (!this.isLogged) {
return false;
}
const start = Date.now();
while (!this.page.isClosed() && this.isLogged && !this.isInChat) {
if (this.options.deviceSyncTimeout > 0 &&
Date.now() - start >= this.options.deviceSyncTimeout) {
return false;
}
await (0, sleep_1.sleep)(1000);
const inChat = (0, auth_1.isInsideChat)(this.page).catch(() => null);
this.isInChat = !!inChat;
}
return this.isInChat;
}
async waitForPageLoad() {
while (!this.isInjected) {
await (0, sleep_1.sleep)(200);
}
await this.page.waitForFunction(() => WPP.isReady).catch(() => { });
}
async waitForLogin() {
var _a, _b, _c, _d, _e, _f;
this.log('http', 'Waiting page load');
await this.waitForPageLoad();
this.log('http', 'Checking is logged...');
let authenticated = await (0, auth_1.isAuthenticated)(this.page).catch(() => null);
this.startAutoClose();
if (authenticated === false) {
this.log('http', typeof this.options.phoneNumber === 'string'
? 'Waiting for Login by Code...'
: 'Waiting for QRCode Scan...');
(_a = this.statusFind) === null || _a === void 0 ? void 0 : _a.call(this, 'notLogged', this.session);
await this.waitForQrCodeScan();
this.log('http', typeof this.options.phoneNumber === 'string'
? 'Checking Login by Code status...'
: 'Checking QRCode status...');
// Wait for interface update
await (0, sleep_1.sleep)(200);
authenticated = await (0, auth_1.isAuthenticated)(this.page).catch(() => null);
if (authenticated === null) {
this.log('warn', 'Failed to authenticate');
(_b = this.statusFind) === null || _b === void 0 ? void 0 : _b.call(this, 'qrReadError', this.session);
}
else if (authenticated) {
this.log('http', 'Login with success');
(_c = this.statusFind) === null || _c === void 0 ? void 0 : _c.call(this, 'qrReadSuccess', this.session);
}
else {
this.log('warn', 'Login Fail');
(_d = this.statusFind) === null || _d === void 0 ? void 0 : _d.call(this, 'qrReadFail', this.session);
this.tryAutoClose();
throw new Error('Failed to read the QRCode');
}
}
else if (authenticated === true) {
this.log('http', 'Authenticated');
(_e = this.statusFind) === null || _e === void 0 ? void 0 : _e.call(this, 'isLogged', this.session);
}
if (authenticated === true) {
// Reinicia o contador do autoclose
this.cancelAutoClose();
// Wait for interface update
await (0, sleep_1.sleep)(200);
this.startAutoClose(this.options.deviceSyncTimeout);
this.log('http', 'Checking phone is connected...');
const inChat = await this.waitForInChat();
if (!inChat) {
this.log('warn', 'Phone not connected');
(_f = this.statusFind) === null || _f === void 0 ? void 0 : _f.call(this, 'phoneNotConnected', this.session);
this.tryAutoClose();
throw new Error('Phone not connected');
}
this.cancelAutoClose();
return true;
}
if (authenticated === false) {
this.tryAutoClose();
this.log('warn', 'Not logged');
throw new Error('Not logged');
}
this.tryAutoClose();
if (this.autoCloseCalled) {
this.log('error', 'Auto Close Called');
throw new Error('Auto Close Called');
}
if (this.page.isClosed()) {
this.log('error', 'Page Closed');
throw new Error('Page Closed');
}
this.log('error', 'Unknow error');
throw new Error('Unknow error');
}
/**
* @category Host
* @returns Current host device details
*/
async getHostDevice() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WAPI.getHost());
}
/**
* @category Host
* @returns Current wid connected
*/
async getWid() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WAPI.getWid());
}
/**
* Retrieves WA version
* @category Host
*/
async getWAVersion() {
await this.page
.waitForFunction(() => WAPI.getWAVersion())
.catch(() => null);
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WAPI.getWAVersion());
}
/**
* Retrieves WA-JS version
* @category Host
*/
async getWAJSVersion() {
await this.page.waitForFunction(() => WPP.version).catch(() => null);
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WPP.version);
}
/**
* Retrieves the connection state
* @category Host
*/
async getConnectionState() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => {
return WPP.whatsapp.Socket.state;
});
}
/**
* Retrieves if the phone is online. Please note that this may not be real time.
* @category Host
*/
async isConnected() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WAPI.isConnected());
}
/**
* Check is online
* @category Host
*/
async isOnline() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WPP.conn.isOnline());
}
/**
* Retrieves if the phone is online. Please note that this may not be real time.
* @category Host
*/
async isLoggedIn() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WAPI.isLoggedIn());
}
/**
* Retrieves Battery Level
* @category Host
*/
async getBatteryLevel() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WAPI.getBatteryLevel());
}
/**
* Start phone Watchdog, forcing the phone connection verification.
*
* @category Host
* @param interval interval number in miliseconds
*/
async startPhoneWatchdog(interval = 15000) {
return await (0, helpers_1.evaluateAndReturn)(this.page, (interval) => WAPI.startPhoneWatchdog(interval), interval);
}
/**
* Stop phone Watchdog, more details in {@link startPhoneWatchdog}
* @category Host
*/
async stopPhoneWatchdog(interval) {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WAPI.stopPhoneWatchdog());
}
/**
* Check the current session is an MultiDevice session
* @category Host
*/
async isMultiDevice() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WPP.conn.isMultiDevice());
}
/**
* Retrieve main interface is authenticated, loaded and synced
* @category Host
*/
async isMainReady() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WPP.conn.isMainReady());
}
/**
* Retrieve if is authenticated
* @category Host
*/
async isAuthenticated() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WPP.conn.isAuthenticated());
}
/**
* Retrieve if main interface is authenticated and loaded, bot not synced
* @category Host
*/
async isMainLoaded() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WPP.conn.isMainLoaded());
}
/**
* Retrieve if main interface is initializing
* @category Host
*/
async isMainInit() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WPP.conn.isMainInit());
}
/**
* Join or leave of WhatsApp Web beta program.
* Will return the value seted
* @category Host
*/
async joinWebBeta(value) {
return await (0, helpers_1.evaluateAndReturn)(this.page, (value) => WPP.conn.joinWebBeta(value), value);
}
/**
* Get WhatsApp build constants
* @category Host
* @returns Build constants information
*/
async getBuildConstants() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WPP.conn.getBuildConstants());
}
/**
* Check if the account has been migrated to LID
* @category Host
* @returns true if the account has been migrated to LID, false otherwise
*/
async isLidMigrated() {
return await (0, helpers_1.evaluateAndReturn)(this.page, () => WPP.whatsapp.functions.isLidMigrated());
}
}
exports.HostLayer = HostLayer;