Exemple #1
0
  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,
              )
  }
Exemple #2
0
  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
  }
Exemple #3
0
  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)
  }
Exemple #4
0
 public contactRawPayloadDirty(
   contactId: string,
 ): void {
   log.verbose('PuppetPadchatManager', 'contactRawPayloadDirty(%d)', contactId)
   if (!this.cacheContactRawPayload) {
     throw new Error('cache not inited' )
   }
   this.cacheContactRawPayload.delete(contactId)
 }
Exemple #5
0
 public roomRawPayloadDirty(
   roomId: string,
 ): void {
   log.verbose('PuppetPadchatManager', 'roomRawPayloadDirty(%d)', roomId)
   if (!this.cacheRoomRawPayload) {
     throw new Error('cache not inited' )
   }
   this.cacheRoomRawPayload.delete(roomId)
 }
Exemple #6
0
 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
 }
Exemple #7
0
 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
 }
Exemple #8
0
  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
  }
Exemple #9
0
  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.')
    }
  }
Exemple #10
0
    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'))
    })