UNPKG

@juzi/wechaty-puppet-whatsapp

Version:
296 lines 11.2 kB
/** * Wechaty - https://github.com/chatie/wechaty * * @copyright 2016-2018 Huan LI <zixia@zixia.net> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import * as PUPPET from '@juzi/wechaty-puppet'; import { log } from '@juzi/wechaty-puppet'; import { VERSION, } from './config.js'; import Manager from './manager.js'; import WAError from './exception/whatsapp-error.js'; import { WA_ERROR_TYPE } from './exception/error-type.js'; import { EventName } from './schema/event-name.js'; import { RequestPool } from './request/request-pool.js'; import { contactSelfQRCode, contactSelfName, contactSelfSignature } from './puppet-mixin/contact-self.js'; import { contactAlias, contactPhone, contactCorporationRemark, contactDescription, contactList, contactAvatar, contactRawPayloadParser, contactRawPayload } from './puppet-mixin/contact.js'; import { conversationReadMark } from './puppet-mixin/conversation.js'; import { friendshipRawPayload, friendshipRawPayloadParser, friendshipSearchPhone, friendshipSearchWeixin, friendshipAdd, friendshipAccept, friendshipSearchHandle } from './puppet-mixin/friendship.js'; import { messageContact, messageImage, messageRecall, messageFile, messageUrl, messageMiniProgram, messageSendText, messageSendFile, messageSendContact, messageSendUrl, messageSendMiniProgram, messageForward, messageRawPayloadParser, messageRawPayload, messagePost, messageSendChannel, messageChannel, messageSendLocation, messageLocation } from './puppet-mixin/message.js'; import { roomRawPayloadParser, roomRawPayload, roomList, roomDel, roomAvatar, roomAdd, roomTopic, roomCreate, roomQuit, roomQRCode, roomMemberList, roomMemberRawPayload, roomMemberRawPayloadParser, roomAnnounce, roomInvitationAccept, roomInvitationRawPayload, roomInvitationRawPayloadParser } from './puppet-mixin/room.js'; import { tagContactTagAdd, tagContactTagList, tagContactTagRemove, tagGroupAdd, tagGroupDelete, tagGroupList, tagGroupTagList, tagTagAdd, tagTagContactList, tagTagDelete, tagTagList } from './puppet-mixin/tag.js'; const PRE = 'PuppetWhatsapp'; class PuppetWhatsapp extends PUPPET.Puppet { options; static VERSION = VERSION; manager; constructor(options = {}) { super(options); this.options = options; log.verbose(PRE, 'constructor()'); this.manager = new Manager(this.options); } version() { return VERSION; } async onStart() { log.verbose(PRE, 'onStart()'); let whatsapp; try { whatsapp = await this.startManager(this.manager); } catch (err) { log.error(PRE, `Can not start whatsapp, error: ${err.message}`); throw WAError(WA_ERROR_TYPE.ERR_INIT, `Can not start whatsapp, error: ${err.message}`); } /** * Huan(202102): Wait for Puppeteer to be inited before resolve start() for robust state management */ const future = new Promise(resolve => { function check() { if (whatsapp.pupBrowser) { resolve(); } else { setTimeout(check, 100); } } check(); }); return Promise.race([ future, this.state.stable('inactive'), ]); } async startManager(manager) { manager.on({ dirty: data => { this.emit('dirty', data); }, error: this.onError.bind(this), friendship: this.onFriendship.bind(this), heartbeat: data => this.emit('heartbeat', { data, }), login: this.onLogin.bind(this), logout: this.onLogout.bind(this), message: this.onMessage.bind(this), ready: this.onReady.bind(this), reset: this.onReset.bind(this), 'room-invite': this.onRoomInvite.bind(this), 'room-join': this.onRoomJoin.bind(this), 'room-leave': this.onRoomLeave.bind(this), 'room-topic': this.onRoomTopic.bind(this), scan: this.onScan.bind(this), }); const memory = this.memory; const whatsapp = await this.manager.start(memory); return whatsapp; } async onStop() { log.verbose(PRE, 'onStop()'); try { await this.stopManager(); } catch (err) { log.error(PRE, `Can not stop, error: ${err.message}`); } } async stopManager() { this.manager.off('*'); await this.manager.stop(); } /** * Event section: onXXX */ async onLogin(wxid) { log.verbose(PRE, 'onLogin(%s)', wxid); if (this.isLoggedIn) { log.warn(PRE, 'onLogin(%s) already login? NOOP', wxid); return; } log.info(PRE, `${EventName.LOGIN}, ${wxid}`); await super.login(wxid); // no need to emit login since super.login will do that // this.emit('login', { contactId: wxid }) } async onLogout(wxid, message) { log.verbose(PRE, 'onLogout(%s, %s)', wxid, message); if (!this.isLoggedIn) { log.warn(PRE, 'onLogout(%s) already logged out?', wxid); } log.info(PRE, `${EventName.LOGOUT}, ${wxid}`); const requestPool = RequestPool.Instance; requestPool.clearPool(); this.emit('logout', { contactId: wxid, data: message }); } async onMessage(message) { log.verbose(PRE, 'onMessage(%s)', JSON.stringify(message)); this.emit('message', message); } async onScan(payload) { log.verbose(PRE, 'onScan(%s)', JSON.stringify(payload)); log.info(PRE, `${EventName.SCAN}`); this.emit('scan', payload); } async onError(e) { log.info(PRE, `${EventName.ERROR}, ${e}`); this.emit('error', { data: e, }); } async onReset(reason) { log.info(PRE, `${EventName.RESET}, ${reason}`); this.emit('reset', { data: reason }); } async onFriendship(payload) { const friendshipPayload = await this.friendshipRawPayload(payload.friendshipId); if (friendshipPayload.type === PUPPET.types.Friendship.Receive) { // 收到好友请求暂不冒泡,直接接受 await this.friendshipAccept(payload.friendshipId); return; } this.emit('friendship', payload); } async onRoomJoin(payload) { const roomId = payload.roomId; await this.dirtyPayload(PUPPET.types.Payload.Room, roomId); this.emit('room-join', payload); } async onRoomLeave(payload) { const roomId = payload.roomId; await this.dirtyPayload(PUPPET.types.Payload.Room, roomId); this.emit('room-leave', payload); } async onRoomTopic(payload) { const roomId = payload.roomId; await this.dirtyPayload(PUPPET.types.Payload.Room, roomId); this.emit('room-topic', payload); } async onRoomInvite(payload) { this.emit('room-invite', payload); } async onReady() { log.verbose(PRE, 'onReady()'); log.info(PRE, `${EventName.READY}`); this.emit('ready', { data: 'ready' }); } /** * Override Methods */ async logout() { await super.logout(); if (!this.isLoggedIn) { log.verbose(PRE, 'logout() do nothing'); return; } return this.manager.logout(); } ding(data) { log.silly(PRE, 'ding(%s)', data || ''); setTimeout(() => this.emit('dong', { data: data || '' }), 1000); } /** * ContactSelf */ contactSelfQRCode = contactSelfQRCode; contactSelfName = contactSelfName; contactSelfSignature = contactSelfSignature; /** * Contact */ contactAlias = contactAlias; contactPhone = contactPhone; contactCorporationRemark = contactCorporationRemark; contactDescription = contactDescription; contactList = contactList; contactAvatar = contactAvatar; contactRawPayloadParser = contactRawPayloadParser; contactRawPayload = contactRawPayload; /** * Conversation */ conversationReadMark = conversationReadMark; /** * Message */ // FIXME: need to implement in wechaty-puppet messagePost = messagePost; messageContact = messageContact; messageImage = messageImage; messageRecall = messageRecall; messageFile = messageFile; messageUrl = messageUrl; messageMiniProgram = messageMiniProgram; messageChannel = messageChannel; messageSendText = messageSendText; messageSendFile = messageSendFile; messageSendContact = messageSendContact; messageSendUrl = messageSendUrl; messageSendMiniProgram = messageSendMiniProgram; messageSendChannel = messageSendChannel; messageSendLocation = messageSendLocation; messageLocation = messageLocation; messageForward = messageForward; messageRawPayloadParser = messageRawPayloadParser; messageRawPayload = messageRawPayload; /** * Room */ roomRawPayloadParser = roomRawPayloadParser; roomRawPayload = roomRawPayload; roomList = roomList; roomDel = roomDel; roomAvatar = roomAvatar; roomAdd = roomAdd; roomTopic = roomTopic; roomCreate = roomCreate; roomQuit = roomQuit; roomQRCode = roomQRCode; roomMemberList = roomMemberList; roomMemberRawPayload = roomMemberRawPayload; roomMemberRawPayloadParser = roomMemberRawPayloadParser; roomAnnounce = roomAnnounce; roomInvitationAccept = roomInvitationAccept; roomInvitationRawPayload = roomInvitationRawPayload; roomInvitationRawPayloadParser = roomInvitationRawPayloadParser; /** * Friendship */ friendshipRawPayload = friendshipRawPayload; friendshipRawPayloadParser = friendshipRawPayloadParser; friendshipSearchPhone = friendshipSearchPhone; friendshipSearchWeixin = friendshipSearchWeixin; friendshipSearchHandle = friendshipSearchHandle; friendshipAdd = friendshipAdd; friendshipAccept = friendshipAccept; /** * Tag */ tagContactTagAdd = tagContactTagAdd; tagContactTagRemove = tagContactTagRemove; tagContactTagList = tagContactTagList; tagGroupAdd = tagGroupAdd; tagGroupDelete = tagGroupDelete; tagGroupList = tagGroupList; tagGroupTagList = tagGroupTagList; tagTagAdd = tagTagAdd; tagTagDelete = tagTagDelete; tagTagList = tagTagList; tagTagContactList = tagTagContactList; } export { PuppetWhatsapp }; export default PuppetWhatsapp; //# sourceMappingURL=puppet-whatsapp.js.map