diff --git a/example/room-bot.ts b/example/room-bot.ts index 948f07e4742959e915add296e8c0b302a912ef14..ded52c6166db70d399a569ca7eab17bfe2dee070 100644 --- a/example/room-bot.ts +++ b/example/room-bot.ts @@ -83,9 +83,9 @@ bot * Global Event: room-join */ .on('room-join', (room, invitee, inviter) => { - log.info('Bot', 'room-join event: Room %s got new member %s, invited by %s' + log.info('Bot', 'EVENT: room-join - Room %s got new member %s, invited by %s' , room.topic() - , invitee.map + , Array.isArray(invitee) ? invitee.map(c => c.name()).join(',') : invitee , inviter.name() @@ -96,7 +96,7 @@ bot * Global Event: room-leave */ .on('room-leave', (room, leaver) => { - log.info('Bot', 'room-leave event: Room %s lost member %s' + log.info('Bot', 'EVENT: room-leave - Room %s lost member %s' , room.topic() , leaver.name() ) @@ -107,7 +107,7 @@ bot */ .on('room-topic', (room, topic, oldTopic, changer) => { try { - log.info('Bot', 'room-topic event: Room %s change topic to %s by member %s' + log.info('Bot', 'EVENT: room-topic - Room %s change topic to %s by member %s' , oldTopic , topic , changer.name() @@ -120,7 +120,7 @@ bot /** * Global Event: message */ -.on('message', message => { +.on('message', (message) => { const room = message.room() const sender = message.from() const content = message.content() @@ -166,7 +166,7 @@ bot * room found */ if (dingRoom) { - log.info('Bot', 'onMessage: got dingRoom') + log.info('Bot', 'onMessage: got dingRoom: %s', dingRoom.topic()) /** * speaker is already in room @@ -183,7 +183,8 @@ bot * put speaker into room */ } else { - log.info('Bot', 'onMessage: add sender to dingRoom') + log.info('Bot', 'onMessage: add sender(%s) to dingRoom(%s)', sender.name(), dingRoom.topic()) + sender.say('ok, I will put you in ding room!') putInRoom(sender, dingRoom) } @@ -230,22 +231,23 @@ function manageDingRoom() { /** * Event: Join */ - room.on('join', (invitee: Contact|Contact[], inviter: Contact) => + room.on('join', (invitee: Contact|Contact[], inviter: Contact) => { + log.verbose('Bot', 'Room EVENT: join - %s, %s', typeof invitee, typeof inviter) checkRoomJoin.call(this, room, invitee, inviter) - ) + }) /** * Event: Leave */ room.on('leave', (leaver) => { - log.info('Bot', 'room event: %s leave, byebye', leaver.name()) + log.info('Bot', 'Room EVENT: leave - %s leave, byebye', leaver.name()) }) /** * Event: Topic Change */ room.on('topic', (topic, oldTopic, changer) => { - log.info('Bot', 'room event: topic changed from %s to %s by member %s' + log.info('Bot', 'Room EVENT: topic - changed from %s to %s by member %s' , oldTopic , topic , changer.name() diff --git a/package.json b/package.json old mode 100755 new mode 100644 diff --git a/src/contact.ts b/src/contact.ts index 1bc16436f81c372d6411bdbc3b4ecb08bc7299e6..f2f824dec5967b6949a372b4785b898be1561aec 100644 --- a/src/contact.ts +++ b/src/contact.ts @@ -7,7 +7,9 @@ * */ import Config from './config' +import Message from './message' import UtilLib from './util-lib' +import Wechaty from './wechaty' import log from './brolog-env' @@ -184,6 +186,22 @@ class Contact { return Contact.pool[id] } + public say(content: string): Promise { + log.verbose('Contact', 'say(%s)', content) + + const wechaty = Wechaty.instance() + const user = wechaty.user() + + const m = new Message() + m.from(user) + m.to(this) + m.content(content) + + log.silly('Contact', 'say() from: %s to: %s content: %s', user.name(), this.name(), content) + + return wechaty.send(m) + } + } // Contact.search = function(options) { diff --git a/src/event-scope.ts b/src/event-scope.ts index 60109c2a8b0e7e88c4a44916afaff07a47af29f5..99bccd2c20b220ac3b47be05bd514ffcd9824e39 100755 --- a/src/event-scope.ts +++ b/src/event-scope.ts @@ -45,14 +45,11 @@ class EventScope { return Object.keys(EVENT_CONFIG) } - public static wrap(this: Wechaty|Room, event: WechatyEventType, callback: Function) { - log.verbose('WechatyEvent', 'wrap(%s, %s)', event, typeof callback) - - // if (!(this instanceof Wechaty)) { - // throw new Error('`this` should be Wechaty instance') - // } - if (typeof callback !== 'function') { - throw new Error('`callback` should be function') + public static wrap(this: Wechaty|Room, event: WechatyEventType, listener: Function): Function { + log.verbose('WechatyEvent', 'wrap(%s, %s)', event, typeof listener) + + if (typeof listener !== 'function') { + throw new Error('`listener` should be function') } if (!(event in EVENT_CONFIG)) { @@ -61,13 +58,13 @@ class EventScope { const wrapper = EVENT_CONFIG[event] /** - * We assign a empty object to each event callback, + * We assign a empty object to each event listener, * to carry the indenpendent scope */ if (wrapper) { - return wrapper(callback) + return wrapper(listener) } else { - return callback + return listener } } } @@ -92,11 +89,11 @@ function isRoom(room) { return true } -function wrapContact(callback) { +function wrapContact(listener) { log.verbose('WechatyEvent', 'wrapContact()') return (...argList) => { - log.silly('WechatyEvent', 'wrapContact() callback') + log.silly('WechatyEvent', 'wrapContact() listener') if (!isContact(argList[0])) { throw new Error('contact not found in argList') @@ -113,15 +110,15 @@ function wrapContact(callback) { .send(msg) } - return callback.apply(eventScope, argList) + return listener.apply(eventScope, argList) } } -function wrapRoom(callback) { +function wrapRoom(listener) { log.verbose('WechatyEvent', 'wrapRoom()') return (room: Room, ...argList) => { - log.silly('WechatyEvent', 'wrapRoom(%s, %s, %s, %s) callback', room.topic(), argList[0], argList[1], argList[2]) + log.silly('WechatyEvent', 'wrapRoom(%s, %s, %s, %s) listener', room.topic(), argList[0], argList[1], argList[2]) let contact for (let arg of argList) { @@ -144,17 +141,17 @@ function wrapRoom(callback) { return room.say(content, replyTo) } - return callback.apply(eventScope, [room, ...argList]) + return listener.apply(eventScope, [room, ...argList]) } } -function wrapMessage(callback) { +function wrapMessage(listener) { log.verbose('WechatyEvent', 'wrapMessage()') return (...argList) => { - log.silly('WechatyEvent', 'wrapMessage() callback') + log.silly('WechatyEvent', 'wrapMessage() listener') - // console.log('############### wrapped on message callback') + // console.log('############### wrapped on message listener') // console.log(typeof Message) // console.log(argList) if (!(argList[0] instanceof Message)) { @@ -183,15 +180,15 @@ function wrapMessage(callback) { .send(m) } - return callback.apply(eventScope, argList) + return listener.apply(eventScope, argList) } } -function wrapFilehelper(callback) { +function wrapFilehelper(listener) { log.verbose('WechatyEvent', 'wrapFilehelper()') return (...argList) => { - log.silly('WechatyEvent', 'wrapFilehelper() callback') + log.silly('WechatyEvent', 'wrapFilehelper() listener') const eventScope = {} eventScope.say = (content) => { log.silly('WechatyEvent', 'wrapFilehelper() say(%s)', content) @@ -202,7 +199,7 @@ function wrapFilehelper(callback) { .send(msg) } - return callback.apply(eventScope, argList) + return listener.apply(eventScope, argList) } } diff --git a/src/message.ts b/src/message.ts index c8ffef0916212e40db23dc943ad373b2526f37b7..178d0a6de899425c4f31c1b1f0a607b1089c617f 100644 --- a/src/message.ts +++ b/src/message.ts @@ -134,7 +134,7 @@ class Message { return '{' + this.type() + '}' + content } - public from(contact?: Contact) { + public from(contact?: Contact): Contact { if (contact) { if (contact instanceof Contact) { this.obj.from = contact.id diff --git a/src/puppet-web/firer.ts b/src/puppet-web/firer.ts index 7323d5eface2cdb6224f0c4302ab65757068fd20..4e0e48da89ba2c31ecc6791c7ff4138640e76529 100644 --- a/src/puppet-web/firer.ts +++ b/src/puppet-web/firer.ts @@ -210,11 +210,11 @@ async function fireRoomJoin(m: Message): Promise { await room.ready() if (inviteeContactList.length === 1) { - this.emit('room-join', room , inviteeContactList[0], inviterContact) - room.emit('join' , inviteeContactList[0], inviterContact) + this.emit('room-join', room , inviteeContactList[0] , inviterContact) + room.emit('join' , inviteeContactList[0] , inviterContact) } else { - this.emit('room-join', room , inviteeContactList, inviterContact) - room.emit('join' , inviteeContactList, inviterContact) + this.emit('room-join', room , inviteeContactList , inviterContact) + room.emit('join' , inviteeContactList , inviterContact) } // }).catch(e => { diff --git a/src/room.ts b/src/room.ts index d7e6618c19bf5ecb471895921fb2a6ab6d49069b..646d6d016fa8b399322a539bc8b1c878e55d23e7 100644 --- a/src/room.ts +++ b/src/room.ts @@ -109,19 +109,34 @@ class Room extends EventEmitter { }) } - public on( event: 'join' | 'leave' | 'topic' - , listener: Function - ) { + public on(event: 'join' , listener: (invitee: Contact , inviter: Contact) => void) // XXX ??? + public on(event: 'join' , listener: (inviteeList: Contact[] , inviter: Contact) => void): Room + public on(event: 'topic', listener: (topic: string, oldTopic: string, changer: Contact) => void): Room + public on(event: 'leave', listener: (leaver: Contact) => void): Room + + public on(event: string, listener: Function): Room { log.verbose('Room', 'on(%s, %s)', event, typeof listener) + /** + * wrap a room event listener to a global event listener + */ + const listenerWithRoomArg = (room: Room, ...argList) => { + return listener.apply(this, argList) + } + /** * every room event must can be mapped to a global event. * such as: `join` to `room-join` */ - const callbackWithScope = EventScope.wrap.call(this, 'room-' + event, listener) + const globalEventName = 'room-' + event + const listenerWithScope = EventScope.wrap.call(this, globalEventName, listenerWithRoomArg) - // bind(this1, this2): the second this is for simulate the global room-* event - super.on(event, callbackWithScope.bind(this, this)) + /** + * bind(listenerWithScope, this): + * the `this` is for simulate the global room-* event, + * provide the first argument `room` + */ + super.on(event, listenerWithScope.bind(listenerWithScope, this)) return this } diff --git a/src/wechaty.ts b/src/wechaty.ts index f9042f945cf708544e9efa0ca10478754a0e85ec..0f415b94d5c7aef10d2f065d2b7635474fb513dd 100644 --- a/src/wechaty.ts +++ b/src/wechaty.ts @@ -18,14 +18,16 @@ import Config, { , PuppetType } from './config' -import Contact from './contact' -import Message from './message' -import Puppet from './puppet' -import PuppetWeb from './puppet-web/index' -import UtilLib from './util-lib' -import EventScope from './event-scope' +import Contact from './contact' +import FriendRequest from './friend-request' +import Message from './message' +import Puppet from './puppet' +import PuppetWeb from './puppet-web/index' +import Room from './room' +import UtilLib from './util-lib' +import EventScope from './event-scope' -import log from './brolog-env' +import log from './brolog-env' type WechatySetting = { profile?: string @@ -152,11 +154,23 @@ class Wechaty extends EventEmitter { return this } - public on(event: string, listener: Function) { + public on(event: 'message', listener: (message: Message, n: number) => void) // XXX ??? + public on(event: 'scan' , listener: ({url: string, code: number}) => void): Wechaty + public on(event: 'logout' , listener: (user: Contact) => void): Wechaty + public on(event: 'login' , listener: (user: Contact) => void): Wechaty + public on(event: 'friend' , listener: (friend: Contact, request: FriendRequest) => void): Wechaty + public on(event: 'error' , listener: (error: Error) => void): Wechaty + public on(event: 'heartbeat' , listener: (data: any) => void): Wechaty + public on(event: 'room-join' , listener: (room: Room, invitee: Contact, inviter: Contact) => void): Wechaty + public on(event: 'room-join' , listener: (room: Room, inviteeList: Contact, inviter: Contact) => void): Wechaty + public on(event: 'room-leave' , listener: (room: Room, leaver: Contact) => void): Wechaty + public on(event: 'room-topic' , listener: (room: Room, topic: string, oldTopic: string, changer: Contact) => void): Wechaty + + public on(event: string, listener: Function): Wechaty { log.verbose('Wechaty', 'on(%s, %s)', event, typeof listener) - const wrapListener = EventScope.wrap.call(this, event, listener) - super.on(event, wrapListener) + const listenerWithScope = EventScope.wrap.call(this, event, listener) + super.on(event, listenerWithScope) return this } @@ -231,7 +245,7 @@ class Wechaty extends EventEmitter { return this.puppet.self(message) } - public send(message) { + public send(message: Message): Promise { return this.puppet.send(message) .catch(e => { log.error('Wechaty', 'send() exception: %s', e.message) @@ -239,7 +253,7 @@ class Wechaty extends EventEmitter { }) } - public reply(message, reply) { + public reply(message: Message, reply: string) { return this.puppet.reply(message, reply) .catch(e => { log.error('Wechaty', 'reply() exception: %s', e.message)