提交 02d7036a 编写于 作者: L lijiarui 提交者: Huan (李卓桓)

Add doc (#1458)

* init

* add wechaty main doc

* fix wechaty comment

* add contact doc

* add contact more comment

* add room docs

* add message doc

* add friendship doc

* change as request

* change room find function typo

* add request doc

* remove index.md

* removed change of docs/index

* fix typo

* fix message typo

* https://github.com/qhduan/wechaty-doc/issues/19

* https://github.com/qhduan/wechaty-doc/issues/20

* wechaty.init should use start instead

* https://github.com/qhduan/wechaty-doc/issues/20

* https://github.com/qhduan/wechaty-doc/issues/20\#issuecomment-404408822

* https://github.com/qhduan/wechaty-doc/issues/23

* fix contact enum things in https://github.com/qhduan/wechaty-doc/issues/22

* change friendship send function
上级 4bba6d1c
......@@ -43,7 +43,6 @@ export const POOL = Symbol('pool')
/**
* All wechat contacts(friend) will be encapsulated as a Contact.
*
* `Contact` is `Sayable`,
* [Examples/Contact-Bot]{@link https://github.com/Chatie/wechaty/blob/master/examples/contact-bot.ts}
*/
export class Contact extends Accessory implements Sayable {
......@@ -71,6 +70,17 @@ export class Contact extends Accessory implements Sayable {
* @private
* About the Generic: https://stackoverflow.com/q/43003970/1123955
*/
/**
* Get Contact by id
*
* @static
* @param {string} id
* @returns {Contact}
* @example
* const bot = new Wechaty()
* await bot.start()
* const contact = bot.Contact.load('contactId')
*/
public static load<T extends typeof Contact>(
this : T,
id : string,
......@@ -121,8 +131,10 @@ export class Contact extends Accessory implements Sayable {
* @param {ContactQueryFilter} query
* @returns {(Promise<Contact | null>)} If can find the contact, return Contact, or return null
* @example
* const contactFindByName = await Contact.find({ name:"ruirui"} )
* const contactFindByAlias = await Contact.find({ alias:"lijiarui"} )
* const bot = new Wechaty()
* await bot.start()
* const contactFindByName = await bot.Contact.find({ name:"ruirui"} )
* const contactFindByAlias = await bot.Contact.find({ alias:"lijiarui"} )
*/
public static async find<T extends typeof Contact>(
this : T,
......@@ -180,9 +192,11 @@ export class Contact extends Accessory implements Sayable {
* @param {ContactQueryFilter} [queryArg]
* @returns {Promise<Contact[]>}
* @example
* const contactList = await Contact.findAll() // get the contact list of the bot
* const contactList = await Contact.findAll({name: 'ruirui'}) // find allof the contacts whose name is 'ruirui'
* const contactList = await Contact.findAll({alias: 'lijiarui'}) // find all of the contacts whose alias is 'lijiarui'
* const bot = new Wechaty()
* await bot.start()
* const contactList = await bot.Contact.findAll() // get the contact list of the bot
* const contactList = await bot.Contact.findAll({name: 'ruirui'}) // find allof the contacts whose name is 'ruirui'
* const contactList = await bot.Contact.findAll({alias: 'lijiarui'}) // find all of the contacts whose alias is 'lijiarui'
*/
public static async findAll<T extends typeof Contact>(
this : T,
......@@ -239,6 +253,7 @@ export class Contact extends Accessory implements Sayable {
/**
*
* Instance properties
* @private
*
*/
protected get payload(): undefined | ContactPayload {
......@@ -282,35 +297,37 @@ export class Contact extends Accessory implements Sayable {
return `Contact<${identity}>`
}
/**
* Sent Text to contact
*
* @param {string} text
* @example
* const contact = await Contact.find({name: 'lijiarui'}) // change 'lijiarui' to any of your contact name in wechat
* try {
* await contact.say('welcome to wechaty!')
* } catch (e) {
* console.error(e)
* }
*/
public async say(text: string): Promise<void>
public async say(file: FileBox) : Promise<void>
public async say(contact: Contact) : Promise<void>
/**
* Send Media File to Contact
*
* @param {Message} Message
* @param {(string | Contact | FileBox)} textOrContactOrFile
* send text, Contact, or file to contact. </br>
* You can use {@link https://www.npmjs.com/package/file-box|FileBox} to send file
* @returns {Promise<void>}
* @example
* const contact = await Contact.find({name: 'lijiarui'}) // change 'lijiarui' to any of your contact name in wechat
* try {
* await contact.say(bot.Message.create(__dirname + '/wechaty.png') // put the filePath you want to send here
* } catch (e) {
* console.error(e)
* }
* const bot = new Wechaty()
* await bot.start()
* const contact = await bot.Contact.find({name: 'lijiarui'}) // change 'lijiarui' to any of your contact name in wechat
*
* # 1. send text to contact
*
* await contact.say('welcome to wechaty!')
*
* # 2. send media file to contact
*
* import { FileBox } from 'file-box'
* const fileBox1 = FileBox.fromUrl('https://chatie.io/wechaty/images/bot-qr-code.png')
* const fileBox2 = FileBox.fromLocal('/tmp/text.txt')
* await contact.say(fileBox1)
* await contact.say(fileBox2)
*
* # 3. send contact card to contact
*
* const contactCard = bot.Contact.load('contactId')
* await contact.say(contactCard)
*/
public async say(file: FileBox) : Promise<void>
public async say(contact: Contact) : Promise<void>
public async say(textOrContactOrFile: string | Contact | FileBox): Promise<void> {
log.verbose('Contact', 'say(%s)', textOrContactOrFile)
......@@ -414,13 +431,11 @@ export class Contact extends Accessory implements Sayable {
}
/**
* Check if contact is stranger
*
* @deprecated use friend() instead
* @description
* Should use {@link Contact#friend} instead
*
* @returns {boolean | null} - True for not friend of the bot, False for friend of the bot, null for unknown.
* @example
* const isStranger = contact.stranger()
* @deprecated
*/
public stranger(): null | boolean {
log.warn('Contact', 'stranger() DEPRECATED. use friend() instead.')
......@@ -431,7 +446,10 @@ export class Contact extends Accessory implements Sayable {
/**
* Check if contact is friend
*
* @returns {boolean | null} - True for friend of the bot, False for not friend of the bot, null for unknown.
* @returns {boolean | null}
*
* <br>True for friend of the bot <br>
* False for not friend of the bot, null for unknown.
* @example
* const isFriend = contact.friend()
*/
......@@ -444,15 +462,15 @@ export class Contact extends Accessory implements Sayable {
}
/**
* Check if it's a offical account
*
* @deprecated use type() instead
*
* @returns {boolean | null} - True for official account, Flase for contact is not a official account, null for unknown
* @ignore
* @see {@link https://github.com/Chatie/webwx-app-tracker/blob/7c59d35c6ea0cff38426a4c5c912a086c4c512b2/formatted/webwxApp.js#L3243|webwxApp.js#L324}
* @see {@link https://github.com/Urinx/WeixinBot/blob/master/README.md|Urinx/WeixinBot/README}
* @example
* const isOfficial = contact.official()
*/
/**
* @description
* Check if it's a offical account, should use {@link Contact#type} instead
* @deprecated
*
*/
public official(): boolean {
log.warn('Contact', 'official() DEPRECATED. use type() instead')
......@@ -460,31 +478,40 @@ export class Contact extends Accessory implements Sayable {
}
/**
* Check if it's a personal account
*
* @deprecated use type() instead
*
* @returns {boolean} - True for personal account, Flase for contact is not a personal account
* @example
* const isPersonal = contact.personal()
* @description
* Check if it's a personal account, should use {@link Contact#type} instead
* @deprecated
*/
public personal(): boolean {
log.warn('Contact', 'personal() DEPRECATED. use type() instead')
return !this.official()
}
/**
* Enum for ContactType
* @enum {number}
* @property {number} Unknown - ContactType.Unknown (0) for Unknown
* @property {number} Personal - ContactType.Personal (1) for Personal
* @property {number} Official - ContactType.Official (2) for Official
*/
/**
* Return the type of the Contact
* > Tips: ContactType is enum here.</br>
* @returns {ContactType.Unknown | ContactType.Personal | ContactType.Official}
*
* @returns ContactType - Contact.Type.PERSONAL for personal account, Contact.Type.OFFICIAL for official account
* @example
* const isOfficial = contact.type() === Contact.Type.OFFICIAL
* const bot = new Wechaty()
* await bot.start()
* const isOfficial = contact.type() === bot.Contact.Type.Official
*/
public type(): ContactType {
return this.payload!.type
}
/**
* @private
* TODO
* Check if the contact is star contact.
*
* @returns {boolean | null} - True for star friend, False for no star friend.
......@@ -502,10 +529,11 @@ export class Contact extends Accessory implements Sayable {
/**
* Contact gender
* > Tips: ContactGender is enum here. </br>
*
* @returns {ContactGender.Male(2)|Gender.Female(1)|Gender.Unknown(0)}
* @returns {ContactGender.Unknown | ContactGender.Male | ContactGender.Female}
* @example
* const gender = contact.gender()
* const gender = contact.gender() === bot.Contact.Gender.Male
*/
public gender(): ContactGender {
return this.payload
......@@ -540,13 +568,13 @@ export class Contact extends Accessory implements Sayable {
*
* @returns {Promise<FileBox>}
* @example
* const avatarFileName = contact.name() + `.jpg`
* const fileBox = await contact.avatar()
* const avatarWriteStream = createWriteStream(avatarFileName)
* fileBox.pipe(avatarWriteStream)
* log.info('Bot', 'Contact: %s: %s with avatar file: %s', contact.weixin(), contact.name(), avatarFileName)
* # Save avatar to local file like `1-name.jpg`
*
* const file = await contact.avatar()
* const name = file.name
* await file.toFile(name, true)
* console.log(`Contact: ${contact.name()} with avatar file: ${name}`)
*/
// TODO: use File to replace ReadableStream
public async avatar(): Promise<FileBox> {
log.verbose('Contact', 'avatar()')
......@@ -554,13 +582,10 @@ export class Contact extends Accessory implements Sayable {
}
/**
* Force reload(re-ready()) data for Contact
*
* @deprecated use sync() instead
* @description
* Force reload(re-ready()) data for Contact, use {@link Contact#sync} instead
*
* @returns {Promise<this>}
* @example
* await contact.refresh()
* @deprecated
*/
public refresh(): Promise<void> {
log.warn('Contact', 'refresh() DEPRECATED. use sync() instead.')
......@@ -568,7 +593,7 @@ export class Contact extends Accessory implements Sayable {
}
/**
* sycc data for Contact
* Force reload(re-ready()) data for Contact,
*
* @returns {Promise<this>}
* @example
......
......@@ -67,16 +67,30 @@ export class Friendship extends Accessory {
}
/**
* @deprecated use add() instead
* @description
* use {@link Friendship#add} instead
* @deprecated
*/
public static async send(contact: Contact, hello: string) {
log.warn('Friendship', 'static send() DEPRECATED, use add() instead.')
return this.add(contact, hello)
}
/**
* Send a Friend Request to a `contact` with message `hello`.
* @param contact
* @param hello
*
* The best practice is to send friend request once per minute.
* Remeber not to do this too frequently, or your account may be blocked.
*
* @param {Contact} contact - Send friend request to contact
* @param {string} hello - The friend request content
* @returns {Promise<void>}
*
* @example
* const memberList = await room.memberList()
* for (let i = 0; i < memberList.length; i++) {
* await bot.Friendship.add(member, 'Nice to meet you! I am wechaty bot!')
* }
*/
public static async add(
contact : Contact,
......@@ -138,6 +152,9 @@ export class Friendship extends Accessory {
*
*/
/**
* @ignore
*/
protected get payload(): undefined | FriendshipPayload {
if (!this.id) {
return undefined
......@@ -183,6 +200,7 @@ export class Friendship extends Accessory {
/**
* no `dirty` support because Friendship has no rawPayload(yet)
* @ignore
*/
public async ready(): Promise<void> {
if (this.payload) {
......@@ -196,6 +214,36 @@ export class Friendship extends Accessory {
}
}
/**
* Accept Friend Request
*
* @returns {Promise<void>}
*
* @example
* const bot = new Wechaty()
* bot.on('friendship', async friendship => {
* try {
* console.log(`received friend event.`)
* switch (friendship.type()) {
*
* # 1. New Friend Request
*
* case Friendship.Type.Receive:
* await friendship.accept()
* break
*
* # 2. Friend Ship Confirmed
*
* case Friendship.Type.Confirm:
* console.log(`friend ship confirmed`)
* break
* }
* } catch (e) {
* console.error(e)
* }
* }
* .start()
*/
public async accept(): Promise<void> {
log.verbose('Friendship', 'accept()')
......@@ -230,6 +278,24 @@ export class Friendship extends Accessory {
}
/**
* Get verify message from
*
* @returns {string}
* @example <caption>If request content is `ding`, then accept the friendship</caption>
* const bot = new Wechaty()
* bot.on('friendship', async friendship => {
* try {
* console.log(`received friend event from ${friendship.contact().name()}`)
* if (friendship.type() === Friendship.Type.Receive && friendship.hello() === 'ding') {
* await friendship.accept()
* }
* } catch (e) {
* console.error(e)
* }
* }
* .start()
*/
public hello(): string {
if (!this.payload) {
throw new Error('no payload')
......@@ -237,6 +303,19 @@ export class Friendship extends Accessory {
return this.payload.hello || ''
}
/**
* Get the contact from friendship
*
* @returns {Contact}
* @example
* const bot = new Wechaty()
* bot.on('friendship', async friendship => {
* const contact = friendship.contact()
* const name = contact.name()
* console.log(`received friend event from ${name}`)
* }
* .start()
*/
public contact(): Contact {
if (!this.payload) {
throw new Error('no payload')
......@@ -246,11 +325,37 @@ export class Friendship extends Accessory {
return contact
}
/**
* @ignore
*/
public async reject(): Promise<void> {
log.warn('Friendship', 'reject() not necessary, NOP.')
return
}
/**
* Return the Friendship Type
* > Tips: FriendshipType is enum here. </br>
* - FriendshipType.Unknown </br>
* - FriendshipType.Confirm </br>
* - FriendshipType.Receive </br>
* - FriendshipType.Verify </br>
*
* @returns {FriendshipType}
*
* @example <caption>If request content is `ding`, then accept the friendship</caption>
* const bot = new Wechaty()
* bot.on('friendship', async friendship => {
* try {
* if (friendship.type() === Friendship.Type.Receive && friendship.hello() === 'ding') {
* await friendship.accept()
* }
* } catch (e) {
* console.error(e)
* }
* }
* .start()
*/
public type(): FriendshipType {
return this.payload
? this.payload.type
......
......@@ -50,7 +50,6 @@ import {
/**
* All wechat messages will be encapsulated as a Message.
*
* `Message` is `Sayable`,
* [Examples/Ding-Dong-Bot]{@link https://github.com/Chatie/wechaty/blob/master/examples/ding-dong-bot.ts}
*/
export class Message extends Accessory implements Sayable {
......@@ -61,10 +60,14 @@ export class Message extends Accessory implements Sayable {
*
*/
/**
* @private
*/
// tslint:disable-next-line:variable-name
public static readonly Type = MessageType
/**
* @ignore
* @todo add function
*/
public static async find<T extends typeof Message>(
......@@ -75,6 +78,7 @@ export class Message extends Accessory implements Sayable {
}
/**
* @ignore
* @todo add function
*/
public static async findAll<T extends typeof Message>(
......@@ -90,7 +94,7 @@ export class Message extends Accessory implements Sayable {
/**
* Create a Mobile Terminated Message
*
* @ignore
* "mobile originated" or "mobile terminated"
* https://www.tatango.com/resources/video-lessons/video-mo-mt-sms-messaging/
*/
......@@ -114,6 +118,7 @@ export class Message extends Accessory implements Sayable {
/**
*
* Instance Properties
* @private
*
*/
private get payload(): undefined | MessagePayload {
......@@ -197,6 +202,21 @@ export class Message extends Accessory implements Sayable {
/**
* Get the sender from a message.
* @returns {Contact}
* @example
* const bot = new Wechaty()
* bot
* .on('message', async m => {
* const contact = msg.from()
* const text = msg.text()
* const room = msg.room()
* if (room) {
* const topic = await room.topic()
* console.log(`Room: ${topic} Contact: ${contact.name()} Text: ${text}`)
* } else {
* console.log(`Contact: ${contact.name()} Text: ${text}`)
* }
* })
* .start()
*/
public from(): null | Contact {
if (!this.payload) {
......@@ -241,6 +261,21 @@ export class Message extends Accessory implements Sayable {
* If the message is not in a room, then will return `null`
*
* @returns {(Room | null)}
* @example
* const bot = new Wechaty()
* bot
* .on('message', async m => {
* const contact = msg.from()
* const text = msg.text()
* const room = msg.room()
* if (room) {
* const topic = await room.topic()
* console.log(`Room: ${topic} Contact: ${contact.name()} Text: ${text}`)
* } else {
* console.log(`Contact: ${contact.name()} Text: ${text}`)
* }
* })
* .start()
*/
public room(): null | Room {
if (!this.payload) {
......@@ -256,7 +291,10 @@ export class Message extends Accessory implements Sayable {
}
/**
* @deprecated use text() instead
* @description
* use {@link Message#text} instead
*
* @deprecated
*/
public content(): string {
log.warn('Message', 'content() DEPRECATED. use text() instead.')
......@@ -267,6 +305,21 @@ export class Message extends Accessory implements Sayable {
* Get the text content of the message
*
* @returns {string}
* @example
* const bot = new Wechaty()
* bot
* .on('message', async m => {
* const contact = msg.from()
* const text = msg.text()
* const room = msg.room()
* if (room) {
* const topic = await room.topic()
* console.log(`Room: ${topic} Contact: ${contact.name()} Text: ${text}`)
* } else {
* console.log(`Contact: ${contact.name()} Text: ${text}`)
* }
* })
* .start()
*/
public text(): string {
if (!this.payload) {
......@@ -284,21 +337,45 @@ export class Message extends Accessory implements Sayable {
* Reply a Text or Media File message to the sender.
*
* @see {@link https://github.com/Chatie/wechaty/blob/master/examples/ding-dong-bot.ts|Examples/ding-dong-bot}
* @param {(string | FileBox)} textOrContactOrFile
* @param {(string | Contact | FileBox)} textOrContactOrFile
* send text, Contact, or file to bot. </br>
* You can use {@link https://www.npmjs.com/package/file-box|FileBox} to send file
* @param {(Contact|Contact[])} [mention]
* If this is a room message, when you set mention param, you can `@` Contact in the room.
* @returns {Promise<void>}
*
* @example
* import { FileBox } from 'file-box'
* const bot = new Wechaty()
* bot
* .on('message', async m => {
*
* # 1. send Image
*
* if (/^ding$/i.test(m.text())) {
* await m.say('hello world')
* console.log('Bot REPLY: hello world')
* await m.say(new bot.Message(__dirname + '/wechaty.png'))
* console.log('Bot REPLY: Image')
* const fileBox = FileBox.fromUrl('https://chatie.io/wechaty/images/bot-qr-code.png')
* await msg.say(fileBox)
* }
*
* # 2. send Text
*
* if (/^dong$/i.test(m.text())) {
* await msg.say('dingdingding')
* }
*
* # 3. send Contact
*
* if (/^lijiarui$/i.test(m.text())) {
* const contactCard = await bot.Contact.find({name: 'lijiarui'})
* if (!contactCard) {
* console.log('not found')
* return
* }
* await msg.say(contactCard)
* }
*
* })
* .start()
*/
public async say(
textOrContactOrFile : string | Contact | FileBox,
......@@ -375,40 +452,24 @@ export class Message extends Accessory implements Sayable {
}
}
/**
* @deprecated use toFile() instead
*/
public async file(): Promise<FileBox> {
log.warn('Message', 'file() DEPRECATED. use toFileBox() instead.')
return this.toFileBox()
}
public async toFileBox(): Promise<FileBox> {
if (this.type() === Message.Type.Text) {
throw new Error('text message no file')
}
const fileBox = await this.puppet.messageFile(this.id)
return fileBox
}
public async toContact(): Promise<Contact> {
log.warn('Message', 'toContact() to be implemented')
if (this.type() === Message.Type.Contact) {
throw new Error('message not a ShareCard')
}
// TODO: return the ShareCard Contact
const contact = this.wechaty.userSelf()
return contact
}
/**
* Get the type from the message.
* > Tips: MessageType is Enum here. </br>
* - MessageType.Unknown </br>
* - MessageType.Attachment </br>
* - MessageType.Audio </br>
* - MessageType.Contact </br>
* - MessageType.Emoticon </br>
* - MessageType.Image </br>
* - MessageType.Text </br>
* - MessageType.Video </br>
* @returns {MessageType}
*
* If type is equal to `MsgType.RECALLED`, {@link Message#id} is the msgId of the recalled message.
* @see {@link MsgType}
* @returns {WebMsgType}
* @example
* const bot = new Wechaty()
* if (message.type() === bot.Message.Type.Text) {
* console.log('This is a text message')
* }
*/
public type(): MessageType {
if (!this.payload) {
......@@ -446,10 +507,10 @@ export class Message extends Accessory implements Sayable {
* | Identify magic code (8197) by programming | ✘ | ✘ | ✘ | ✘ |
* | Identify two contacts with the same roomAlias by [You were mentioned] tip | ✘ | ✘ | √ | √ |
*
* @returns {Contact[]} - Return message mentioned contactList
* @returns {Promise<Contact[]>} - Return message mentioned contactList
*
* @example
* const contactList = message.mentioned()
* const contactList = await message.mention()
* console.log(contactList)
*/
public async mention(): Promise<Contact[]> {
......@@ -517,7 +578,9 @@ export class Message extends Accessory implements Sayable {
}
/**
* @deprecated: use mention() instead
* @description
* should use {@link Message#mention} instead
* @deprecated
*/
public async mentioned(): Promise<Contact[]> {
log.warn('Message', 'mentioned() DEPRECATED. use mention() instead.')
......@@ -603,6 +666,17 @@ export class Message extends Accessory implements Sayable {
* @param {(Sayable | Sayable[])} to Room or Contact
* The recipient of the message, the room, or the contact
* @returns {Promise<void>}
* @example
* const bot = new Wechaty()
* bot
* .on('message', async m => {
* const room = await bot.Room.find({topic: 'wechaty'})
* if (room) {
* await m.forward(room)
* console.log('forward this message to wechaty room!')
* }
* })
* .start()
*/
public async forward(to: Room | Contact): Promise<void> {
log.verbose('Message', 'forward(%s)', to)
......@@ -629,6 +703,9 @@ export class Message extends Accessory implements Sayable {
}
}
/**
* @private
*/
public date(): Date {
if (!this.payload) {
throw new Error('no payload')
......@@ -640,8 +717,12 @@ export class Message extends Accessory implements Sayable {
}
/**
* Message Age:
* in seconds.
* Returns the message age in seconds. <br>
*
* For example, the message 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 age(): number {
const ageMilliseconds = Date.now() - this.date().getTime()
......@@ -649,6 +730,46 @@ export class Message extends Accessory implements Sayable {
return ageSeconds
}
/**
* @description
* use {@link Message#toFileBox} instead
* @deprecated
*/
public async file(): Promise<FileBox> {
log.warn('Message', 'file() DEPRECATED. use toFileBox() instead.')
return this.toFileBox()
}
/**
* Extract the Media File from the Message, and put it into the FileBox.
*
* @returns {Promise<FileBox>}
*/
public async toFileBox(): Promise<FileBox> {
if (this.type() === Message.Type.Text) {
throw new Error('text message no file')
}
const fileBox = await this.puppet.messageFile(this.id)
return fileBox
}
/**
* Get Share Card of the Message
* Extract the Contact Card from the Message, and encapsulate it into Contact class
* @returns {Promise<Contact>}
*/
public async toContact(): Promise<Contact> {
log.warn('Message', 'toContact() to be implemented')
if (this.type() === Message.Type.Contact) {
throw new Error('message not a ShareCard')
}
// TODO: return the ShareCard Contact
const contact = this.wechaty.userSelf()
return contact
}
}
export default Message
......@@ -55,7 +55,6 @@ import {
/**
* All wechat rooms(groups) will be encapsulated as a Room.
*
* `Room` is `Sayable`,
* [Examples/Room-Bot]{@link https://github.com/Chatie/wechaty/blob/master/examples/room-bot.ts}
*/
export class Room extends Accessory implements Sayable {
......@@ -99,14 +98,23 @@ export class Room extends Accessory implements Sayable {
}
/**
* Find room by topic, return all the matched room
* The filter to find the room: {topic: string | RegExp}
*
* @typedef RoomQueryFilter
* @property {string} topic
*/
/**
* Find room by by filter: {topic: string | RegExp}, return all the matched room
* @static
* @param {RoomQueryFilter} [query]
* @returns {Promise<Room[]>}
* @example
* const roomList = await Room.findAll() // get the room list of the bot
* const roomList = await Room.findAll({name: 'wechaty'}) // find all of the rooms with name 'wechaty'
* const bot = new Wechaty()
* await bot.start()
* // after logged in
* const roomList = await bot.Room.findAll() // get the room list of the bot
* const roomList = await bot.Room.findAll({topic: 'wechaty'}) // find all of the rooms with name 'wechaty'
*/
public static async findAll<T extends typeof Room>(
this : T,
......@@ -148,6 +156,12 @@ export class Room extends Accessory implements Sayable {
*
* @param {RoomQueryFilter} query
* @returns {Promise<Room | null>} If can find the room, return Room, or return null
* @example
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const roomList = await bot.Room.find()
* const roomList = await bot.Room.find({topic: 'wechaty'})
*/
public static async find<T extends typeof Room>(
......@@ -200,6 +214,21 @@ export class Room extends Accessory implements Sayable {
* @private
* About the Generic: https://stackoverflow.com/q/43003970/1123955
*/
/**
* Load room by topic. <br>
* > Tips: For Web solution, it cannot get the unique topic id,
* but for other solutions besides web,
* we can get unique and permanent topic id.
*
* @static
* @param {string} id
* @returns {Room}
* @example
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const room = bot.Room.load('roomId')
*/
public static load<T extends typeof Room>(
this : T,
id : string,
......@@ -322,22 +351,34 @@ export class Room extends Accessory implements Sayable {
/**
* Send message inside Room, if set [replyTo], wechaty will mention the contact as well.
*
* @param {(string | MediaMessage)} textOrContactOrFile - Send `text` or `media file` inside Room.
* @param {(Contact | Contact[])} [replyTo] - Optional parameter, send content inside Room, and mention @replyTo contact or contactList.
* @returns {Promise<boolean>}
* If bot send message successfully, it will return true. If the bot failed to send for blocking or any other reason, it will return false
* @param {(string | Contact | FileBox)} textOrContactOrFile - Send `text` or `media file` inside Room. <br>
* You can use {@link https://www.npmjs.com/package/file-box|FileBox} to send file
* @param {(Contact | Contact[])} [mention] - Optional parameter, send content inside Room, and mention @replyTo contact or contactList.
* @returns {Promise<void>}
*
* @example
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const room = await bot.Room.find({topic: 'wechaty'})
*
* # 1. Send text inside Room
*
* @example <caption>Send text inside Room</caption>
* const room = await Room.find({name: 'wechaty'}) // change 'wechaty' to any of your room in wechat
* await room.say('Hello world!')
*
* @example <caption>Send media file inside Room</caption>
* const room = await Room.find({name: 'wechaty'}) // change 'wechaty' to any of your room in wechat
* await room.say(new MediaMessage('/test.jpg')) // put the filePath you want to send here
* # 2. Send media file inside Room
* import { FileBox } from 'file-box'
* const fileBox1 = FileBox.fromUrl('https://chatie.io/wechaty/images/bot-qr-code.png')
* const fileBox2 = FileBox.fromLocal('/tmp/text.txt')
* await room.say(fileBox1)
* await room.say(fileBox2)
*
* @example <caption>Send text inside Room, and mention @replyTo contact</caption>
* const contact = await Contact.find({name: 'lijiarui'}) // change 'lijiarui' to any of the room member
* const room = await Room.find({name: 'wechaty'}) // change 'wechaty' to any of your room in wechat
* # 3. Send Contact Card in a room
* const contactCard = await bot.Contact.find({name: 'lijiarui'}) // change 'lijiarui' to any of the room member
* await room.say(contactCard)
*
* # 4. Send text inside room and mention @mention contact
* const contact = await bot.Contact.find({name: 'lijiarui'}) // change 'lijiarui' to any of the room member
* await room.say('Hello world!', contact)
*/
public async say(
......@@ -423,28 +464,37 @@ export class Room extends Accessory implements Sayable {
* @return {this} - this for chain
*
* @example <caption>Event:join </caption>
* const room = await Room.find({topic: 'event-room'}) // change `event-room` to any room topic in your wechat
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const room = await bot.Room.find({topic: 'topic of your room'}) // change `event-room` to any room topic in your wechat
* if (room) {
* room.on('join', (room: Room, inviteeList: Contact[], inviter: Contact) => {
* const nameList = inviteeList.map(c => c.name()).join(',')
* console.log(`Room ${room.topic()} got new member ${nameList}, invited by ${inviter}`)
* console.log(`Room got new member ${nameList}, invited by ${inviter}`)
* })
* }
*
* @example <caption>Event:leave </caption>
* const room = await Room.find({topic: 'event-room'}) // change `event-room` to any room topic in your wechat
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const room = await bot.Room.find({topic: 'topic of your room'}) // change `event-room` to any room topic in your wechat
* if (room) {
* room.on('leave', (room: Room, leaverList: Contact[]) => {
* const nameList = leaverList.map(c => c.name()).join(',')
* console.log(`Room ${room.topic()} lost member ${nameList}`)
* console.log(`Room lost member ${nameList}`)
* })
* }
*
* @example <caption>Event:topic </caption>
* const room = await Room.find({topic: 'event-room'}) // change `event-room` to any room topic in your wechat
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const room = await bot.Room.find({topic: 'topic of your room'}) // change `event-room` to any room topic in your wechat
* if (room) {
* room.on('topic', (room: Room, topic: string, oldTopic: string, changer: Contact) => {
* console.log(`Room ${room.topic()} topic changed from ${oldTopic} to ${topic} by ${changer.name()}`)
* console.log(`Room topic changed from ${oldTopic} to ${topic} by ${changer.name()}`)
* })
* }
*
......@@ -460,16 +510,18 @@ export class Room extends Accessory implements Sayable {
* Add contact in a room
*
* @param {Contact} contact
* @returns {Promise<number>}
* @returns {Promise<void>}
* @example
* const contact = await Contact.find({name: 'lijiarui'}) // change 'lijiarui' to any contact in your wechat
* const room = await Room.find({topic: 'wechat'}) // change 'wechat' to any room topic in your wechat
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const contact = await bot.Contact.find({name: 'lijiarui'}) // change 'lijiarui' to any contact in your wechat
* const room = await bot.Room.find({topic: 'wechat'}) // change 'wechat' to any room topic in your wechat
* if (room) {
* const result = await room.add(contact)
* if (result) {
* console.log(`add ${contact.name()} to ${room.topic()} successfully! `)
* } else{
* console.log(`failed to add ${contact.name()} to ${room.topic()}! `)
* try {
* await room.add(contact)
* } catch(e) {
* console.error(e)
* }
* }
*/
......@@ -482,16 +534,18 @@ export class Room extends Accessory implements Sayable {
* Delete a contact from the room
* It works only when the bot is the owner of the room
* @param {Contact} contact
* @returns {Promise<number>}
* @returns {Promise<void>}
* @example
* const room = await Room.find({topic: 'wechat'}) // change 'wechat' to any room topic in your wechat
* const contact = await Contact.find({name: 'lijiarui'}) // change 'lijiarui' to any room member in the room you just set
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const room = await bot.Room.find({topic: 'wechat'}) // change 'wechat' to any room topic in your wechat
* const contact = await bot.Contact.find({name: 'lijiarui'}) // change 'lijiarui' to any room member in the room you just set
* if (room) {
* const result = await room.del(contact)
* if (result) {
* console.log(`remove ${contact.name()} from ${room.topic()} successfully! `)
* } else{
* console.log(`failed to remove ${contact.name()} from ${room.topic()}! `)
* try {
* await room.del(contact)
* } catch(e) {
* console.error(e)
* }
* }
*/
......@@ -516,7 +570,11 @@ export class Room extends Accessory implements Sayable {
// }
/**
* @private
* Bot quit the room itself
*
* @returns {Promise<void>}
* @example
* await room.quit()
*/
public async quit(): Promise<void> {
log.verbose('Room', 'quit() %s', this)
......@@ -533,7 +591,7 @@ export class Room extends Accessory implements Sayable {
* @returns {Promise<string | void>}
*
* @example <caption>When you say anything in a room, it will get room topic. </caption>
* const bot = Wechaty.instance()
* const bot = new Wechaty()
* bot
* .on('message', async m => {
* const room = m.room()
......@@ -542,18 +600,20 @@ export class Room extends Accessory implements Sayable {
* console.log(`room topic is : ${topic}`)
* }
* })
* .start()
*
* @example <caption>When you say anything in a room, it will change room topic. </caption>
* const bot = Wechaty.instance()
* const bot = new Wechaty()
* bot
* .on('message', async m => {
* const room = m.room()
* if (room) {
* const oldTopic = room.topic()
* room.topic('change topic to wechaty!')
* const oldTopic = await room.topic()
* await room.topic('change topic to wechaty!')
* console.log(`room topic change from ${oldTopic} to ${room.topic()}`)
* }
* })
* .start()
*/
public async topic(newTopic?: string): Promise<void | string> {
log.verbose('Room', 'topic(%s)', newTopic ? newTopic : '')
......@@ -594,6 +654,30 @@ export class Room extends Accessory implements Sayable {
public async announce() : Promise<string>
public async announce(text: string) : Promise<void>
/**
* SET/GET announce from the room
* > Tips: It only works when bot is the owner of the room.
*
* @param {string} [text] If set this para, it will change room announce.
* @returns {(Promise<void | string>)}
*
* @example <caption>When you say anything in a room, it will get room announce. </caption>
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const room = await bot.Room.find({topic: 'your room'})
* const announce = await room.announce()
* console.log(`room announce is : ${announce}`)
*
* @example <caption>When you say anything in a room, it will change room announce. </caption>
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const room = await bot.Room.find({topic: 'your room'})
* const oldAnnounce = await room.announce()
* await room.announce('change announce to wechaty!')
* console.log(`room announce change from ${oldAnnounce} to ${room.announce()}`)
*/
public async announce(text?: string): Promise<void | string> {
log.verbose('Room', 'announce(%s)', text ? text : '')
......@@ -605,7 +689,9 @@ export class Room extends Accessory implements Sayable {
}
/**
* Room QR Code
* Get QR Code of the Room from the room, which can be used as scan and join the room.
*
* @returns {Promise<string>}
*/
public async qrcode(): Promise<string> {
log.verbose('Room', 'qrcode()')
......@@ -616,18 +702,19 @@ export class Room extends Accessory implements Sayable {
/**
* Return contact's roomAlias in the room, the same as roomAlias
* @param {Contact} contact
* @returns {string | null} - If a contact has an alias in room, return string, otherwise return null
* @returns {Promise<string | null>} - If a contact has an alias in room, return string, otherwise return null
* @example
* const bot = Wechaty.instance()
* const bot = new Wechaty()
* bot
* .on('message', async m => {
* const room = m.room()
* const contact = m.from()
* if (room) {
* const alias = room.alias(contact)
* const alias = await room.alias(contact)
* console.log(`${contact.name()} alias is ${alias}`)
* }
* })
* .start()
*/
public async alias(contact: Contact): Promise<null | string> {
return this.roomAlias(contact)
......@@ -636,7 +723,7 @@ export class Room extends Accessory implements Sayable {
/**
* Same as function alias
* @param {Contact} contact
* @returns {(string | null)}
* @returns {Promise<string | null>}
*/
public async roomAlias(contact: Contact): Promise<null | string> {
......@@ -653,15 +740,18 @@ export class Room extends Accessory implements Sayable {
* Check if the room has member `contact`, the return is a Promise and must be `await`-ed
*
* @param {Contact} contact
* @returns {boolean} Return `true` if has contact, else return `false`.
* @returns {Promise<boolean>} Return `true` if has contact, else return `false`.
* @example <caption>Check whether 'lijiarui' is in the room 'wechaty'</caption>
* const contact = await Contact.find({name: 'lijiarui'}) // change 'lijiarui' to any of contact in your wechat
* const room = await Room.find({topic: 'wechaty'}) // change 'wechaty' to any of the room in your wechat
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const contact = await bot.Contact.find({name: 'lijiarui'}) // change 'lijiarui' to any of contact in your wechat
* const room = await bot.Room.find({topic: 'wechaty'}) // change 'wechaty' to any of the room in your wechat
* if (contact && room) {
* if (await room.has(contact)) {
* console.log(`${contact.name()} is in the room ${room.topic()}!`)
* console.log(`${contact.name()} is in the room wechaty!`)
* } else {
* console.log(`${contact.name()} is not in the room ${room.topic()} !`)
* console.log(`${contact.name()} is not in the room wechaty!`)
* }
* }
*/
......@@ -683,7 +773,7 @@ export class Room extends Accessory implements Sayable {
/**
* The way to search member by Room.member()
*
* @typedef MemberQueryFilter
* @typedef RoomMemberQueryFilter
* @property {string} name -Find the contact by wechat name in a room, equal to `Contact.name()`.
* @property {string} roomAlias -Find the contact by alias set by the bot for others in a room.
* @property {string} contactAlias -Find the contact by alias set by the contact out of a room, equal to `Contact.alias()`.
......@@ -698,8 +788,7 @@ export class Room extends Accessory implements Sayable {
* - `roomAlias` the name-string set by user-self in the room, should be called roomAlias
* - `contactAlias` the name-string set by bot for others, should be called alias, equal to `Contact.alias()`
* @param {(RoomMemberQueryFilter | string)} query -When use memberAll(name:string), return all matched members, including name, roomAlias, contactAlias
* @returns {Contact[]}
* @memberof Room
* @returns {Promise<Contact[]>}
*/
public async memberAll(
query: string | RoomMemberQueryFilter,
......@@ -721,27 +810,33 @@ export class Room extends Accessory implements Sayable {
* Find all contacts in a room, if get many, return the first one.
*
* @param {(RoomMemberQueryFilter | string)} queryArg -When use member(name:string), return all matched members, including name, roomAlias, contactAlias
* @returns {(Contact | null)}
* @returns {Promise<null | Contact>}
*
* @example <caption>Find member by name</caption>
* const room = await Room.find({topic: 'wechaty'}) // change 'wechaty' to any room name in your wechat
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const room = await bot.Room.find({topic: 'wechaty'}) // change 'wechaty' to any room name in your wechat
* if (room) {
* const member = room.member('lijiarui') // change 'lijiarui' to any room member in your wechat
* const member = await room.member('lijiarui') // change 'lijiarui' to any room member in your wechat
* if (member) {
* console.log(`${room.topic()} got the member: ${member.name()}`)
* console.log(`wechaty room got the member: ${member.name()}`)
* } else {
* console.log(`cannot get member in room: ${room.topic()}`)
* console.log(`cannot get member in wechaty room!`)
* }
* }
*
* @example <caption>Find member by MemberQueryFilter</caption>
* const room = await Room.find({topic: 'wechaty'}) // change 'wechaty' to any room name in your wechat
* const bot = new Wechaty()
* await bot.start()
* // after logged in...
* const room = await bot.Room.find({topic: 'wechaty'}) // change 'wechaty' to any room name in your wechat
* if (room) {
* const member = room.member({name: 'lijiarui'}) // change 'lijiarui' to any room member in your wechat
* const member = await room.member({name: 'lijiarui'}) // change 'lijiarui' to any room member in your wechat
* if (member) {
* console.log(`${room.topic()} got the member: ${member.name()}`)
* console.log(`wechaty room got the member: ${member.name()}`)
* } else {
* console.log(`cannot get member in room: ${room.topic()}`)
* console.log(`cannot get member in wechaty room!`)
* }
* }
*/
......@@ -772,7 +867,9 @@ export class Room extends Accessory implements Sayable {
/**
* Get all room member from the room
*
* @returns {Contact[]}
* @returns {Promise<Contact[]>}
* @example
* await room.memberList()
*/
public async memberList(): Promise<Contact[]> {
log.verbose('Room', 'memberList()')
......@@ -791,29 +888,29 @@ export class Room extends Accessory implements Sayable {
}
/**
* Force reload data for Room
* @private
* @deprecated use sync() instead
* @returns {Promise<void>}
* @ignore
*/
public async refresh(): Promise<void> {
return this.sync()
}
/**
* Sync data for Room
* Force reload data for Room, Sync data for Room
*
* @returns {Promise<void>}
* @example
* await room.sync()
*/
public async sync(): Promise<void> {
await this.ready(true)
}
/**
* @private
* Get room's owner from the room.
* Not recommend, because cannot always get the owner
*
* @returns {(Contact | null)}
* @example
* const owner = room.owner()
*/
public owner(): Contact | null {
log.info('Room', 'owner()')
......
......@@ -108,12 +108,25 @@ export interface WechatyOptions {
/**
* Main bot class.
*
* [The World's Shortest ChatBot Code: 6 lines of JavaScript]{@link #wechatyinstance}
* A `Bot` is a wechat client depends on which puppet you use.
* It may equals
* - web-wechat, when you use: [puppet-puppeteer](https://github.com/chatie/wechaty-puppet-puppeteer)/[puppet-wechat4u](https://github.com/chatie/wechaty-puppet-wechat4u)
* - ipad-wechat, when you use: [puppet-padchat](https://github.com/lijiarui/wechaty-puppet-padchat)
* - ios-wechat, when you use: puppet-ioscat
*
* [Wechaty Starter Project]{@link https://github.com/lijiarui/wechaty-getting-started}
* @example
* import { Wechaty } from 'wechaty'
* See more:
* - [What is a Puppet in Wechaty](https://github.com/Chatie/wechaty-getting-started/wiki/FAQ-EN#31-what-is-a-puppet-in-wechaty)
*
* > If you want to know how to send message, see [Message](#Message) <br>
* > If you want to know how to get contact, see [Contact](#Contact)
*
* @example <caption>The World's Shortest ChatBot Code: 6 lines of JavaScript</caption>
* const { Wechaty } = require('wechaty')
* const bot = new Wechaty()
* bot.on('scan', (qrcode, status) => console.log(['https://api.qrserver.com/v1/create-qr-code/?data=',encodeURIComponent(qrcode),'&size=220x220&margin=20',].join('')))
* bot.on('login', user => console.log(`User ${user} logined`))
* bot.on('message', message => console.log(`Message: ${message}`))
* bot.start()
*/
export class Wechaty extends Accessory implements Sayable {
......@@ -169,6 +182,8 @@ export class Wechaty extends Accessory implements Sayable {
/**
* get the singleton instance of Wechaty
*
* @param {WechatyOptions} [options={}]
*
* @example <caption>The World's Shortest ChatBot Code: 6 lines of JavaScript</caption>
* const { Wechaty } = require('wechaty')
*
......@@ -176,7 +191,7 @@ export class Wechaty extends Accessory implements Sayable {
* .on('scan', (url, code) => console.log(`Scan QR Code to login: ${code}\n${url}`))
* .on('login', user => console.log(`User ${user} logined`))
* .on('message', message => console.log(`Message: ${message}`))
* .init()
* .start()
*/
public static instance(
options?: WechatyOptions,
......@@ -191,7 +206,44 @@ export class Wechaty extends Accessory implements Sayable {
}
/**
* @public
* The term [Puppet](https://github.com/Chatie/wechaty/wiki/Puppet) in Wechaty is an Abstract Class for implementing protocol plugins.
* The plugins are the component that helps Wechaty to control the Wechat(that's the reason we call it puppet).
* The plugins are named XXXPuppet, for example:
* - [PuppetPuppeteer](https://github.com/Chatie/wechaty-puppet-puppeteer):
* - [PuppetPadchat](https://github.com/lijiarui/wechaty-puppet-padchat)
*
* @typedef PuppetName
* @property {string} wechat4u
* The default puppet, using the [wechat4u](https://github.com/nodeWechat/wechat4u) to control the [WeChat Web API](https://wx.qq.com/) via a chrome browser.
* @property {string} padchat
* - Using the WebSocket protocol to connect with a Protocol Server for controlling the iPad Wechat program.
* @property {string} puppeteer
* - Using the [google puppeteer](https://github.com/GoogleChrome/puppeteer) to control the [WeChat Web API](https://wx.qq.com/) via a chrome browser.
* @property {string} mock
* - Using the mock data to mock wechat operation, just for test.
*/
/**
* The option parameter to create a wechaty instance
*
* @typedef WechatyOptions
* @property {string} profile -Wechaty Name. </br>
* When you set this: </br>
* `new Wechaty({profile: 'wechatyName'}) ` </br>
* it will generate a file called `wechatyName.memory-card.json`. </br>
* This file stores the bot's login information. </br>
* If the file is valid, the bot can auto login so you don't need to scan the qrcode to login again. </br>
* Also, you can set the environment variable for `WECHATY_PROFILE` to set this value when you start. </br>
* eg: `WECHATY_PROFILE="your-cute-bot-name" node bot.js`
* @property {PuppetName | Puppet} puppet -Puppet name or instance
* @property {Partial<PuppetOptions>} puppetOptions -Puppet TOKEN
* @property {string} ioToken -Io TOKEN
*/
/**
* Creates an instance of Wechaty.
* @param {WechatyOptions} [options={}]
*
*/
constructor(
private options: WechatyOptions = {},
......@@ -208,6 +260,7 @@ export class Wechaty extends Accessory implements Sayable {
this.id = cuid()
/**
* @ignore
* Clone Classes for this bot and attach the `puppet` to the Class
*
* https://stackoverflow.com/questions/36886082/abstract-constructor-type-in-typescript
......@@ -238,33 +291,6 @@ export class Wechaty extends Accessory implements Sayable {
].join('')
}
/**
* @private
*/
public static version(forceNpm = false): string {
if (!forceNpm) {
const revision = config.gitRevision()
if (revision) {
return `#git[${revision}]`
}
}
return VERSION
}
/**
* Return version of Wechaty
*
* @param {boolean} [forceNpm=false] - if set to true, will only return the version in package.json.
* otherwise will return git commit hash if .git exists.
* @returns {string} - the version number
* @example
* console.log(Wechaty.instance().version()) // return '#git[af39df]'
* console.log(Wechaty.instance().version(true)) // return '0.7.9'
*/
public version(forceNpm = false): string {
return Wechaty.version(forceNpm)
}
public emit(event: 'dong' , data?: string) : boolean
public emit(event: 'error' , error: Error) : boolean
public emit(event: 'friendship' , friendship: Friendship) : boolean
......@@ -319,7 +345,8 @@ export class Wechaty extends Accessory implements Sayable {
* @property {string} room-topic - Get topic event, emitted when someone change room topic.
* @property {string} room-leave - Emit when anyone leave the room.<br>
* If someone leaves the room by themselves, wechat will not notice other people in the room, so the bot will never get the "leave" event.
* @property {string} scan - A scan event will be emitted when the bot needs to show you a QR Code for scanning.
* @property {string} scan - A scan event will be emitted when the bot needs to show you a QR Code for scanning. </br>
* It is recommend to install qrcode-terminal(run `npm install qrcode-terminal`) in order to show qrcode in the terminal.
*/
/**
......@@ -351,31 +378,53 @@ export class Wechaty extends Accessory implements Sayable {
* @listens Wechaty
* @param {WechatyEventName} event - Emit WechatyEvent
* @param {WechatyEventFunction} listener - Depends on the WechatyEvent
* @return {Wechaty} - this for chain
*
* More Example Gist: [Examples/Friend-Bot]{@link https://github.com/Chatie/wechaty/blob/master/examples/friend-bot.ts}
* @return {Wechaty} - this for chaining,
* see advanced {@link https://github.com/Chatie/wechaty-getting-started/wiki/FAQ-EN#36-why-wechatyonevent-listener-return-wechaty|chaining usage}
*
* @desc
* When the bot get message, it will emit the following Event.
*
* @example <caption>Event:scan </caption>
* wechaty.on('scan', (url: string, code: number) => {
* You can do anything you want when in these events functions.
* The main Event name as follows:
* - **scan**: Emit when the bot needs to show you a QR Code for scanning. After scan the qrcode, you can login
* - **login**: Emit when bot login full successful.
* - **logout**: Emit when bot detected log out.
* - **message**: Emit when there's a new message.
*
* see more in {@link WechatyEventName}
*
* @example <caption>Event:scan</caption>
* # Scan Event will emit when the bot needs to show you a QR Code for scanning
*
* bot.on('scan', (url: string, code: number) => {
* console.log(`[${code}] Scan ${url} to login.` )
* })
*
* @example <caption>Event:login </caption>
* # Login Event will emit when bot login full successful.
*
* bot.on('login', (user: ContactSelf) => {
* console.log(`user ${user} login`)
* })
*
* @example <caption>Event:logout </caption>
* # Logout Event will emit when bot detected log out.
*
* bot.on('logout', (user: ContactSelf) => {
* console.log(`user ${user} logout`)
* })
*
* @example <caption>Event:message </caption>
* # Message Event will emit when there's a new message.
*
* wechaty.on('message', (message: Message) => {
* console.log(`message ${message} received`)
* })
*
* @example <caption>Event:friendship </caption>
* # Friendship Event will emit when got a new friend request, or friendship is confirmed.
*
* bot.on('friendship', (friendship: Friendship) => {
* if(friendship.type() === Friendship.Type.RECEIVE){ // 1. receive new friendship request from new contact
* const contact = friendship.contact()
......@@ -391,21 +440,34 @@ export class Wechaty extends Accessory implements Sayable {
* })
*
* @example <caption>Event:room-join </caption>
* # room-join Event will emit when someone join the room.
*
* bot.on('room-join', (room: Room, inviteeList: Contact[], inviter: Contact) => {
* const nameList = inviteeList.map(c => c.name()).join(',')
* console.log(`Room ${room.topic()} got new member ${nameList}, invited by ${inviter}`)
* })
*
* @example <caption>Event:room-leave </caption>
* # room-leave Event will emit when someone leave the room.
*
* bot.on('room-leave', (room: Room, leaverList: Contact[]) => {
* const nameList = leaverList.map(c => c.name()).join(',')
* console.log(`Room ${room.topic()} lost member ${nameList}`)
* })
*
* @example <caption>Event:room-topic </caption>
* # room-topic Event will emit when someone change the room's topic.
*
* bot.on('room-topic', (room: Room, topic: string, oldTopic: string, changer: Contact) => {
* console.log(`Room ${room.topic()} topic changed from ${oldTopic} to ${topic} by ${changer.name()}`)
* })
*
* @example <caption>Event:error </caption>
* # error Event will emit when there's an error occurred.
*
* bot.on('error', (error) => {
* console.error(error)
* })
*/
public on(event: WechatyEventName, listener: string | ((...args: any[]) => any)): this {
log.verbose('Wechaty', 'on(%s, %s) registered',
......@@ -765,7 +827,9 @@ export class Wechaty extends Accessory implements Sayable {
}
/**
* @deprecated use start() instead
* @desc
* use {@link Wechaty#start} instead
* @deprecated
*/
public async init(): Promise<void> {
log.warn('Wechaty', 'init() DEPRECATED. use start() instead.')
......@@ -775,6 +839,9 @@ export class Wechaty extends Accessory implements Sayable {
* Start the bot, return Promise.
*
* @returns {Promise<void>}
* @description
* When you start the bot, bot will begin to login, need you wechat scan qrcode to login
* > Tips: All the bot operation needs to be triggered after start() is done
* @example
* await bot.start()
* // do other stuff with bot here
......@@ -938,6 +1005,8 @@ export class Wechaty extends Accessory implements Sayable {
}
/**
* @description
* Should use {@link Wechaty#userSelf} instead
* @deprecated
*/
public self(): Contact {
......@@ -960,10 +1029,33 @@ export class Wechaty extends Accessory implements Sayable {
}
/**
* Send message to userSelf
* Send message to userSelf, in other words, bot send message to itself.
* @param {(string | Contact | FileBox)} textOrContactOrFile
* send text, Contact, or file to bot. </br>
* You can use {@link https://www.npmjs.com/package/file-box|FileBox} to send file
* @returns {Promise<void>}
*
* @param {string} textOrContactOrFile
* @returns {Promise<boolean>}
* @example
* const bot = new Wechaty()
* await bot.start()
* // after logged in
*
* # 1. send text to bot itself
* await bot.say('hello!')
*
* # 2. send Contact to bot itself
* const contact = bot.Contact.load('contactId')
* await bot.say(contact)
*
* # 3. send Image to bot itself from remote url
* import { FileBox } from 'file-box'
* const fileBox = FileBox.fromUrl('https://chatie.io/wechaty/images/bot-qr-code.png')
* await bot.say(fileBox)
*
* # 4. send Image to bot itself from local file
* import { FileBox } from 'file-box'
* const fileBox = FileBox.fromLocal('/tmp/text.jpg')
* await bot.say(fileBox)
*/
public async say(textOrContactOrFile: string | Contact | FileBox): Promise<void> {
log.verbose('Wechaty', 'say(%s)', textOrContactOrFile)
......@@ -980,6 +1072,33 @@ export class Wechaty extends Accessory implements Sayable {
}
}
/**
* @private
*/
public static version(forceNpm = false): string {
if (!forceNpm) {
const revision = config.gitRevision()
if (revision) {
return `#git[${revision}]`
}
}
return VERSION
}
/**
* Return version of Wechaty
*
* @param {boolean} [forceNpm=false] - If set to true, will only return the version in package.json. </br>
* Otherwise will return git commit hash if .git exists.
* @returns {string} - the version number
* @example
* console.log(Wechaty.instance().version()) // return '#git[af39df]'
* console.log(Wechaty.instance().version(true)) // return '0.7.9'
*/
public version(forceNpm = false): string {
return Wechaty.version(forceNpm)
}
/**
* @private
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册