protected async initCache( token : string, userId : string, ): Promise<void> { log.verbose('PuppetPadchatManager', 'initCache(%s, %s)', token, userId) if ( this.cacheContactRawPayload || this.cacheRoomMemberRawPayload || this.cacheRoomRawPayload ) { throw new Error('cache exists') } const baseDir = path.join( os.homedir(), path.sep, '.wechaty', 'puppet-padchat-cache', path.sep, token, path.sep, userId, ) const baseDirExist = await fs.pathExists(baseDir) if (!baseDirExist) { await fs.mkdirp(baseDir) } this.cacheContactRawPayload = new FlashStoreSync(path.join(baseDir, 'contact-raw-payload')) this.cacheRoomMemberRawPayload = new FlashStoreSync(path.join(baseDir, 'room-member-raw-payload')) this.cacheRoomRawPayload = new FlashStoreSync(path.join(baseDir, 'room-raw-payload')) await Promise.all([ this.cacheContactRawPayload.ready(), this.cacheRoomMemberRawPayload.ready(), this.cacheRoomRawPayload.ready(), ]) const roomMemberTotalNum = [...this.cacheRoomMemberRawPayload.values()].reduce( (accuVal, currVal) => { return accuVal + Object.keys(currVal).length }, 0, ) log.verbose('PuppetPadchatManager', 'initCache() inited %d Contacts, %d RoomMembers, %d Rooms, cachedir="%s"', this.cacheContactRawPayload.size, roomMemberTotalNum, this.cacheRoomRawPayload.size, baseDir, ) }
public async getRoomMemberIdList( roomId: string, dirty = false, ): Promise<string[]> { log.verbose('PuppetPadchatManager', 'getRoomMemberIdList(%d)', roomId) if (!this.cacheRoomMemberRawPayload) { throw new Error('cache not inited' ) } if (dirty) { this.roomMemberRawPayloadDirty(roomId) } const memberRawPayloadDict = this.cacheRoomMemberRawPayload.get(roomId) || await this.syncRoomMember(roomId) if (!memberRawPayloadDict) { // or return [] ? throw new Error('roomId not found: ' + roomId) } const memberIdList = Object.keys(memberRawPayloadDict) // console.log('memberRawPayloadDict:', memberRawPayloadDict) log.verbose('PuppetPadchatManager', 'getRoomMemberIdList(%d) length=%d', roomId, memberIdList.length) return memberIdList }
protected async onLogin(userId: string): Promise<void> { log.verbose('PuppetPadchatManager', `login(%s)`, userId) if (this.userId) { throw new Error('userId exist') } this.userId = userId await this.stopCheckScan() /** * Update Memory Slot */ this.memorySlot = await this.refreshMemorySlotData( this.memorySlot, userId, ) await this.options.memory.set(MEMORY_SLOT_NAME, this.memorySlot) await this.options.memory.save() /** * Init persistence cache */ await this.initCache(this.options.token, this.userId) /** * Refresh the login-ed user payload */ if (this.cacheContactRawPayload) { this.cacheContactRawPayload.delete(this.userId) await this.contactRawPayload(this.userId) } this.emit('login', this.userId) }
public contactRawPayloadDirty( contactId: string, ): void { log.verbose('PuppetPadchatManager', 'contactRawPayloadDirty(%d)', contactId) if (!this.cacheContactRawPayload) { throw new Error('cache not inited' ) } this.cacheContactRawPayload.delete(contactId) }
public roomRawPayloadDirty( roomId: string, ): void { log.verbose('PuppetPadchatManager', 'roomRawPayloadDirty(%d)', roomId) if (!this.cacheRoomRawPayload) { throw new Error('cache not inited' ) } this.cacheRoomRawPayload.delete(roomId) }
public getRoomIdList(): string[] { log.verbose('PuppetPadchatManager', 'getRoomIdList()') if (!this.cacheRoomRawPayload) { throw new Error('cache not inited' ) } const roomIdList = [...this.cacheRoomRawPayload.keys()] log.verbose('PuppetPadchatManager', 'getRoomIdList()=%d', roomIdList.length) return roomIdList }
public getContactIdList(): string[] { log.verbose('PuppetPadchatManager', 'getContactIdList()') if (!this.cacheContactRawPayload) { throw new Error('cache not inited' ) } const contactIdList = [...this.cacheContactRawPayload.keys()] log.silly('PuppetPadchatManager', 'getContactIdList() = %d', contactIdList.length) return contactIdList }
public async syncRoomMember( roomId: string, ): Promise<{ [contactId: string]: PadchatRoomMemberPayload }> { log.silly('PuppetPadchatManager', 'syncRoomMember(%s)', roomId) const memberListPayload = await this.WXGetChatRoomMember(roomId) if (!memberListPayload || !('user_name' in memberListPayload)) { // check user_name too becasue the server might return {} /** * Room Id not exist * See: https://github.com/lijiarui/wechaty-puppet-padchat/issues/64#issuecomment-397319016 */ this.roomMemberRawPayloadDirty(roomId) this.roomRawPayloadDirty(roomId) return {} } log.silly('PuppetPadchatManager', 'syncRoomMember(%s) total %d members', roomId, Object.keys(memberListPayload).length, ) const memberDict: { [contactId: string]: PadchatRoomMemberPayload } = {} for (const memberPayload of memberListPayload.member) { const contactId = memberPayload.user_name memberDict[contactId] = memberPayload } if (!this.cacheRoomMemberRawPayload) { throw new Error('cache not inited' ) } const oldMemberDict = this.cacheRoomMemberRawPayload.get(roomId) const newMemberDict = { ...oldMemberDict, ...memberDict, } this.cacheRoomMemberRawPayload.set(roomId, newMemberDict) return newMemberDict }
protected async releaseCache(): Promise<void> { log.verbose('PuppetPadchatManager', 'releaseCache()') if ( this.cacheContactRawPayload && this.cacheRoomMemberRawPayload && this.cacheRoomRawPayload ) { await this.cacheContactRawPayload.close(), await this.cacheRoomMemberRawPayload.close(), await this.cacheRoomRawPayload.close(), this.cacheContactRawPayload = undefined this.cacheRoomMemberRawPayload = undefined this.cacheRoomRawPayload = undefined log.silly('PuppetPadchatManager', 'releaseCache() cache closed.') } else { log.verbose('PuppetPadchatManager', 'releaseCache() cache not exist.') } }
const rawPayload = await Misc.retry(async (retry, attempt) => { log.silly('PuppetPadchatManager', 'roomRawPayload(%s) retry() attempt=%d', id, attempt) if (!this.cacheRoomRawPayload) { throw new Error('no cache') } if (this.cacheRoomRawPayload.has(id)) { return this.cacheRoomRawPayload.get(id) } const tryRawPayload = await this.WXGetRoomPayload(id) // check user_name too becasue the server might return {} // See issue #1358 https://github.com/Chatie/wechaty/issues/1358 if (tryRawPayload /* && tryRawPayload.user_name */) { this.cacheRoomRawPayload.set(id, tryRawPayload) return tryRawPayload } return retry(new Error('tryRawPayload empty')) })