@juzi/wechaty-puppet-whatsapp
Version:
Wechaty Puppet for WhatsApp
202 lines • 9.22 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable no-case-declarations */
const PUPPET = __importStar(require("@juzi/wechaty-puppet"));
const config_js_1 = require("../../config.js");
const error_type_js_1 = require("../../exception/error-type.js");
const whatsapp_error_js_1 = __importDefault(require("../../exception/whatsapp-error.js"));
const whatsapp_interface_js_1 = require("../../schema/whatsapp-interface.js");
const whatsapp_base_js_1 = __importDefault(require("../whatsapp-base.js"));
const miscellaneous_js_1 = require("../../helper/miscellaneous.js");
const PRE = 'LoginEventHandler';
class LoginEventHandler extends whatsapp_base_js_1.default {
loadingData = false;
qrcodeOrLoginCheckTimer;
hasLogin = false;
lastQRCodeTime = Date.now();
onQRCode(qrcode) {
config_js_1.log.info(PRE, `onQRCode(${qrcode})`);
// NOTE: This event will not be fired if a session is specified.
this.lastQRCodeTime = Date.now();
this.hasLogin = false;
this.emit('scan', { qrcode, status: PUPPET.types.ScanStatus.Waiting, timestamp: Date.now() });
this.checkQRCodeOrLoginEvent();
}
checkQRCodeOrLoginEvent() {
if (this.qrcodeOrLoginCheckTimer) {
return;
}
this.qrcodeOrLoginCheckTimer = setInterval(() => {
if (!this.hasLogin && Date.now() > this.lastQRCodeTime + 2 * 60 * 1000) {
this.emit('error', 'can not get scan or login event more than 2 mins');
}
}, 25 * 1000);
}
clearQrcodeOrLoginCheckTimer() {
if (!this.qrcodeOrLoginCheckTimer) {
return;
}
clearInterval(this.qrcodeOrLoginCheckTimer);
}
async onAuthenticated() {
config_js_1.log.info(PRE, 'onAuthenticated()');
}
async onAuthFailure(message) {
config_js_1.log.warn(PRE, 'auth_failure: %s', message);
// avoid reuse invalid session data
await this.clearSession();
}
async onWhatsAppReady() {
config_js_1.log.verbose(PRE, 'onWhatsAppReady()');
if (this.hasLogin) {
config_js_1.log.info(PRE, 'onWhatsAppReady() already login, skip');
return;
}
this.hasLogin = true;
this.clearQrcodeOrLoginCheckTimer();
const whatsapp = this.getWhatsAppClient();
try {
this.botId = whatsapp.info.wid._serialized;
await this.manager.initCache(this.botId);
}
catch (error) {
throw (0, whatsapp_error_js_1.default)(error_type_js_1.WA_ERROR_TYPE.ERR_INIT, `Can not get bot id from WhatsApp client, current state: ${await whatsapp.getState()}`, JSON.stringify(error));
}
await this.onLogin();
const contactOrRoomList = await this.manager.syncContactOrRoomList();
await this.onReady(contactOrRoomList);
this.manager.startSchedule();
}
async onLogin() {
config_js_1.log.verbose(PRE, 'onLogin()');
const whatsapp = this.getWhatsAppClient();
config_js_1.log.info(PRE, `WhatsApp Client Info: ${JSON.stringify(whatsapp.info)}`);
const cacheManager = await this.manager.getCacheManager();
const botSelf = await this.manager.requestManager.getContactById(this.botId);
await cacheManager.setContactOrRoomRawPayload(this.botId, {
...botSelf,
avatar: await this.manager.requestManager.getAvatarUrl(this.botId),
});
this.emit('login', this.botId);
config_js_1.log.info(PRE, `onLogin(${this.botId}})`);
}
async onReady(contactOrRoomList) {
config_js_1.log.verbose(PRE, 'onReady()');
if (this.loadingData) {
config_js_1.log.verbose(PRE, 'onReady() loading data are under process.');
return;
}
this.loadingData = true;
let friendCount = 0;
let contactCount = 0;
let roomCount = 0;
const cacheManager = await this.manager.getCacheManager();
const batchSize = 100;
await (0, miscellaneous_js_1.batchProcess)(batchSize, contactOrRoomList, async (contactOrRoom) => {
const contactOrRoomId = contactOrRoom.id._serialized;
const avatar = await contactOrRoom.getProfilePicUrl();
const contactWithAvatar = Object.assign(contactOrRoom, { avatar });
if ((0, miscellaneous_js_1.isContactId)(contactOrRoomId)) {
contactCount++;
if (contactOrRoom.isMyContact) {
friendCount++;
}
await cacheManager.setContactOrRoomRawPayload(contactOrRoomId, contactWithAvatar);
}
else if ((0, miscellaneous_js_1.isRoomId)(contactOrRoomId)) {
const memberList = await this.manager.syncRoomMemberList(contactOrRoomId);
if (memberList.length > 0) {
roomCount++;
await cacheManager.setContactOrRoomRawPayload(contactOrRoomId, contactWithAvatar);
}
else {
await cacheManager.deleteContactOrRoom(contactOrRoomId);
await cacheManager.deleteRoomMemberIdList(contactOrRoomId);
}
}
else {
config_js_1.log.warn(PRE, `Unknown contact type: ${JSON.stringify(contactOrRoom)}`);
}
await this.manager.processHistoryMessages(contactOrRoom);
});
config_js_1.log.info(PRE, `onReady() all contacts and rooms are ready, friendCount: ${friendCount} contactCount: ${contactCount} roomCount: ${roomCount}`);
await (0, miscellaneous_js_1.sleep)(15 * 1000);
this.emit('ready');
this.loadingData = false;
}
async onLogout(reason = config_js_1.STRINGS[config_js_1.LANGUAGE].LOGOUT_REASON.DEFAULT) {
config_js_1.log.verbose(PRE, `onLogout(${reason})`);
await this.clearSession();
this.hasLogin = false;
this.manager.stopSchedule();
this.emit('logout', this.getBotId(), reason);
this.baseStop();
if (!this.getWhatsAppClient().pupPage) {
await this.getWhatsAppClient().initialize();
}
}
async onChangeState(state) {
config_js_1.log.info(PRE, `onChangeState(${JSON.stringify(state)})`);
if (!this.botId) {
throw (0, whatsapp_error_js_1.default)(error_type_js_1.WA_ERROR_TYPE.ERR_INIT, 'No login bot id.');
}
switch (state) {
case whatsapp_interface_js_1.WAState.TIMEOUT:
this.pendingLogoutEmitTimer = setTimeout(() => {
this.emit('logout', this.getBotId(), config_js_1.STRINGS[config_js_1.LANGUAGE].LOGOUT_REASON.NETWORK_TIMEOUT_IN_PHONE);
this.pendingLogoutEmitTimer = undefined;
}, config_js_1.DEFAULT_TIMEOUT.TIMEOUT_WAIT_CONNECTED);
break;
case whatsapp_interface_js_1.WAState.CONNECTED:
this.clearPendingLogoutEmitTimer();
this.emit('login', this.botId);
this.loadingData = false;
const contactOrRoomList = await this.manager.syncContactOrRoomList();
await this.onReady(contactOrRoomList);
break;
default:
break;
}
}
/**
* unsupported events
* leave logs to for further dev
*/
async onChangeBattery(batteryInfo) {
config_js_1.log.verbose(PRE, `onChangeBattery(${JSON.stringify(batteryInfo)})`);
if (!this.botId) {
throw (0, whatsapp_error_js_1.default)(error_type_js_1.WA_ERROR_TYPE.ERR_INIT, 'No login bot id.');
}
if (batteryInfo.battery <= config_js_1.MIN_BATTERY_VALUE_FOR_LOGOUT && !batteryInfo.plugged) {
this.emit('logout', this.botId, config_js_1.STRINGS[config_js_1.LANGUAGE].LOGOUT_REASON.BATTERY_LOWER_IN_PHONE);
}
}
}
exports.default = LoginEventHandler;
//# sourceMappingURL=login-event-handler.js.map