room-invitation.ts 8.0 KB
Newer Older
1
/**
2
 *   Wechaty Chatbot SDK - https://github.com/wechaty/wechaty
3
 *
4 5
 *   @copyright 2016 Huan LI (李卓桓) <https://github.com/huan>, and
 *                   Wechaty Contributors <https://github.com/wechaty>.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 *   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 {
  instanceToClass,
}                   from 'clone-class'

import {
25 26
  Wechaty,
}               from '../wechaty'
27 28 29 30 31 32
import {
  log,
}               from '../config'
import {
  Acceptable,
}               from '../types'
33 34 35
import {
  timestampToDate,
}                   from '../helper-functions/pure/timestamp-to-date'
36 37 38 39

import {
  Contact,
}               from './contact'
40
import { RoomInvitationPayload } from 'wechaty-puppet'
41

L
lijiarui 已提交
42 43 44 45
/**
 *
 * accept room invitation
 */
46 47 48 49
class RoomInvitation implements Acceptable {

  static get wechaty  (): Wechaty { throw new Error('This class can not be used directory. See: https://github.com/wechaty/wechaty/issues/2027') }
  get wechaty        (): Wechaty { throw new Error('This class can not be used directory. See: https://github.com/wechaty/wechaty/issues/2027') }
50 51 52 53 54 55 56 57 58 59

  public static load<T extends typeof RoomInvitation> (
    this : T,
    id   : string,
  ): T['prototype'] {
    const newRoomInvitation = new (this as any)(id)
    return newRoomInvitation
  }

  /**
60
   * @hideconstructor
61 62 63 64
   * Instance Properties
   *
   */
  constructor (
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
65
    public readonly id: string,
66 67 68 69 70 71
  ) {
    log.verbose('RoomInvitation', 'constructor(id=%s)', id)

    const MyClass = instanceToClass(this, RoomInvitation)

    if (MyClass === RoomInvitation) {
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
72
      throw new Error('RoomInvitation class can not be instantiated directly! See: https://github.com/wechaty/wechaty/issues/1217')
73 74
    }

75
    if (!this.wechaty.puppet) {
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
76
      throw new Error('RoomInvitation class can not be instantiated without a puppet!')
77 78 79 80 81 82
    }
  }

  public toString () {
    return [
      'RoomInvitation#',
83
      this.id || 'loading',
84 85 86
    ].join('')
  }

87
  /**
88
    * @ignore
89
   */
90
  public async toStringAsync (): Promise<string> {
91
    const payload = await this.wechaty.puppet.roomInvitationPayload(this.id)
92 93 94 95
    return [
      'RoomInvitation#',
      this.id,
      '<',
96
      payload.topic,
97
      ',',
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
      payload.inviterId,
      '>',
    ].join('')
  }

  /**
   * Accept Room Invitation
   *
   * @returns {Promise<void>}
   *
   * @example
   * const bot = new Wechaty()
   * bot.on('room-invite', async roomInvitation => {
   *   try {
   *     console.log(`received room-invite event.`)
   *     await roomInvitation.accept()
   *   } catch (e) {
   *     console.error(e)
   *   }
   * }
   * .start()
   */
  public async accept (): Promise<void> {
    log.verbose('RoomInvitation', 'accept()')

123
    await this.wechaty.puppet.roomInvitationAccept(this.id)
124 125

    const inviter = await this.inviter()
Huan (李卓桓)'s avatar
lint  
Huan (李卓桓) 已提交
126
    const topic   = await this.topic()
127 128 129 130 131

    try {
      await inviter.ready()

      log.verbose('RoomInvitation', 'accept() with room(%s) & inviter(%s) ready()',
132 133 134
        topic,
        inviter,
      )
135 136
      return
    } catch (e) {
137
      log.warn('RoomInvitation', 'accept() inviter(%s) is not ready because of %s',
138 139 140
        inviter,
        (e && e.message) || e,
      )
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
    }
  }

  /**
   * Get the inviter from room invitation
   *
   * @returns {Contact}
   * @example
   * const bot = new Wechaty()
   * bot.on('room-invite', async roomInvitation => {
   *   const inviter = await roomInvitation.inviter()
   *   const name = inviter.name()
   *   console.log(`received room invitation event from ${name}`)
   * }
   * .start()
   */
  public async inviter (): Promise<Contact> {
158 159
    log.verbose('RoomInvitation', 'inviter()')

160
    const payload = await this.wechaty.puppet.roomInvitationPayload(this.id)
161 162 163 164 165
    const inviter = this.wechaty.Contact.load(payload.inviterId)
    return inviter
  }

