diff --git a/README.md b/README.md index b6536a54c3d610ef9e80d6cb27f4afe6fcbe92c6..b9cc8901774db9dff7b567e76a76ac744a466b47 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Wechaty.instance() // Global Instance .start() ``` -> **Notice: Wechaty requires Node.js version >= 8.5** +> **Notice: Wechaty requires Node.js version >= 10** This bot can log all messages to the console. @@ -56,12 +56,11 @@ You can find more examples from [Wiki](https://github.com/chatie/wechaty/wiki/Ex ## GETTING STARTED [![node](https://img.shields.io/node/v/wechaty.svg?maxAge=604800)](https://nodejs.org/) -[![Repo Size](https://reposs.herokuapp.com/?path=Chatie/wechaty)](https://github.com/chatie/wechaty) ### A Great Live Coding Tutorial
The above 15 minute video tutorial is a good start point if you are new to Wechaty. diff --git a/docs/index.md b/docs/index.md index 9fa182fe028b8f4fb42f3ae15fc920f9169f1a15..3854c29f18134a4c803c510c53a7e69b65a10a24 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,4 @@ -# Wechaty v0.15.26 Documentation -* https://blog.chatie.io - +# Wechaty v0.17.59 Documentation\n* https://blog.chatie.io\n ## ClassesThe World's Shortest ChatBot Code: 6 lines of JavaScript
+All wechat rooms(groups) will be encapsulated as a Room.
+Room
is Sayable
,
+Examples/Room-Bot
All wechat contacts(friend) will be encapsulated as a Contact.
+Contact
is Sayable
,
+Examples/Contact-Bot
Send, receive friend request, and friend confirmation events.
+All wechat messages will be encapsulated as a Message.
+Message
is Sayable
,
+Examples/Ding-Dong-Bot
Wechaty Class Event Function
Room Class Event Type
+Room Class Event Function
+The way to search member by Room.member()
+The way to search Contact
+string
* [.on(event, listener)](#Wechaty+on) ⇒ [Wechaty
](#Wechaty)
* [.start()](#Wechaty+start) ⇒ Promise.<void>
@@ -43,8 +79,8 @@ Main bot class.
* [.logout()](#Wechaty+logout) ⇒ Promise.<void>
* [.logonoff()](#Wechaty+logonoff) ⇒ boolean
* ~~[.self()](#Wechaty+self)~~
- * [.userSelf()](#Wechaty+userSelf) ⇒ Contact
- * [.say(text)](#Wechaty+say) ⇒ Promise.<boolean>
+ * [.userSelf()](#Wechaty+userSelf) ⇒ [Contact
](#Contact)
+ * [.say(textOrContactOrFile)](#Wechaty+say) ⇒ Promise.<boolean>
* _static_
* [.instance()](#Wechaty.instance)
@@ -53,12 +89,28 @@ Main bot class.
### wechaty.Contact
Clone Classes for this bot and attach the `puppet` to the Class
-Fixme:
https://stackoverflow.com/questions/36886082/abstract-constructor-type-in-typescript
https://github.com/Microsoft/TypeScript/issues/5843#issuecomment-290972055
https://github.com/Microsoft/TypeScript/issues/19197
**Kind**: instance property of [Wechaty
](#Wechaty)
+
+* [.Contact](#Wechaty+Contact)
+ * [.wechaty](#Wechaty+Contact.wechaty)
+ * [.puppet](#Wechaty+Contact.puppet)
+
+
+
+#### Contact.wechaty
+1. Set Wechaty
+
+**Kind**: static property of [Contact
](#Wechaty+Contact)
+
+
+#### Contact.puppet
+2. Set Puppet
+
+**Kind**: static property of [Contact
](#Wechaty+Contact)
### wechaty.version([forceNpm]) ⇒ string
@@ -97,13 +149,13 @@ wechaty.on('scan', (url: string, code: number) => {
```
**Example** *(Event:login )*
```js
-bot.on('login', (user: Contact) => {
+bot.on('login', (user: ContactSelf) => {
console.log(`user ${user} login`)
})
```
**Example** *(Event:logout )*
```js
-bot.on('logout', (user: Contact) => {
+bot.on('logout', (user: ContactSelf) => {
console.log(`user ${user} logout`)
})
```
@@ -115,15 +167,16 @@ wechaty.on('message', (message: Message) => {
```
**Example** *(Event:friend )*
```js
-bot.on('friend', (contact: Contact, request: FriendRequest) => {
- if(request){ // 1. request to be friend from new contact
+bot.on('friend', (request: Friendship) => {
+ if(request.type === Friendship.Type.RECEIVE){ // 1. receive new friend request from new contact
+ const contact = request.contact()
let result = await request.accept()
if(result){
console.log(`Request from ${contact.name()} is accept succesfully!`)
} else{
console.log(`Request from ${contact.name()} failed to accept!`)
}
- } else { // 2. confirm friend ship
+ } else if (request.type === Friendship.Type.CONFIRM) { // 2. confirm friend ship
console.log(`new friendship confirmed with ${contact.name()}`)
}
})
@@ -201,7 +254,7 @@ if (bot.logonoff()) {
**Kind**: instance method of [Wechaty
](#Wechaty)
-### wechaty.userSelf() ⇒ Contact
+### wechaty.userSelf() ⇒ [Contact
](#Contact)
Get current user
**Kind**: instance method of [Wechaty
](#Wechaty)
@@ -212,14 +265,14 @@ console.log(`Bot is ${contact.name()}`)
```
-### wechaty.say(text) ⇒ Promise.<boolean>
-Send message to filehelper
+### wechaty.say(textOrContactOrFile) ⇒ Promise.<boolean>
+Send message to userSelf
**Kind**: instance method of [Wechaty
](#Wechaty)
| Param | Type |
| --- | --- |
-| text | string
|
+| textOrContactOrFile | string
|
@@ -237,63 +290,905 @@ Wechaty.instance() // Singleton
.on('message', message => console.log(`Message: ${message}`))
.init()
```
-
+
-## AppMsgType : enum
-Enum for AppMsgType values.
+## Room
+All wechat rooms(groups) will be encapsulated as a Room.
-**Kind**: global enum
-**Properties**
+`Room` is `Sayable`,
+[Examples/Room-Bot](https://github.com/Chatie/wechaty/blob/master/examples/room-bot.ts)
-| Name | Type | Description |
+**Kind**: global class
+
+* [Room](#Room)
+ * _instance_
+ * [.say(textOrContactOrFile, [replyTo])](#Room+say) ⇒ Promise.<boolean>
+ * [.on(event, listener)](#Room+on) ⇒ this
+ * [.add(contact)](#Room+add) ⇒ Promise.<number>
+ * [.del(contact)](#Room+del) ⇒ Promise.<number>
+ * [.topic([newTopic])](#Room+topic) ⇒ Promise.<(string\|void)>
+ * [.qrcode()](#Room+qrcode)
+ * [.alias(contact)](#Room+alias) ⇒ string
\| null
+ * [.roomAlias(contact)](#Room+roomAlias) ⇒ string
\| null
+ * [.has(contact)](#Room+has) ⇒ boolean
+ * [.memberAll(query)](#Room+memberAll) ⇒ [Array.<Contact>
](#Contact)
+ * [.member(queryArg)](#Room+member) ⇒ [Contact
](#Contact) \| null
+ * [.memberList()](#Room+memberList) ⇒ [Array.<Contact>
](#Contact)
+ * [.sync()](#Room+sync) ⇒ Promise.<void>
+ * _static_
+ * [.create(contactList, [topic])](#Room.create) ⇒ [Promise.<Room>
](#Room)
+ * [.findAll([query])](#Room.findAll) ⇒ Promise.<Array.<Room>>
+ * [.find(query)](#Room.find) ⇒ Promise.<(Room\|null)>
+
+
+
+### room.say(textOrContactOrFile, [replyTo]) ⇒ Promise.<boolean>
+Send message inside Room, if set [replyTo], wechaty will mention the contact as well.
+
+**Kind**: instance method of [Room
](#Room)
+**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 | Type | Description |
| --- | --- | --- |
-| TEXT | number
| AppMsgType.TEXT (1) for TEXT |
-| IMG | number
| AppMsgType.IMG (2) for IMG |
-| AUDIO | number
| AppMsgType.AUDIO (3) for AUDIO |
-| VIDEO | number
| AppMsgType.VIDEO (4) for VIDEO |
-| URL | number
| AppMsgType.URL (5) for URL |
-| ATTACH | number
| AppMsgType.ATTACH (6) for ATTACH |
-| OPEN | number
| AppMsgType.OPEN (7) for OPEN |
-| EMOJI | number
| AppMsgType.EMOJI (8) for EMOJI |
-| VOICE_REMIND | number
| AppMsgType.VOICE_REMIND (9) for VOICE_REMIND |
-| SCAN_GOOD | number
| AppMsgType.SCAN_GOOD (10) for SCAN_GOOD |
-| GOOD | number
| AppMsgType.GOOD (13) for GOOD |
-| EMOTION | number
| AppMsgType.EMOTION (15) for EMOTION |
-| CARD_TICKET | number
| AppMsgType.CARD_TICKET (16) for CARD_TICKET |
-| REALTIME_SHARE_LOCATION | number
| AppMsgType.REALTIME_SHARE_LOCATION (17) for REALTIME_SHARE_LOCATION |
-| TRANSFERS | number
| AppMsgType.TRANSFERS (2e3) for TRANSFERS |
-| RED_ENVELOPES | number
| AppMsgType.RED_ENVELOPES (2001) for RED_ENVELOPES |
-| READER_TYPE | number
| AppMsgType.READER_TYPE (100001) for READER_TYPE |
-
-
-
-## MsgType : enum
-Enum for MsgType values.
-
-**Kind**: global enum
-**Properties**
+| textOrContactOrFile | string
\| MediaMessage
| Send `text` or `media file` inside Room. |
+| [replyTo] | [Contact
](#Contact) \| [Array.<Contact>
](#Contact) | Optional parameter, send content inside Room, and mention @replyTo contact or contactList. |
-| Name | Type | Description |
+**Example** *(Send text inside Room)*
+```js
+const room = await Room.find({name: 'wechaty'}) // change 'wechaty' to any of your room in wechat
+await room.say('Hello world!')
+```
+**Example** *(Send media file inside Room)*
+```js
+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
+```
+**Example** *(Send text inside Room, and mention @replyTo contact)*
+```js
+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
+await room.say('Hello world!', contact)
+```
+
+
+### room.on(event, listener) ⇒ this
+**Kind**: instance method of [Room
](#Room)
+**Returns**: this
- - this for chain
+
+| Param | Type | Description |
| --- | --- | --- |
-| TEXT | number
| MsgType.TEXT (1) for TEXT |
-| IMAGE | number
| MsgType.IMAGE (3) for IMAGE |
-| VOICE | number
| MsgType.VOICE (34) for VOICE |
-| VERIFYMSG | number
| MsgType.VERIFYMSG (37) for VERIFYMSG |
-| POSSIBLEFRIEND_MSG | number
| MsgType.POSSIBLEFRIEND_MSG (40) for POSSIBLEFRIEND_MSG |
-| SHARECARD | number
| MsgType.SHARECARD (42) for SHARECARD |
-| VIDEO | number
| MsgType.VIDEO (43) for VIDEO |
-| EMOTICON | number
| MsgType.EMOTICON (47) for EMOTICON |
-| LOCATION | number
| MsgType.LOCATION (48) for LOCATION |
-| APP | number
| MsgType.APP (49) for APP |
-| VOIPMSG | number
| MsgType.VOIPMSG (50) for VOIPMSG |
-| STATUSNOTIFY | number
| MsgType.STATUSNOTIFY (51) for STATUSNOTIFY |
-| VOIPNOTIFY | number
| MsgType.VOIPNOTIFY (52) for VOIPNOTIFY |
-| VOIPINVITE | number
| MsgType.VOIPINVITE (53) for VOIPINVITE |
-| MICROVIDEO | number
| MsgType.MICROVIDEO (62) for MICROVIDEO |
-| SYSNOTICE | number
| MsgType.SYSNOTICE (9999) for SYSNOTICE |
-| SYS | number
| MsgType.SYS (10000) for SYS |
-| RECALLED | number
| MsgType.RECALLED (10002) for RECALLED |
+| event | [RoomEventName
](#RoomEventName) | Emit WechatyEvent |
+| listener | [RoomEventFunction
](#RoomEventFunction) | Depends on the WechatyEvent |
+
+**Example** *(Event:join )*
+```js
+const room = await Room.find({topic: 'event-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}`)
+ })
+}
+```
+**Example** *(Event:leave )*
+```js
+const room = await Room.find({topic: 'event-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}`)
+ })
+}
+```
+**Example** *(Event:topic )*
+```js
+const room = await Room.find({topic: 'event-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()}`)
+ })
+}
+```
+
+
+### room.add(contact) ⇒ Promise.<number>
+Add contact in a room
+
+**Kind**: instance method of [Room
](#Room)
+
+| Param | Type |
+| --- | --- |
+| contact | [Contact
](#Contact) |
+
+**Example**
+```js
+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
+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()}! `)
+ }
+}
+```
+
+
+### room.del(contact) ⇒ Promise.<number>
+Delete a contact from the room
+It works only when the bot is the owner of the room
+
+**Kind**: instance method of [Room
](#Room)
+
+| Param | Type |
+| --- | --- |
+| contact | [Contact
](#Contact) |
+
+**Example**
+```js
+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
+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()}! `)
+ }
+}
+```
+
+
+### room.topic([newTopic]) ⇒ Promise.<(string\|void)>
+SET/GET topic from the room
+
+**Kind**: instance method of [Room
](#Room)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| [newTopic] | string
| If set this para, it will change room topic. |
+
+**Example** *(When you say anything in a room, it will get room topic. )*
+```js
+const bot = Wechaty.instance()
+bot
+.on('message', async m => {
+ const room = m.room()
+ if (room) {
+ const topic = await room.topic()
+ console.log(`room topic is : ${topic}`)
+ }
+})
+```
+**Example** *(When you say anything in a room, it will change room topic. )*
+```js
+const bot = Wechaty.instance()
+bot
+.on('message', async m => {
+ const room = m.room()
+ if (room) {
+ const oldTopic = room.topic()
+ room.topic('change topic to wechaty!')
+ console.log(`room topic change from ${oldTopic} to ${room.topic()}`)
+ }
+})
+```
+
+
+### room.qrcode()
+Room QR Code
+
+**Kind**: instance method of [Room
](#Room)
+
+
+### room.alias(contact) ⇒ string
\| null
+Return contact's roomAlias in the room, the same as roomAlias
+
+**Kind**: instance method of [Room
](#Room)
+**Returns**: string
\| null
- - If a contact has an alias in room, return string, otherwise return null
+
+| Param | Type |
+| --- | --- |
+| contact | [Contact
](#Contact) |
+
+**Example**
+```js
+const bot = Wechaty.instance()
+bot
+.on('message', async m => {
+ const room = m.room()
+ const contact = m.from()
+ if (room) {
+ const alias = room.alias(contact)
+ console.log(`${contact.name()} alias is ${alias}`)
+ }
+})
+```
+
+
+### room.roomAlias(contact) ⇒ string
\| null
+Same as function alias
+
+**Kind**: instance method of [Room
](#Room)
+
+| Param | Type |
+| --- | --- |
+| contact | [Contact
](#Contact) |
+
+
+
+### room.has(contact) ⇒ boolean
+Check if the room has member `contact`, the return is a Promise and must be `await`-ed
+
+**Kind**: instance method of [Room
](#Room)
+**Returns**: boolean
- Return `true` if has contact, else return `false`.
+
+| Param | Type |
+| --- | --- |
+| contact | [Contact
](#Contact) |
+
+**Example** *(Check whether 'lijiarui' is in the room 'wechaty')*
+```js
+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
+if (contact && room) {
+ if (await room.has(contact)) {
+ console.log(`${contact.name()} is in the room ${room.topic()}!`)
+ } else {
+ console.log(`${contact.name()} is not in the room ${room.topic()} !`)
+ }
+}
+```
+
+
+### room.memberAll(query) ⇒ [Array.<Contact>
](#Contact)
+Find all contacts in a room
+
+#### definition
+- `name` the name-string set by user-self, should be called name, equal to `Contact.name()`
+- `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()`
+
+**Kind**: instance method of [Room
](#Room)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| query | RoomMemberQueryFilter
\| string
| When use memberAll(name:string), return all matched members, including name, roomAlias, contactAlias |
+
+
+
+### room.member(queryArg) ⇒ [Contact
](#Contact) \| null
+Find all contacts in a room, if get many, return the first one.
+
+**Kind**: instance method of [Room
](#Room)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| queryArg | RoomMemberQueryFilter
\| string
| When use member(name:string), return all matched members, including name, roomAlias, contactAlias |
+
+**Example** *(Find member by name)*
+```js
+const room = await 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
+ if (member) {
+ console.log(`${room.topic()} got the member: ${member.name()}`)
+ } else {
+ console.log(`cannot get member in room: ${room.topic()}`)
+ }
+}
+```
+**Example** *(Find member by MemberQueryFilter)*
+```js
+const room = await 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
+ if (member) {
+ console.log(`${room.topic()} got the member: ${member.name()}`)
+ } else {
+ console.log(`cannot get member in room: ${room.topic()}`)
+ }
+}
+```
+
+
+### room.memberList() ⇒ [Array.<Contact>
](#Contact)
+Get all room member from the room
+
+**Kind**: instance method of [Room
](#Room)
+
+
+### room.sync() ⇒ Promise.<void>
+Sync data for Room
+
+**Kind**: instance method of [Room
](#Room)
+
+
+### Room.create(contactList, [topic]) ⇒ [Promise.<Room>
](#Room)
+Create a new room.
+
+**Kind**: static method of [Room
](#Room)
+
+| Param | Type |
+| --- | --- |
+| contactList | [Array.<Contact>
](#Contact) |
+| [topic] | string
|
+
+**Example** *(Creat a room with 'lijiarui' and 'juxiaomi', the room topic is 'ding - created')*
+```js
+const helperContactA = await Contact.find({ name: 'lijiarui' }) // change 'lijiarui' to any contact in your wechat
+const helperContactB = await Contact.find({ name: 'juxiaomi' }) // change 'juxiaomi' to any contact in your wechat
+const contactList = [helperContactA, helperContactB]
+console.log('Bot', 'contactList: %s', contactList.join(','))
+const room = await Room.create(contactList, 'ding')
+console.log('Bot', 'createDingRoom() new ding room created: %s', room)
+await room.topic('ding - created')
+await room.say('ding - created')
+```
+
+
+### Room.findAll([query]) ⇒ Promise.<Array.<Room>>
+Find room by topic, return all the matched room
+
+**Kind**: static method of [Room
](#Room)
+
+| Param | Type |
+| --- | --- |
+| [query] | RoomQueryFilter
|
+
+**Example**
+```js
+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'
+```
+
+
+### Room.find(query) ⇒ Promise.<(Room\|null)>
+Try to find a room by filter: {topic: string | RegExp}. If get many, return the first one.
+
+**Kind**: static method of [Room
](#Room)
+**Returns**: Promise.<(Room\|null)>
- If can find the room, return Room, or return null
+
+| Param | Type |
+| --- | --- |
+| query | RoomQueryFilter
|
+
+
+
+## Contact
+All wechat contacts(friend) will be encapsulated as a Contact.
+
+`Contact` is `Sayable`,
+[Examples/Contact-Bot](https://github.com/Chatie/wechaty/blob/master/examples/contact-bot.ts)
+
+**Kind**: global class
+
+* [Contact](#Contact)
+ * _instance_
+ * [.payload](#Contact+payload)
+ * [.name()](#Contact+name) ⇒ string
+ * [.alias(newAlias)](#Contact+alias) ⇒ string
\| null
\| Promise.<boolean>
+ * ~~[.stranger()](#Contact+stranger) ⇒ boolean
\| null
~~
+ * [.friend()](#Contact+friend) ⇒ boolean
\| null
+ * ~~[.official()](#Contact+official) ⇒ boolean
\| null
~~
+ * ~~[.personal()](#Contact+personal) ⇒ boolean
~~
+ * [.type()](#Contact+type) ⇒
+ * [.star()](#Contact+star) ⇒ boolean
\| null
+ * [.gender()](#Contact+gender) ⇒ ContactGender.Male(2)
\| Gender.Female(1)
\| Gender.Unknown(0)
+ * [.province()](#Contact+province) ⇒ string
\| null
+ * [.city()](#Contact+city) ⇒ string
\| null
+ * [.avatar()](#Contact+avatar) ⇒ Promise.<FileBox>
+ * ~~[.refresh()](#Contact+refresh) ⇒ Promise.<this>
~~
+ * [.sync()](#Contact+sync) ⇒ Promise.<this>
+ * [.self()](#Contact+self) ⇒ boolean
+ * _static_
+ * [.find(query)](#Contact.find) ⇒ Promise.<(Contact\|null)>
+ * [.findAll([queryArg])](#Contact.findAll) ⇒ Promise.<Array.<Contact>>
+
+
+
+### contact.payload
+Instance properties
+
+**Kind**: instance property of [Contact
](#Contact)
+
+
+### contact.name() ⇒ string
+Get the name from a contact
+
+**Kind**: instance method of [Contact
](#Contact)
+**Example**
+```js
+const name = contact.name()
+```
+
+
+### contact.alias(newAlias) ⇒ string
\| null
\| Promise.<boolean>
+GET / SET / DELETE the alias for a contact
+
+Tests show it will failed if set alias too frequently(60 times in one minute).
+
+**Kind**: instance method of [Contact
](#Contact)
+
+| Param | Type |
+| --- | --- |
+| newAlias | none
\| string
\| null
|
+
+**Example** *( GET the alias for a contact, return {(string | null)})*
+```js
+const alias = contact.alias()
+if (alias === null) {
+ console.log('You have not yet set any alias for contact ' + contact.name())
+} else {
+ console.log('You have already set an alias for contact ' + contact.name() + ':' + alias)
+}
+```
+**Example** *(SET the alias for a contact)*
+```js
+try {
+ await contact.alias('lijiarui')
+ console.log(`change ${contact.name()}'s alias successfully!`)
+} catch (e) {
+ console.log(`failed to change ${contact.name()} alias!`)
+}
+```
+**Example** *(DELETE the alias for a contact)*
+```js
+try {
+ const oldAlias = await contact.alias(null)
+ console.log(`delete ${contact.name()}'s alias successfully!`)
+ console.log('old alias is ${oldAlias}`)
+} catch (e) {
+ console.log(`failed to delete ${contact.name()}'s alias!`)
+}
+```
+
+
+### ~~contact.stranger() ⇒ boolean
\| null
~~
+***Deprecated***
+
+Check if contact is stranger
+
+**Kind**: instance method of [Contact
](#Contact)
+**Returns**: boolean
\| null
- - True for not friend of the bot, False for friend of the bot, null for unknown.
+**Example**
+```js
+const isStranger = contact.stranger()
+```
+
+
+### contact.friend() ⇒ boolean
\| null
+Check if contact is friend
+
+**Kind**: instance method of [Contact
](#Contact)
+**Returns**: boolean
\| null
- - True for friend of the bot, False for not friend of the bot, null for unknown.
+**Example**
+```js
+const isFriend = contact.friend()
+```
+
+
+### ~~contact.official() ⇒ boolean
\| null
~~
+***Deprecated***
+
+Check if it's a offical account
+
+**Kind**: instance method of [Contact
](#Contact)
+**Returns**: boolean
\| null
- - True for official account, Flase for contact is not a official account, null for unknown
+**See**
+
+- [webwxApp.js#L324](https://github.com/Chatie/webwx-app-tracker/blob/7c59d35c6ea0cff38426a4c5c912a086c4c512b2/formatted/webwxApp.js#L3243)
+- [Urinx/WeixinBot/README](https://github.com/Urinx/WeixinBot/blob/master/README.md)
+**Example**
+```js
+const isOfficial = contact.official()
+```
+
+
+### ~~contact.personal() ⇒ boolean
~~
+***Deprecated***
+
+Check if it's a personal account
+
+**Kind**: instance method of [Contact
](#Contact)
+**Returns**: boolean
- - True for personal account, Flase for contact is not a personal account
+**Example**
+```js
+const isPersonal = contact.personal()
+```
+
+
+### contact.type() ⇒
+Return the type of the Contact
+
+**Kind**: instance method of [Contact
](#Contact)
+**Returns**: ContactType - Contact.Type.PERSONAL for personal account, Contact.Type.OFFICIAL for official account
+**Example**
+```js
+const isOfficial = contact.type() === Contact.Type.OFFICIAL
+```
+
+
+### contact.star() ⇒ boolean
\| null
+Check if the contact is star contact.
+
+**Kind**: instance method of [Contact
](#Contact)
+**Returns**: boolean
\| null
- - True for star friend, False for no star friend.
+**Example**
+```js
+const isStar = contact.star()
+```
+
+
+### contact.gender() ⇒ ContactGender.Male(2)
\| Gender.Female(1)
\| Gender.Unknown(0)
+Contact gender
+
+**Kind**: instance method of [Contact
](#Contact)
+**Example**
+```js
+const gender = contact.gender()
+```
+
+
+### contact.province() ⇒ string
\| null
+Get the region 'province' from a contact
+
+**Kind**: instance method of [Contact
](#Contact)
+**Example**
+```js
+const province = contact.province()
+```
+
+
+### contact.city() ⇒ string
\| null
+Get the region 'city' from a contact
+
+**Kind**: instance method of [Contact
](#Contact)
+**Example**
+```js
+const city = contact.city()
+```
+
+
+### contact.avatar() ⇒ Promise.<FileBox>
+Get avatar picture file stream
+
+**Kind**: instance method of [Contact
](#Contact)
+**Example**
+```js
+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)
+```
+
+
+### ~~contact.refresh() ⇒ Promise.<this>
~~
+***Deprecated***
+
+Force reload(re-ready()) data for Contact
+
+**Kind**: instance method of [Contact
](#Contact)
+**Example**
+```js
+await contact.refresh()
+```
+
+
+### contact.sync() ⇒ Promise.<this>
+sycc data for Contact
+
+**Kind**: instance method of [Contact
](#Contact)
+**Example**
+```js
+await contact.sync()
+```
+
+
+### contact.self() ⇒ boolean
+Check if contact is self
+
+**Kind**: instance method of [Contact
](#Contact)
+**Returns**: boolean
- True for contact is self, False for contact is others
+**Example**
+```js
+const isSelf = contact.self()
+```
+
+
+### Contact.find(query) ⇒ Promise.<(Contact\|null)>
+Try to find a contact by filter: {name: string | RegExp} / {alias: string | RegExp}
+
+Find contact by name or alias, if the result more than one, return the first one.
+
+**Kind**: static method of [Contact
](#Contact)
+**Returns**: Promise.<(Contact\|null)>
- If can find the contact, return Contact, or return null
+
+| Param | Type |
+| --- | --- |
+| query | [ContactQueryFilter
](#ContactQueryFilter) |
+
+**Example**
+```js
+const contactFindByName = await Contact.find({ name:"ruirui"} )
+const contactFindByAlias = await Contact.find({ alias:"lijiarui"} )
+```
+
+
+### Contact.findAll([queryArg]) ⇒ Promise.<Array.<Contact>>
+Find contact by `name` or `alias`
+
+If use Contact.findAll() get the contact list of the bot.
+
+#### definition
+- `name` the name-string set by user-self, should be called name
+- `alias` the name-string set by bot for others, should be called alias
+
+**Kind**: static method of [Contact
](#Contact)
+
+| Param | Type |
+| --- | --- |
+| [queryArg] | [ContactQueryFilter
](#ContactQueryFilter) |
+
+**Example**
+```js
+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'
+```
+
+
+## Friendship
+Send, receive friend request, and friend confirmation events.
+
+1. send request
+2. receive request(in friend event)
+3. confirmation friendship(friend event)
+
+[Examples/Friend-Bot](https://github.com/Chatie/wechaty/blob/master/examples/friend-bot.ts)
+
+**Kind**: global class
+
+* [Friendship](#Friendship)
+ * _instance_
+ * [.payload](#Friendship+payload)
+ * [.ready()](#Friendship+ready)
+ * _static_
+ * ~~[.send()](#Friendship.send)~~
+ * [.add(contact, hello)](#Friendship.add)
+
+
+
+### friendship.payload
+Instance Properties
+
+**Kind**: instance property of [Friendship
](#Friendship)
+
+
+### friendship.ready()
+no `dirty` support because Friendship has no rawPayload(yet)
+
+**Kind**: instance method of [Friendship
](#Friendship)
+
+
+### ~~Friendship.send()~~
+***Deprecated***
+
+**Kind**: static method of [Friendship
](#Friendship)
+
+
+### Friendship.add(contact, hello)
+Send a Friend Request to a `contact` with message `hello`.
+
+**Kind**: static method of [Friendship
](#Friendship)
+
+| Param |
+| --- |
+| contact |
+| hello |
+
+
+
+## Message
+All wechat messages will be encapsulated as a Message.
+
+`Message` is `Sayable`,
+[Examples/Ding-Dong-Bot](https://github.com/Chatie/wechaty/blob/master/examples/ding-dong-bot.ts)
+
+**Kind**: global class
+
+* [Message](#Message)
+ * _instance_
+ * [.payload](#Message+payload)
+ * [.from()](#Message+from) ⇒ [Contact
](#Contact)
+ * [.to()](#Message+to) ⇒ [Contact
](#Contact) \| null
+ * [.room()](#Message+room) ⇒ [Room
](#Room) \| null
+ * ~~[.content()](#Message+content)~~
+ * [.text()](#Message+text) ⇒ string
+ * [.say(textOrContactOrFile, [mention])](#Message+say) ⇒ Promise.<void>
+ * ~~[.file()](#Message+file)~~
+ * [.type()](#Message+type) ⇒ WebMsgType
+ * [.self()](#Message+self) ⇒ boolean
+ * [.mention()](#Message+mention) ⇒ [Array.<Contact>
](#Contact)
+ * [.mentioned()](#Message+mentioned)
+ * [.forward(to)](#Message+forward) ⇒ Promise.<void>
+ * [.age()](#Message+age)
+ * _static_
+ * [.Type](#Message.Type)
+ * [.find()](#Message.find)
+ * [.findAll()](#Message.findAll)
+ * [.create()](#Message.create)
+
+
+
+### message.payload
+Instance Properties
+
+**Kind**: instance property of [Message
](#Message)
+
+
+### message.from() ⇒ [Contact
](#Contact)
+Get the sender from a message.
+
+**Kind**: instance method of [Message
](#Message)
+
+
+### message.to() ⇒ [Contact
](#Contact) \| null
+Get the destination of the message
+Message.to() will return null if a message is in a room, use Message.room() to get the room.
+
+**Kind**: instance method of [Message
](#Message)
+
+
+### message.room() ⇒ [Room
](#Room) \| null
+Get the room from the message.
+If the message is not in a room, then will return `null`
+
+**Kind**: instance method of [Message
](#Message)
+
+
+### ~~message.content()~~
+***Deprecated***
+
+**Kind**: instance method of [Message
](#Message)
+
+
+### message.text() ⇒ string
+Get the text content of the message
+
+**Kind**: instance method of [Message
](#Message)
+
+
+### message.say(textOrContactOrFile, [mention]) ⇒ Promise.<void>
+Reply a Text or Media File message to the sender.
+
+**Kind**: instance method of [Message
](#Message)
+**See**: [Examples/ding-dong-bot](https://github.com/Chatie/wechaty/blob/master/examples/ding-dong-bot.ts)
+
+| Param | Type |
+| --- | --- |
+| textOrContactOrFile | string
\| FileBox
|
+| [mention] | [Contact
](#Contact) \| [Array.<Contact>
](#Contact) |
+
+**Example**
+```js
+const bot = new Wechaty()
+bot
+.on('message', async m => {
+ 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')
+ }
+})
+```
+
+
+### ~~message.file()~~
+***Deprecated***
+
+**Kind**: instance method of [Message
](#Message)
+
+
+### message.type() ⇒ WebMsgType
+Get the type from the message.
+
+If type is equal to `MsgType.RECALLED`, [Message#id](Message#id) is the msgId of the recalled message.
+
+**Kind**: instance method of [Message
](#Message)
+**See**: [MsgType](MsgType)
+
+
+### message.self() ⇒ boolean
+Check if a message is sent by self.
+
+**Kind**: instance method of [Message
](#Message)
+**Returns**: boolean
- - Return `true` for send from self, `false` for send from others.
+**Example**
+```js
+if (message.self()) {
+ console.log('this message is sent by myself!')
+}
+```
+
+
+### message.mention() ⇒ [Array.<Contact>
](#Contact)
+Get message mentioned contactList.
+
+Message event table as follows
+
+| | Web | Mac PC Client | iOS Mobile | android Mobile |
+| :--- | :--: | :----: | :---: | :---: |
+| [You were mentioned] tip ([有人@我]的提示) | ✘ | √ | √ | √ |
+| Identify magic code (8197) by copy & paste in mobile | ✘ | √ | √ | ✘ |
+| Identify magic code (8197) by programming | ✘ | ✘ | ✘ | ✘ |
+| Identify two contacts with the same roomAlias by [You were mentioned] tip | ✘ | ✘ | √ | √ |
+
+**Kind**: instance method of [Message
](#Message)
+**Returns**: [Array.<Contact>
](#Contact) - - Return message mentioned contactList
+**Example**
+```js
+const contactList = message.mentioned()
+console.log(contactList)
+```
+
+
+### message.mentioned()
+**Kind**: instance method of [Message
](#Message)
+**Deprecated:**: use mention() instead
+
+
+### message.forward(to) ⇒ Promise.<void>
+Forward the received message.
+
+**Kind**: instance method of [Message
](#Message)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| to | Sayable
\| Array.<Sayable>
| Room or Contact The recipient of the message, the room, or the contact |
+
+
+
+### message.age()
+Message Age:
+ in seconds.
+
+**Kind**: instance method of [Message
](#Message)
+
+
+### Message.Type
+Static Properties
+
+**Kind**: static property of [Message
](#Message)
+
+
+### Message.find()
+**Kind**: static method of [Message
](#Message)
+**Todo**
+
+- [ ] add function
+
+
+
+### Message.findAll()
+**Kind**: static method of [Message
](#Message)
+**Todo**
+
+- [ ] add function
+
+
+
+### Message.create()
+Create a Mobile Terminated Message
+
+"mobile originated" or "mobile terminated"
+https://www.tatango.com/resources/video-lessons/video-mo-mt-sms-messaging/
+
+**Kind**: static method of [Message
](#Message)
## WechatyEventName
@@ -326,13 +1221,68 @@ Wechaty Class Event Function
| Name | Type | Description |
| --- | --- | --- |
| error | function
| (this: Wechaty, error: Error) => void callback function |
-| login | function
| (this: Wechaty, user: Contact)=> void |
-| logout | function
| (this: Wechaty, user: Contact) => void |
+| login | function
| (this: Wechaty, user: ContactSelf)=> void |
+| logout | function
| (this: Wechaty, user: ContactSelf) => void |
| scan | function
| (this: Wechaty, url: string, code: number) => void function
| (this: Wechaty, data: any) => void |
-| friend | function
| (this: Wechaty, friend: Contact, request?: FriendRequest) => void |
+| friend | function
| (this: Wechaty, request?: Friendship) => void |
| message | function
| (this: Wechaty, message: Message) => void |
| room-join | function
| (this: Wechaty, room: Room, inviteeList: Contact[], inviter: Contact) => void |
-| room-topic | function
| (this: Wechaty, room: Room, topic: string, oldTopic: string, changer: Contact) => void |
+| room-topic | function
| (this: Wechaty, room: Room, newTopic: string, oldTopic: string, changer: Contact) => void |
| room-leave | function
| (this: Wechaty, room: Room, leaverList: Contact[]) => void |
+
+
+## RoomEventName
+Room Class Event Type
+
+**Kind**: global typedef
+**Properties**
+
+| Name | Type | Description |
+| --- | --- | --- |
+| join | string
| Emit when anyone join any room. |
+| topic | string
| Get topic event, emitted when someone change room topic. |
+| leave | string
| Emit when anyone leave the room.function
| (this: Room, inviteeList: Contact[] , inviter: Contact) => void |
+| room-topic | function
| (this: Room, topic: string, oldTopic: string, changer: Contact) => void |
+| room-leave | function
| (this: Room, leaver: Contact) => void |
+
+
+
+## MemberQueryFilter
+The way to search member by Room.member()
+
+**Kind**: global typedef
+**Properties**
+
+| Name | Type | Description |
+| --- | --- | --- |
+| name | string
| Find the contact by wechat name in a room, equal to `Contact.name()`. |
+| roomAlias | string
| Find the contact by alias set by the bot for others in a room. |
+| contactAlias | string
| Find the contact by alias set by the contact out of a room, equal to `Contact.alias()`. [More Detail](https://github.com/Chatie/wechaty/issues/365) |
+
+
+
+## ContactQueryFilter
+The way to search Contact
+
+**Kind**: global typedef
+**Properties**
+
+| Name | Type | Description |
+| --- | --- | --- |
+| name | string
| The name-string set by user-self, should be called name |
+| alias | string
| The name-string set by bot for others, should be called alias [More Detail](https://github.com/Chatie/wechaty/issues/365) |
+
diff --git a/scripts/generate-docs.sh b/scripts/generate-docs.sh
index 0e9885a500f97a2b817e8b11649d94c69e427d8e..f5194fd5b51a2ce58fa0280a048eeeef248f39b4 100755
--- a/scripts/generate-docs.sh
+++ b/scripts/generate-docs.sh
@@ -3,7 +3,7 @@ set -e
npm version
-if ./scripts/development-release.ts; then
+if [ "$1" != "dev" ] && ./scripts/development-release.ts; then
echo "Current release is a development release, please only update the docs when there's a stable release."
exit 1
else
diff --git a/src/accessory.ts b/src/accessory.ts
index 8cf984a237eb52c68843e2f72d1dc40a479a10fc..c43c20547ffe47a36a12788356db81fb1ed11df4 100644
--- a/src/accessory.ts
+++ b/src/accessory.ts
@@ -30,6 +30,9 @@ export abstract class Accessory extends EventEmitter {
private static _puppet? : Puppet
private static _wechaty? : Wechaty
+ /**
+ * @private
+ */
public static set puppet(puppet: Puppet) {
log.silly('Accessory', '<%s> static set puppet = "%s"',
this.name,
@@ -42,6 +45,9 @@ export abstract class Accessory extends EventEmitter {
this._puppet = puppet
}
+ /**
+ * @private
+ */
public static get puppet(): Puppet {
// log.silly('Accessory', '<%s> static get puppet()',
// this.name,
@@ -56,6 +62,9 @@ export abstract class Accessory extends EventEmitter {
)
}
+ /**
+ * @private
+ */
public static set wechaty(wechaty: Wechaty) {
log.silly('Accessory', '<%s> static set wechaty = "%s"',
this.name,
@@ -67,6 +76,9 @@ export abstract class Accessory extends EventEmitter {
this._wechaty = wechaty
}
+ /**
+ * @private
+ */
public static get wechaty(): Wechaty {
// log.silly('Accessory', '<%s> static get wechaty()',
// this.name,
@@ -90,6 +102,9 @@ export abstract class Accessory extends EventEmitter {
*/
private _puppet? : Puppet
+ /**
+ * @private
+ */
public set puppet(puppet: Puppet) {
log.silly('Accessory', '<%s> set puppet = "%s"',
this[SYMBOL_NAME] || this,
@@ -102,6 +117,8 @@ export abstract class Accessory extends EventEmitter {
}
/**
+ * @private
+ *
* instance.puppet
*
* Needs to support different `puppet` between instances.
@@ -130,6 +147,8 @@ export abstract class Accessory extends EventEmitter {
}
/**
+ * @private
+ *
* instance.wechaty is for:
* Contact.wechaty
* FriendRequest.wechaty
diff --git a/src/user/room.ts b/src/user/room.ts
index 4361bf07a7630b985e04e9993e04d1860250bd1a..fac81f1fa07bb11bb20cc134638e7b7c90f526bd 100644
--- a/src/user/room.ts
+++ b/src/user/room.ts
@@ -221,7 +221,7 @@ export class Room extends Accessory implements Sayable {
}
/**
- *
+ * @private
*
* Instance Properties
*
@@ -792,6 +792,7 @@ export class Room extends Accessory implements Sayable {
/**
* Force reload data for Room
+ * @private
* @deprecated use sync() instead
* @returns {Promise