wechaty-puppet-padplus
Version:
Puppet Padplus for Wechaty
993 lines (992 loc) • 53.3 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const util_1 = __importDefault(require("util"));
const rx_queue_1 = require("rx-queue");
const state_switch_1 = require("state-switch");
const config_1 = require("../config");
const file_box_1 = __importDefault(require("file-box"));
const lru_cache_1 = __importDefault(require("lru-cache"));
const file_box_to_qrcode_1 = __importDefault(require("../utils/file-box-to-qrcode"));
const grpc_gateway_1 = require("../server-manager/grpc-gateway");
const PadPlusServer_pb_1 = require("../server-manager/proto-ts/PadPlusServer_pb");
const wechaty_puppet_1 = require("wechaty-puppet");
const request_1 = require("./api-request/request");
const user_1 = require("./api-request/user");
const contact_1 = require("./api-request/contact");
const message_1 = require("./api-request/message");
const schemas_1 = require("../schemas");
const message_convertor_1 = require("../convert-manager/message-convertor");
const cache_manager_1 = require("../server-manager/cache-manager");
const contact_convertor_1 = require("../convert-manager/contact-convertor");
const room_1 = require("./api-request/room");
const room_convertor_1 = require("../convert-manager/room-convertor");
const callbackHelper_1 = require("../utils/callbackHelper");
const friendship_1 = require("./api-request/friendship");
const room_member_parser_1 = require("../pure-function-helpers/room-member-parser");
const pure_function_helpers_1 = require("../pure-function-helpers");
const events_1 = require("events");
const MEMORY_SLOT_NAME = 'WECHATY_PUPPET_PADPLUS';
const PRE = 'PadplusManager';
class PadplusManager extends events_1.EventEmitter {
constructor(options) {
super();
this.options = options;
config_1.log.verbose(PRE, 'constructor()');
const lruOptions = {
dispose(key, val) {
config_1.log.silly(PRE, `constructor() lruOptions.dispose(${key}, ${JSON.stringify(val)})`);
},
max: config_1.MESSAGE_CACHE_MAX,
maxAge: config_1.MESSAGE_CACHE_AGE,
};
this.loginStatus = false;
this.cachePadplusMessagePayload = new lru_cache_1.default(lruOptions);
this.state = new state_switch_1.StateSwitch('PadplusManager');
this.state.off();
this.memorySlot = {
qrcodeId: '',
uin: '',
userName: '',
};
this.getContactQueue = new rx_queue_1.DelayQueueExecutor(200);
this.getRoomMemberQueue = new rx_queue_1.DelayQueueExecutor(500);
this.resetThrottleQueue = new rx_queue_1.ThrottleQueue(5000);
this.resetThrottleQueue.subscribe((reason) => __awaiter(this, void 0, void 0, function* () {
config_1.log.silly('Puppet', 'constructor() resetThrottleQueue.subscribe() reason: %s', reason);
if (this.grpcGatewayEmitter) {
this.grpcGatewayEmitter.removeAllListeners();
}
delete this.padplusUser;
delete this.padplusContact;
delete this.padplusFriendship;
delete this.padplusRoom;
delete this.padplusMesasge;
delete this.requestClient;
yield this.start();
}));
config_1.log.silly(PRE, ` : ${util_1.default.inspect(this.state)}`);
}
emit(event, ...args) {
return super.emit(event, ...args);
}
on(event, listener) {
config_1.log.verbose(PRE, `on(${event}, ${typeof listener}) registered`);
super.on(event, (...args) => {
try {
listener.apply(this, args);
}
catch (e) {
config_1.log.error(PRE, 'onFunction(%s) listener exception: %s', event, e);
}
});
return this;
}
start() {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `start()`);
this.state.on('pending');
let emitter;
try {
emitter = yield grpc_gateway_1.GrpcGateway.init(this.options.token, this.options.endpoint || config_1.GRPC_ENDPOINT, String(this.options.name));
}
catch (e) {
config_1.log.info(`start grpc gateway failed for reason: ${e}, retry start in 5 seconds.`);
yield new Promise(resolve => setTimeout(resolve, 5000));
yield this.start();
return;
}
if (!grpc_gateway_1.GrpcGateway.Instance) {
throw new Error(`The grpc gateway has no instance.`);
}
this.requestClient = new request_1.RequestClient(grpc_gateway_1.GrpcGateway.Instance, emitter);
this.padplusUser = new user_1.PadplusUser(this.requestClient);
this.padplusMesasge = new message_1.PadplusMessage(this.requestClient);
this.padplusContact = new contact_1.PadplusContact(this.requestClient);
this.padplusRoom = new room_1.PadplusRoom(this.requestClient);
this.padplusFriendship = new friendship_1.PadplusFriendship(this.requestClient);
yield this.initGrpcGatewayListener(emitter);
this.grpcGatewayEmitter = emitter;
if (this.memory) {
const slot = yield this.memory.get(MEMORY_SLOT_NAME);
if (slot && slot.uin) {
config_1.log.silly(PRE, `uin : ${slot.uin}`);
emitter.setUIN(slot.uin);
yield new Promise((resolve) => setTimeout(resolve, 500));
yield this.padplusUser.initInstance();
}
else {
yield this.padplusUser.getWeChatQRCode();
}
this.memorySlot = Object.assign(Object.assign({}, this.memorySlot), yield this.memory.get(MEMORY_SLOT_NAME));
}
});
}
stop() {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.verbose(PRE, `stop()`);
this.state.off('pending');
if (this.grpcGatewayEmitter) {
this.grpcGatewayEmitter.removeAllListeners();
}
yield grpc_gateway_1.GrpcGateway.release();
yield cache_manager_1.CacheManager.release();
this.cacheManager = undefined;
this.loginStatus = false;
this.state.off(true);
config_1.log.verbose(PRE, `stop() finished`);
});
}
logout(selfId) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.verbose(PRE, `logout()`);
this.state.off('pending');
if (this.padplusUser) {
const logoutResult = yield this.padplusUser.logout(selfId);
if (!logoutResult) {
config_1.log.error(`Logout WeChat failed!`);
}
else {
config_1.log.silly(PRE, `Logout WeChat success!`);
}
}
else {
throw new Error(`no padplus user.`);
}
if (this.grpcGatewayEmitter) {
this.grpcGatewayEmitter.removeAllListeners();
}
if (grpc_gateway_1.GrpcGateway.Instance) {
yield grpc_gateway_1.GrpcGateway.Instance.stop();
}
yield cache_manager_1.CacheManager.release();
this.cacheManager = undefined;
this.loginStatus = false;
this.state.off(true);
config_1.log.verbose(PRE, `logout() finished`);
});
}
setMemory(memory) {
this.memory = memory;
}
setContactAndRoomData() {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `setContactAndRoomData()`);
if (!this.cacheManager) {
config_1.log.verbose(PRE, `setContactAndRoomData() can not proceed due to no cache.`);
return;
}
const contactTotal = yield this.cacheManager.getContactCount();
const roomTotal = yield this.cacheManager.getRoomCount();
const friendTotal = (yield this.cacheManager.getAllContacts()).filter(contact => {
return contact.contactFlag !== 0;
}).length;
const now = new Date().getTime();
if (this.contactAndRoomData) {
if (this.contactAndRoomData.contactTotal === contactTotal
&& this.contactAndRoomData.roomTotal === roomTotal
&& this.contactAndRoomData.friendTotal === friendTotal) {
if (now - this.contactAndRoomData.updatedTime > config_1.WAIT_FOR_READY_TIME
&& !this.contactAndRoomData.readyEmitted) {
config_1.log.verbose(PRE, `setContactAndRoomData() more than ${config_1.WAIT_FOR_READY_TIME / 1000 / 60} minutes no change on data, emit ready event.`);
this.contactAndRoomData.readyEmitted = true;
this.emit('ready');
}
config_1.log.silly(PRE, `setContactAndRoomData() found contact, room, friend data no change.`);
}
else {
config_1.log.silly(PRE, `setContactAndRoomData() found contact or room or friend change. Record changes...`);
this.contactAndRoomData.contactTotal = contactTotal;
this.contactAndRoomData.roomTotal = roomTotal;
this.contactAndRoomData.friendTotal = friendTotal;
this.contactAndRoomData.updatedTime = now;
}
}
else {
config_1.log.silly(PRE, `setContactAndRoomData() initialize contact and room data.`);
this.contactAndRoomData = {
contactTotal,
friendTotal,
readyEmitted: false,
roomTotal,
updatedTime: now,
};
}
});
}
initGrpcGatewayListener(grpcGatewayEmitter) {
return __awaiter(this, void 0, void 0, function* () {
grpcGatewayEmitter.on('reconnect', () => __awaiter(this, void 0, void 0, function* () {
this.resetThrottleQueue.next('reconnect');
}));
grpcGatewayEmitter.on('grpc-end', () => __awaiter(this, void 0, void 0, function* () {
this.emit('reset', 'grpc server end.');
}));
grpcGatewayEmitter.on('heartbeat', (data) => __awaiter(this, void 0, void 0, function* () {
this.emit('heartbeat', data);
// TODO: 数据同步后,需要停止该函数的执行
if (!this.contactAndRoomData || !this.contactAndRoomData.readyEmitted) {
yield this.setContactAndRoomData();
}
}));
grpcGatewayEmitter.on('EXPIRED_TOKEN', () => __awaiter(this, void 0, void 0, function* () {
config_1.log.info(config_1.EXPIRED_TOKEN_MESSAGE);
setTimeout(() => process.exit(), 5000);
}));
grpcGatewayEmitter.on('INVALID_TOKEN', () => __awaiter(this, void 0, void 0, function* () {
config_1.log.info(config_1.INVALID_TOKEN_MESSAGE);
setTimeout(() => process.exit(), 5000);
}));
grpcGatewayEmitter.on('data', (data) => __awaiter(this, void 0, void 0, function* () {
const type = data.getResponsetype();
switch (type) {
case PadPlusServer_pb_1.ResponseType.LOGIN_QRCODE:
const qrcodeRawData = data.getData();
if (qrcodeRawData) {
const qrcodeData = JSON.parse(qrcodeRawData);
grpcGatewayEmitter.setQrcodeId(qrcodeData.qrcodeId);
const fileBox = file_box_1.default.fromBase64(qrcodeData.qrcode, `qrcode${(Math.random() * 10000).toFixed()}.png`);
const qrcodeUrl = yield file_box_to_qrcode_1.default(fileBox);
this.emit('scan', qrcodeUrl, wechaty_puppet_1.ScanStatus.Cancel);
this.qrcodeStatus = wechaty_puppet_1.ScanStatus.Cancel;
}
break;
case PadPlusServer_pb_1.ResponseType.QRCODE_SCAN:
const scanRawData = data.getData();
if (scanRawData) {
config_1.log.silly(PRE, `QRCODE_SCAN : ${util_1.default.inspect(scanRawData)}`);
const scanData = JSON.parse(scanRawData);
config_1.log.info(PRE, `
=================================================
QRCODE_SCAN MSG : ${scanData.msg || '已确认'}
=================================================
`);
grpcGatewayEmitter.setQrcodeId(scanData.user_name);
switch (scanData.status) {
case schemas_1.QrcodeStatus.Scanned:
if (this.qrcodeStatus !== wechaty_puppet_1.ScanStatus.Waiting) {
this.qrcodeStatus = wechaty_puppet_1.ScanStatus.Waiting;
this.emit('scan', '', this.qrcodeStatus);
}
break;
case schemas_1.QrcodeStatus.Confirmed:
if (this.qrcodeStatus !== wechaty_puppet_1.ScanStatus.Scanned) {
this.qrcodeStatus = wechaty_puppet_1.ScanStatus.Scanned;
this.emit('scan', '', this.qrcodeStatus);
}
break;
case schemas_1.QrcodeStatus.Canceled:
case schemas_1.QrcodeStatus.Expired:
const uin = yield grpcGatewayEmitter.getUIN();
const wxid = yield grpcGatewayEmitter.getUserName();
const data = {
uin,
wxid,
};
this.emit('scan', '', scanData.status);
if (this.padplusUser) {
yield this.padplusUser.getWeChatQRCode(data);
}
break;
default:
break;
}
}
break;
case PadPlusServer_pb_1.ResponseType.QRCODE_LOGIN:
const grpcLoginData = data.getData();
if (grpcLoginData) {
config_1.log.silly(PRE, `QRCODE_LOGIN : ${util_1.default.inspect(grpcLoginData)}`);
const loginData = JSON.parse(grpcLoginData);
this.loginStatus = true;
grpcGatewayEmitter.setQrcodeId('');
grpcGatewayEmitter.setUserName(loginData.userName);
grpcGatewayEmitter.setUIN(loginData.uin);
if (this.memory) {
this.memorySlot = {
qrcodeId: '',
uin: loginData.uin,
userName: loginData.userName,
};
config_1.log.silly(PRE, `name: ${this.options.name}, memory slot : ${util_1.default.inspect(this.memorySlot)}`);
yield this.memory.set(MEMORY_SLOT_NAME, this.memorySlot);
yield this.memory.save();
}
config_1.log.verbose(PRE, `init cache manager`);
yield cache_manager_1.CacheManager.init(loginData.userName);
this.cacheManager = cache_manager_1.CacheManager.Instance;
const contactSelf = {
alias: loginData.alias,
bigHeadUrl: loginData.headImgUrl,
city: '',
contactFlag: 3,
contactType: 0,
country: '',
labelLists: '',
nickName: loginData.nickName,
province: '',
remark: '',
sex: wechaty_puppet_1.ContactGender.Unknown,
signature: '',
smallHeadUrl: '',
stranger: '',
ticket: '',
userName: loginData.userName,
verifyFlag: 0,
};
yield this.cacheManager.setContact(contactSelf.userName, contactSelf);
this.emit('login', loginData);
const selfOnline = yield this.getContact(loginData.userName);
if (selfOnline) {
yield this.cacheManager.setContact(selfOnline.userName, selfOnline);
}
}
break;
case PadPlusServer_pb_1.ResponseType.AUTO_LOGIN:
const grpcAutoLoginData = data.getData();
if (grpcAutoLoginData) {
const autoLoginData = JSON.parse(grpcAutoLoginData);
config_1.log.silly(PRE, `user name : ${util_1.default.inspect(autoLoginData)}`);
if (autoLoginData && autoLoginData.online) {
if (!this.loginStatus) {
const wechatUser = autoLoginData.wechatUser;
config_1.log.verbose(PRE, `init cache manager`);
yield cache_manager_1.CacheManager.init(wechatUser.userName);
this.cacheManager = cache_manager_1.CacheManager.Instance;
/* if (this.padplusUser) {
await this.padplusUser.reconnect()
} else {
throw new Error(`no padplus user.`)
} */
const contactSelfInfo = yield this.contactSelfInfo();
const contactSelfPayload = contact_convertor_1.convertFromGrpcContactSelf(contactSelfInfo);
yield this.cacheManager.setContact(contactSelfPayload.userName, contactSelfPayload);
this.emit('login', wechatUser);
this.loginStatus = true;
}
}
else {
const uin = yield grpcGatewayEmitter.getUIN();
const wxid = yield grpcGatewayEmitter.getUserName();
const data = {
uin,
wxid,
};
yield grpcGatewayEmitter.setUIN('');
yield grpcGatewayEmitter.setUserName('');
if (this.padplusUser) {
yield this.padplusUser.getWeChatQRCode(data);
}
}
}
break;
case PadPlusServer_pb_1.ResponseType.ACCOUNT_LOGOUT:
const logoutRawData = data.getData();
if (logoutRawData) {
const logoutData = JSON.parse(logoutRawData);
const uin = data.getUin();
const _uin = grpcGatewayEmitter.getUIN();
if (uin === _uin) {
this.loginStatus = false;
if (logoutData.mqType === 1100) {
this.emit('error', new schemas_1.PadplusError(schemas_1.PadplusErrorType.EXIT, logoutData.message));
yield new Promise((resolve) => setTimeout(resolve, 20 * 1000));
this.emit('logout');
}
}
else {
const userName = grpcGatewayEmitter.getUserName();
throw new Error(`can not get userName for this uin : ${uin}, userName: ${userName}`);
}
}
else {
config_1.log.info(`can not get data from Event LOGOUT, ready to restart...`);
if (!this.padplusUser) {
throw new Error(`no padplusUser`);
}
yield this.padplusUser.reconnect();
yield new Promise((resolve) => setTimeout(resolve, 30 * 1000));
this.emit('reset', 'logout with some unknow reasons');
}
break;
case PadPlusServer_pb_1.ResponseType.CONTACT_LIST:
case PadPlusServer_pb_1.ResponseType.CONTACT_MODIFY:
const roomRawData = data.getData();
if (roomRawData) {
const _data = JSON.parse(roomRawData);
if (!pure_function_helpers_1.isRoomId(_data.UserName)) {
const contactData = _data;
if (contactData.Type7) {
config_1.log.warn(`This id: ${contactData.UserName} is not wxid, using weixin instead of wxid will potentially cause system failure. To make sure everything works as excepted, please use the wxid to load Contact.`);
}
const contact = contact_convertor_1.convertFromGrpcContact(contactData, true);
if (this.cacheManager) {
yield this.cacheManager.setContact(contact.userName, contact);
}
callbackHelper_1.CallbackPool.Instance.resolveContactCallBack(contact.userName, contact);
}
else {
const roomData = _data;
const roomPayload = room_convertor_1.convertRoomFromGrpc(roomData);
if (this.cacheManager) {
const roomMembers = room_member_parser_1.briefRoomMemberParser(roomPayload.members);
const _roomMembers = yield this.cacheManager.getRoomMember(roomPayload.chatroomId);
if (!_roomMembers) {
yield this.cacheManager.setRoomMember(roomPayload.chatroomId, roomMembers);
}
yield this.cacheManager.setRoom(roomPayload.chatroomId, roomPayload);
}
else {
throw new schemas_1.PadplusError(schemas_1.PadplusErrorType.NO_CACHE, `CONTACT_MODIFY`);
}
callbackHelper_1.CallbackPool.Instance.resolveRoomCallBack(roomPayload.chatroomId, roomPayload);
}
}
break;
case PadPlusServer_pb_1.ResponseType.CONTACT_DELETE:
const contactDataStr = data.getData();
if (contactDataStr) {
const contactData = JSON.parse(contactDataStr);
config_1.log.silly(PRE, `delete contact data : ${util_1.default.inspect(contactData)}`);
const deleteUserName = contactData.field;
if (this.cacheManager) {
if (pure_function_helpers_1.isRoomId(deleteUserName)) {
const room = yield this.cacheManager.getRoom(deleteUserName);
if (!room) {
const roomPayload = {
alias: '',
bigHeadUrl: '',
chatRoomOwner: '',
chatroomId: deleteUserName,
chatroomVersion: 0,
contactType: 0,
isDelete: true,
labelLists: '',
memberCount: 0,
members: [],
nickName: '',
smallHeadUrl: '',
stranger: '',
ticket: '',
};
yield this.cacheManager.setRoom(deleteUserName, roomPayload);
}
else {
room.isDelete = true;
yield this.cacheManager.setRoom(deleteUserName, room);
}
yield this.cacheManager.setRoomMember(deleteUserName, {});
}
else if (pure_function_helpers_1.isContactId(deleteUserName)) {
yield this.cacheManager.deleteContact(deleteUserName);
}
else {
throw new Error(`the filed is not right.`);
}
}
}
break;
case PadPlusServer_pb_1.ResponseType.MESSAGE_RECEIVE:
const rawMessageStr = data.getData();
if (rawMessageStr) {
const rawMessage = JSON.parse(rawMessageStr);
const message = yield this.onProcessMessage(rawMessage);
this.emit('message', message);
}
break;
case PadPlusServer_pb_1.ResponseType.CONTACT_ADD:
const addContactCallback = callbackHelper_1.CallbackPool.Instance.getCallback(data.getRequestid());
addContactCallback && addContactCallback(data);
callbackHelper_1.CallbackPool.Instance.removeCallback(data.getRequestid());
break;
case PadPlusServer_pb_1.ResponseType.CONTACT_SEARCH:
const searchContactTraceId = data.getTraceid();
if (searchContactTraceId) {
const searchContactCallback = callbackHelper_1.CallbackPool.Instance.getCallback(searchContactTraceId);
searchContactCallback && searchContactCallback(data);
callbackHelper_1.CallbackPool.Instance.removeCallback(searchContactTraceId);
}
break;
case PadPlusServer_pb_1.ResponseType.ROOM_QRCODE:
const roomQrcodeTraceId = data.getTraceid();
if (roomQrcodeTraceId) {
const callback = callbackHelper_1.CallbackPool.Instance.getCallback(roomQrcodeTraceId);
callback && callback(data);
callbackHelper_1.CallbackPool.Instance.removeCallback(roomQrcodeTraceId);
}
break;
case PadPlusServer_pb_1.ResponseType.ROOM_MEMBER_LIST:
const roomMembersStr = data.getData();
if (roomMembersStr) {
if (this.cacheManager) {
const roomMemberList = JSON.parse(roomMembersStr);
const roomId = roomMemberList.roomId;
const membersStr = roomMemberList.membersJson;
const membersList = JSON.parse(membersStr);
const members = room_member_parser_1.roomMemberParser(membersList);
yield this.cacheManager.setRoomMember(roomId, members);
yield Promise.all(membersList.map((member) => __awaiter(this, void 0, void 0, function* () {
if (!this.cacheManager) {
throw new schemas_1.PadplusError(schemas_1.PadplusErrorType.NO_CACHE, 'roomMemberList');
}
const contact = yield this.cacheManager.getContact(member.UserName);
if (!contact) {
const newContact = {
alias: '',
bigHeadUrl: member.HeadImgUrl,
city: '',
contactFlag: 0,
contactType: 0,
country: '',
labelLists: '',
nickName: member.NickName,
province: '',
remark: '',
sex: wechaty_puppet_1.ContactGender.Unknown,
signature: '',
smallHeadUrl: member.HeadImgUrl,
stranger: '',
ticket: '',
userName: member.UserName,
verifyFlag: 0,
};
yield this.cacheManager.setContact(newContact.userName, newContact);
}
else {
const newContact = Object.assign({}, contact, {
bigHeadUrl: member.HeadImgUrl,
nickName: member.NickName,
smallHeadUrl: member.HeadImgUrl,
userName: member.UserName,
});
yield this.cacheManager.setContact(newContact.userName, newContact);
}
callbackHelper_1.CallbackPool.Instance.resolveRoomMemberCallback(roomId, members);
})));
}
else {
throw new schemas_1.PadplusError(schemas_1.PadplusErrorType.NO_CACHE, `CONTACT_MODIFY`);
}
}
else {
throw new Error(`can not get receive room member data from server`);
}
break;
case PadPlusServer_pb_1.ResponseType.ROOM_MEMBER_MODIFY:
// TODO: not support now
break;
case PadPlusServer_pb_1.ResponseType.STATUS_NOTIFY:
// TODO: not support now
break;
case PadPlusServer_pb_1.ResponseType.MESSAGE_MEDIA_SRC:
const traceId = data.getTraceid();
if (traceId) {
const callback = callbackHelper_1.CallbackPool.Instance.getCallback(traceId);
callback && callback(data);
callbackHelper_1.CallbackPool.Instance.removeCallback(traceId);
}
else {
config_1.log.silly(PRE, `can not get trace id`);
}
break;
case PadPlusServer_pb_1.ResponseType.REQUEST_RESPONSE:
const requestId = data.getRequestid();
const responseData = data.getData();
if (responseData) {
const callback = callbackHelper_1.CallbackPool.Instance.getCallback(requestId);
callback && callback(data);
}
break;
}
}));
});
}
/**
* Contact Self Section
*/
contactSelfQrcode() {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `contactSelfQrcode()`);
if (this.padplusContact) {
return this.padplusContact.contactSelfQrcode();
}
else {
throw new Error(`no padplus contact`);
}
});
}
contactSelfName(name) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `contactSelfName(${name})`);
if (this.padplusContact) {
const data = {
nickName: name,
};
yield this.padplusContact.setContactSelfInfo(data);
}
else {
throw new Error(`no padplus contact`);
}
});
}
contactSelfSignature(signature) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `contactSelfSignature(${signature})`);
if (this.padplusContact) {
const data = {
signature,
};
yield this.padplusContact.setContactSelfInfo(data);
}
else {
throw new Error(`no padplus contact`);
}
});
}
contactSelfInfo() {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `contactSelfInfo()`);
if (this.padplusContact) {
return this.padplusContact.getContactSelfInfo();
}
else {
throw new Error(`no padplus contact`);
}
});
}
/**
* Message Section
*/
loadRichMediaData(mediaData) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `loadRichMediaData()`);
if (!this.padplusMesasge) {
throw new Error(`no padplus message`);
}
const data = yield this.padplusMesasge.loadRichMeidaData(mediaData);
const mediaStr = data.getData();
if (mediaStr) {
const mediaData = JSON.parse(mediaStr);
return mediaData;
}
else {
throw new Error(`can not load media data on manager`);
}
});
}
sendMessage(selfId, receiver, text, type, mention) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `selfId : ${selfId}, receiver : ${receiver}, text : ${text}, type : ${type}`);
if (!this.padplusMesasge) {
throw new Error(`no padplus message`);
}
return this.padplusMesasge.sendMessage(selfId, receiver, text, type, mention);
});
}
sendContact(selfId, receiver, contentStr) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `selfId : ${selfId},receiver : ${receiver}`);
if (!this.cacheManager) {
throw new schemas_1.PadplusError(schemas_1.PadplusErrorType.NO_CACHE, `sendContact()`);
}
if (!this.padplusMesasge) {
throw new Error(`no padplus message`);
}
return this.padplusMesasge.sendContact(selfId, receiver, contentStr);
});
}
addFriend(contactId, hello, isPhoneNumber, strangerV1, strangerV2) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.verbose(PRE, `addFriend(), isPhoneNumber: ${isPhoneNumber}`);
if (!this.padplusFriendship) {
throw new Error(`no padplusFriendship`);
}
return this.padplusFriendship.addFriend(strangerV1, strangerV2, isPhoneNumber, contactId, hello);
});
}
generatorFileUrl(file) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.verbose(PRE, 'generatorFileUrl(%s)', file);
if (this.requestClient) {
const url = yield this.requestClient.uploadFile(file.name, yield file.toStream());
return url;
}
else {
throw new Error(`no requestClient`);
}
});
}
sendFile(selfId, receiverId, url, fileName, subType, fileSize) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.verbose(PRE, 'sendFile()');
if (!this.padplusMesasge) {
throw new Error(`no padplus message`);
}
return this.padplusMesasge.sendFile(selfId, receiverId, url, fileName, subType, fileSize);
});
}
sendUrlLink(selfId, receiver, content) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.padplusMesasge) {
throw new Error(`no padplus message`);
}
return this.padplusMesasge.sendUrlLink(selfId, receiver, content);
});
}
onProcessMessage(rawMessage) {
return __awaiter(this, void 0, void 0, function* () {
const payload = yield message_convertor_1.convertMessageFromGrpcToPadplus(rawMessage);
this.cachePadplusMessagePayload.set(payload.msgId, payload);
return payload;
});
}
/**
* Contact Section
*/
setContactAlias(contactId, alias) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `setContactAlias(), contactId : ${contactId}, alias: ${alias}`);
if (!this.padplusContact) {
throw new Error(`no padplusContact`);
}
yield this.padplusContact.setAlias(contactId, alias);
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
reject(new Error('set alias failed since timeout'));
}, 5000);
callbackHelper_1.CallbackPool.Instance.pushContactAliasCallback(contactId, alias, () => {
clearTimeout(timeout);
resolve();
});
});
});
}
getContactIdList(selfId) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `selfId : ${util_1.default.inspect(selfId)}`);
if (!this.cacheManager) {
throw new schemas_1.PadplusError(schemas_1.PadplusErrorType.NO_CACHE, 'contactList()');
}
return this.cacheManager.getContactIds();
});
}
getContact(contactId) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.cacheManager) {
throw new Error();
}
const contact = yield this.cacheManager.getContact(contactId);
if (contact) {
return contact;
}
yield this.getContactQueue.execute(() => __awaiter(this, void 0, void 0, function* () {
if (!this.padplusContact) {
throw new Error(`no padplusContact`);
}
yield this.padplusContact.getContactInfo(contactId);
}));
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => reject(new Error('get contact timeout')), 5000);
callbackHelper_1.CallbackPool.Instance.pushContactCallback(contactId, (data) => {
clearTimeout(timeout);
resolve(data);
});
});
});
}
getContactPayload(contactId) {
return __awaiter(this, void 0, void 0, function* () {
const payload = yield this.getContact(contactId);
if (!payload) {
throw new Error('Can not find payload for contactId ' + contactId);
}
return payload;
});
}
searchContact(contactId) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.padplusContact) {
throw new Error(`no padplusContact`);
}
const payload = yield this.padplusContact.searchContact(contactId);
if (!payload) {
throw new Error('Can not find payload for contactId ' + contactId);
}
return payload;
});
}
syncContacts() {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `sync all contacts`);
if (!this.padplusContact) {
throw new Error(`no padplusContact`);
}
yield this.padplusContact.syncContacts();
});
}
/**
* Room Section
*/
setRoomTopic(roomId, topic) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.padplusRoom) {
throw new Error(`no padplus Room.`);
}
yield this.padplusRoom.setTopic(roomId, topic);
if (this.cacheManager) {
yield this.cacheManager.deleteRoom(roomId);
}
else {
throw new Error(`no cache manager.`);
}
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
reject(new Error('set alias failed since timeout'));
}, 5000);
callbackHelper_1.CallbackPool.Instance.pushRoomTopicCallback(roomId, topic, () => {
clearTimeout(timeout);
resolve();
});
});
});
}
getRoomQrcode(roomId) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.padplusRoom) {
throw new Error(`no padplusRoom`);
}
const qrcodeBuf = this.padplusRoom.getRoomQrcode(roomId);
return qrcodeBuf;
});
}
getRoomIdList() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.cacheManager) {
throw new Error(`no cache.`);
}
return this.cacheManager.getRoomIds();
});
}
getRoomMemberIdList(roomId) {
return __awaiter(this, void 0, void 0, function* () {
const memberMap = yield this.getRoomMembers(roomId);
if (memberMap) {
return Object.keys(memberMap);
}
else {
return [];
}
});
}
getRoomInfo(roomId) {
return __awaiter(this, void 0, void 0, function* () {
const room = yield this.getRoom(roomId);
if (room) {
if (!this.cacheManager) {
throw new schemas_1.PadplusError(schemas_1.PadplusErrorType.NO_CACHE, `get room info`);
}
yield this.cacheManager.setRoom(room.chatroomId, room);
return room;
}
else {
throw new Error(`can not get room info by api`);
}
});
}
getRoom(roomId) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.cacheManager) {
throw new Error();
}
const room = yield this.cacheManager.getRoom(roomId);
if (room) {
return room;
}
yield this.getContactQueue.execute(() => __awaiter(this, void 0, void 0, function* () {
if (!this.padplusContact) {
throw new Error(`no padplusContact`);
}
yield this.padplusContact.getContactInfo(roomId);
}));
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => reject(new Error('get room timeout')), 5000);
callbackHelper_1.CallbackPool.Instance.pushContactCallback(roomId, (data) => {
clearTimeout(timeout);
resolve(data);
});
});
});
}
getRoomMembers(roomId) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.cacheManager) {
throw new Error(`no cache.`);
}
const memberMap = yield this.cacheManager.getRoomMember(roomId);
if (!memberMap) {
if (!this.grpcGatewayEmitter) {
throw new Error(`no grpcGatewayEmitter.`);
}
const uin = this.grpcGatewayEmitter.getUIN();
yield this.getRoomMemberQueue.execute(() => __awaiter(this, void 0, void 0, function* () {
if (!this.padplusRoom) {
throw new Error(`no padplus Room.`);
}
yield this.padplusRoom.getRoomMembers(uin, roomId);
}));
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
reject(new Error('get room member failed since timeout'));
}, 5000);
callbackHelper_1.CallbackPool.Instance.pushRoomMemberCallback(roomId, (data) => {
clearTimeout(timeout);
resolve(data);
});
});
}
else {
return memberMap;
}
});
}
deleteRoomMember(roomId, contactId) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `deleteRoomMember(%s, %s)`, roomId, contactId);
if (!this.padplusRoom) {
throw new Error(`no padplus Room.`);
}
yield this.padplusRoom.deleteRoomMember(roomId, contactId);
});
}
setAnnouncement(roomId, announcement) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.padplusRoom) {
throw new Error(`no padplus Room.`);
}
return this.padplusRoom.setAnnouncement(roomId, announcement);
});
}
getAnnouncement(roomId) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.padplusRoom) {
throw new Error(`no padplus Room.`);
}
return this.padplusRoom.getAnnouncement(roomId);
});
}
roomAddMember(roomId, memberId) {
return __awaiter(this, void 0, void 0, function* () {
config_1.log.silly(PRE, `roomAddMember: ${roomId}, ${memberId}`);
if (!this.padplusRoom) {
throw new Error(`no padplus Room.`);