提交 e6ee5fd8 编写于 作者: Huan (李卓桓)'s avatar Huan (李卓桓)

abstract Message

上级 bbbabdbb
/**
* Wechaty - https://github.com/chatie/wechaty
*
* @copyright 2016-2018 Huan LI <zixia@zixia.net>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @ignore
*/
import {
Readable,
} from 'stream'
import {
Sayable,
log,
} from './config'
import Contact from './contact'
import Room from './room'
import PuppetAccessory from './puppet-accessory'
/**
*
* Enum for AppMsgType values.
*
* @enum {number}
* @property {number} TEXT - AppMsgType.TEXT (1) for TEXT
* @property {number} IMG - AppMsgType.IMG (2) for IMG
* @property {number} AUDIO - AppMsgType.AUDIO (3) for AUDIO
* @property {number} VIDEO - AppMsgType.VIDEO (4) for VIDEO
* @property {number} URL - AppMsgType.URL (5) for URL
* @property {number} ATTACH - AppMsgType.ATTACH (6) for ATTACH
* @property {number} OPEN - AppMsgType.OPEN (7) for OPEN
* @property {number} EMOJI - AppMsgType.EMOJI (8) for EMOJI
* @property {number} VOICE_REMIND - AppMsgType.VOICE_REMIND (9) for VOICE_REMIND
* @property {number} SCAN_GOOD - AppMsgType.SCAN_GOOD (10) for SCAN_GOOD
* @property {number} GOOD - AppMsgType.GOOD (13) for GOOD
* @property {number} EMOTION - AppMsgType.EMOTION (15) for EMOTION
* @property {number} CARD_TICKET - AppMsgType.CARD_TICKET (16) for CARD_TICKET
* @property {number} REALTIME_SHARE_LOCATION - AppMsgType.REALTIME_SHARE_LOCATION (17) for REALTIME_SHARE_LOCATION
* @property {number} TRANSFERS - AppMsgType.TRANSFERS (2e3) for TRANSFERS
* @property {number} RED_ENVELOPES - AppMsgType.RED_ENVELOPES (2001) for RED_ENVELOPES
* @property {number} READER_TYPE - AppMsgType.READER_TYPE (100001) for READER_TYPE
*/
export enum AppMsgType {
TEXT = 1,
IMG = 2,
AUDIO = 3,
VIDEO = 4,
URL = 5,
ATTACH = 6,
OPEN = 7,
EMOJI = 8,
VOICE_REMIND = 9,
SCAN_GOOD = 10,
GOOD = 13,
EMOTION = 15,
CARD_TICKET = 16,
REALTIME_SHARE_LOCATION = 17,
TRANSFERS = 2e3,
RED_ENVELOPES = 2001,
READER_TYPE = 100001,
}
/**
*
* Enum for MsgType values.
* @enum {number}
* @property {number} TEXT - MsgType.TEXT (1) for TEXT
* @property {number} IMAGE - MsgType.IMAGE (3) for IMAGE
* @property {number} VOICE - MsgType.VOICE (34) for VOICE
* @property {number} VERIFYMSG - MsgType.VERIFYMSG (37) for VERIFYMSG
* @property {number} POSSIBLEFRIEND_MSG - MsgType.POSSIBLEFRIEND_MSG (40) for POSSIBLEFRIEND_MSG
* @property {number} SHARECARD - MsgType.SHARECARD (42) for SHARECARD
* @property {number} VIDEO - MsgType.VIDEO (43) for VIDEO
* @property {number} EMOTICON - MsgType.EMOTICON (47) for EMOTICON
* @property {number} LOCATION - MsgType.LOCATION (48) for LOCATION
* @property {number} APP - MsgType.APP (49) for APP
* @property {number} VOIPMSG - MsgType.VOIPMSG (50) for VOIPMSG
* @property {number} STATUSNOTIFY - MsgType.STATUSNOTIFY (51) for STATUSNOTIFY
* @property {number} VOIPNOTIFY - MsgType.VOIPNOTIFY (52) for VOIPNOTIFY
* @property {number} VOIPINVITE - MsgType.VOIPINVITE (53) for VOIPINVITE
* @property {number} MICROVIDEO - MsgType.MICROVIDEO (62) for MICROVIDEO
* @property {number} SYSNOTICE - MsgType.SYSNOTICE (9999) for SYSNOTICE
* @property {number} SYS - MsgType.SYS (10000) for SYS
* @property {number} RECALLED - MsgType.RECALLED (10002) for RECALLED
*/
export enum MsgType {
TEXT = 1,
IMAGE = 3,
VOICE = 34,
VERIFYMSG = 37,
POSSIBLEFRIEND_MSG = 40,
SHARECARD = 42,
VIDEO = 43,
EMOTICON = 47,
LOCATION = 48,
APP = 49,
VOIPMSG = 50,
STATUSNOTIFY = 51,
VOIPNOTIFY = 52,
VOIPINVITE = 53,
MICROVIDEO = 62,
SYSNOTICE = 9999,
SYS = 10000,
RECALLED = 10002,
}
// export type TypeName = 'attachment'
// | 'audio'
// | 'image'
// | 'video'
/**
* 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 abstract class Message extends PuppetAccessory implements Sayable {
/**
* @private
*/
constructor(
readonly objOrId: Object | string,
) {
super()
log.silly('Message', 'constructor()')
}
/**
* @private
*/
public toString() {
return `Message`
}
public abstract async say(text: string, replyTo?: Contact | Contact[]) : Promise<void>
public abstract async say(mediaMessage: MediaMessage, replyTo?: Contact | Contact[]): Promise<void>
/**
* 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 | MediaMessage)} textOrMedia
* @param {(Contact|Contact[])} [replyTo]
* @returns {Promise<any>}
*
* @example
* const bot = new Wechaty()
* bot
* .on('message', async m => {
* if (/^ding$/i.test(m.content())) {
* await m.say('hello world')
* console.log('Bot REPLY: hello world')
* await m.say(new MediaMessage(__dirname + '/wechaty.png'))
* console.log('Bot REPLY: Image')
* }
* })
*/
public abstract async say(textOrMedia: string | MediaMessage, replyTo?: Contact|Contact[]): Promise<void>
/**
* @private
*/
public abstract from(contact: Contact): void
/**
* @private
*/
public abstract from(id: string): void
public abstract from(): Contact
/**
* Get the sender from a message.
* @returns {Contact}
*/
public abstract from(contact?: Contact|string): Contact|void
/**
* @private
*/
public abstract room(room: Room): void
/**
* @private
*/
public abstract room(id: string): void
public abstract room(): Room | null
/**
* Get the room from the message.
* If the message is not in a room, then will return `null`
*
* @returns {(Room | null)}
*/
public abstract room(room?: Room | string): Room | null | void
/**
* Get the content of the message
*
* @returns {string}
*/
public abstract content(): string
/**
* @private
*/
public abstract content(content: string): void
/**
* Get the content of the message
*
* @returns {string}
*/
public abstract content(content?: string): string | void
/**
* Get the type from the message.
*
* If type is equal to `MsgType.RECALLED`, {@link Message#id} is the msgId of the recalled message.
* @see {@link MsgType}
* @returns {MsgType}
*/
public abstract type(): MsgType
/**
* Get the typeSub from the message.
*
* If message is a location message: `m.type() === MsgType.TEXT && m.typeSub() === MsgType.LOCATION`
*
* @see {@link MsgType}
* @returns {MsgType}
*/
public abstract typeSub(): MsgType
/**
* Get the typeApp from the message.
*
* @returns {AppMsgType}
* @see {@link AppMsgType}
*/
public abstract typeApp(): AppMsgType
/**
* Check if a message is sent by self.
*
* @returns {boolean} - Return `true` for send from self, `false` for send from others.
* @example
* if (message.self()) {
* console.log('this message is sent by myself!')
* }
*/
public abstract self(): boolean
/**
*
* 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 | ✘ | ✘ | √ | √ |
*
* @returns {Contact[]} - Return message mentioned contactList
*
* @example
* const contactList = message.mentioned()
* console.log(contactList)
*/
public abstract mentioned(): Contact[]
/**
* @private
*/
public abstract async ready(): Promise<this>
/**
* @todo add function
*/
public static async find(query) {
return this.findAll(query)[0]
}
/**
* @todo add function
*/
public static async findAll(query) {
return Promise.resolve([
new (this as any)(1),
new (this as any)(2),
])
}
/**
* @private
*/
public abstract to(contact: Contact): void
/**
* @private
*/
public abstract to(id: string): void
public abstract to(): Contact | null // if to is not set, then room must had set
/**
* 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.
* @returns {(Contact|null)}
*/
public abstract to(contact?: Contact | string): Contact | Room | null | void
}
/**
* Meidia Type Message
*
*/
export abstract class MediaMessage extends Message {
/**
* @private
*/
public toString() {
return `MediaMessage<${this.filename()}>`
}
/**
* Get the MediaMessage file extension, etc: `jpg`, `gif`, `pdf`, `word` ..
*
* @returns {string}
* @example
* bot.on('message', async function (m) {
* if (m instanceof MediaMessage) {
* console.log('media message file name extention is: ' + m.ext())
* }
* })
*/
public abstract ext(): string
/**
* return the MIME Type of this MediaMessage
*
*/
public abstract mimeType(): string | null
/**
* Get the MediaMessage filename, etc: `how to build a chatbot.pdf`..
*
* @returns {string}
* @example
* bot.on('message', async function (m) {
* if (m instanceof MediaMessage) {
* console.log('media message file name is: ' + m.filename())
* }
* })
*/
public abstract filename(): string
/**
* Get the read stream for attachment file
*/
public abstract async readyStream(): Promise<Readable>
public abstract async forward(to: Room|Contact): Promise<void>
}
export default Message
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册