  /**
166
   * Get the room topic from room invitation
167 168 169 170 171
   *
   * @returns {Contact}
   * @example
   * const bot = new Wechaty()
   * bot.on('room-invite', async roomInvitation => {
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
172
   *   const topic = await roomInvitation.topic()
173 174 175 176
   *   console.log(`received room invitation event from room ${topic}`)
   * }
   * .start()
   */
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
177
  public async topic (): Promise<string> {
178
    const payload = await this.wechaty.puppet.roomInvitationPayload(this.id)
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
179

180
    return payload.topic || payload.topic || ''
181 182
  }

183 184
  public async memberCount (): Promise<number> {
    log.verbose('RoomInvitation', 'memberCount()')
185

186
    const payload = await this.wechaty.puppet.roomInvitationPayload(this.id)
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
187

188
    return payload.memberCount || payload.memberCount || 0
189 190 191 192
  }

  /**
   * List of Room Members that you known(is friend)
193
    * @ignore
194
   */
195
  public async memberList (): Promise<Contact[]> {
196 197
    log.verbose('RoomInvitation', 'roomMemberList()')

198
    const payload = await this.wechaty.puppet.roomInvitationPayload(this.id)
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
199

200
    const contactIdList = payload.memberIdList || payload.memberIdList || []
201 202 203 204 205 206 207 208 209 210 211

    const contactList = contactIdList.map(
      id => this.wechaty.Contact.load(id),
    )
    await Promise.all(
      contactList.map(
        c => c.ready(),
      ),
    )

    return contactList
212 213
  }

L
lijiarui 已提交
214 215 216 217 218
  /**
   * Get the invitation time
   *
   * @returns {Promise<Date>}
   */
219
  public async date (): Promise<Date> {
220 221
    log.verbose('RoomInvitation', 'date()')

222
    const payload = await this.wechaty.puppet.roomInvitationPayload(this.id)
223
    return timestampToDate(payload.timestamp)
224
  }
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

  /**
   * Returns the roopm invitation age in seconds. <br>
   *
   * For example, the invitation is sent at time `8:43:01`,
   * and when we received it in Wechaty, the time is `8:43:15`,
   * then the age() will return `8:43:15 - 8:43:01 = 14 (seconds)`
   * @returns {number}
   */
  public async age (): Promise<number> {
    const recvDate = await this.date()

    const ageMilliseconds = Date.now() - recvDate.getTime()
    const ageSeconds = Math.floor(ageMilliseconds / 1000)

    return ageSeconds
  }

243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
  /**
   * Load the room invitation info from disk
   *
   * @returns {RoomInvitation}
   * @example
   * const bot = new Wechaty()
   * const dataFromDisk // get the room invitation info data from disk
   * const roomInvitation = await bot.RoomInvitation.fromJSON(dataFromDisk)
   * await roomInvitation.accept()
   */
  public static async fromJSON (
    payload: string | RoomInvitationPayload,
  ): Promise<RoomInvitation> {
    log.verbose('RoomInvitation', 'fromJSON(%s)',
      typeof payload === 'string'
        ? payload
        : JSON.stringify(payload),
    )

    if (typeof payload === 'string') {
      payload = JSON.parse(payload) as RoomInvitationPayload
    }

266
    await this.wechaty.puppet.roomInvitationPayload(payload.id, payload)
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284

    return this.wechaty.RoomInvitation.load(payload.id)
  }

  /**
   * Get the room invitation info when listened on room-invite event
   *
   * @returns {string}
   * @example
   * const bot = new Wechaty()
   * bot.on('room-invite', async roomInvitation => {
   *  const roomInvitation = bot.RoomInvitation.load(roomInvitation.id)
   *  const jsonData = await roomInvitation.toJSON(roomInvitation.id)
   *  // save the json data to disk, and we can use it by RoomInvitation.fromJSON()
   * }
   * .start()
   */
  public async toJSON (): Promise<string> {
285
    log.verbose('RoomInvitation', 'toJSON()')
286
    const payload = await this.wechaty.puppet.roomInvitationPayload(this.id)
287 288 289
    return JSON.stringify(payload)
  }

290
}
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308

function wechatifyRoomInvitation (wechaty: Wechaty): typeof RoomInvitation {

  class WechatifiedRoomInvitation extends RoomInvitation {

    static get wechaty  () { return wechaty }
    get wechaty        () { return wechaty }

  }

  return WechatifiedRoomInvitation

}

export {
  RoomInvitation,
  wechatifyRoomInvitation,
}