From 197e7e1deefd85ede78a2d728c1f37ec43613cef Mon Sep 17 00:00:00 2001 From: "Zhuohuan LI (CARPE DIEM)" Date: Tue, 11 Oct 2016 16:56:20 +0800 Subject: [PATCH] #40 fix examples --- example/ding-dong-bot.ts | 3 +- example/friend-bot.ts | 6 +- example/image-bot.ts | 9 ++- example/roger-bot.ts | 6 +- example/room-bot.ts | 9 ++- example/tuling123-bot.ts | 52 ++++++++------- src/{wechaty-event.ts => event-scope.ts} | 41 ++++++------ src/puppet-web/firer.ts | 81 ++++++++++++++---------- src/room.ts | 25 +++++--- src/wechaty.ts | 6 +- tsconfig.json | 4 +- 11 files changed, 138 insertions(+), 104 deletions(-) rename src/{wechaty-event.ts => event-scope.ts} (80%) diff --git a/example/ding-dong-bot.ts b/example/ding-dong-bot.ts index e95b68d9..9ab15dfa 100644 --- a/example/ding-dong-bot.ts +++ b/example/ding-dong-bot.ts @@ -36,7 +36,7 @@ Please wait... I'm trying to login in... ` console.log(welcome) -const bot = new Wechaty({ profile: Config.DEFAULT_PROFILE }) +const bot = Wechaty.instance({ profile: Config.DEFAULT_PROFILE }) bot .on('login' , user => log.info('Bot', `${user.name()} logined`)) @@ -84,3 +84,4 @@ require('fs').appendFile('message.log', data + '\n\n############################ if (err) { log.error('LogToFile: %s', err) } }) } +typeof logToFile; diff --git a/example/friend-bot.ts b/example/friend-bot.ts index 57e278a9..8b40a415 100644 --- a/example/friend-bot.ts +++ b/example/friend-bot.ts @@ -6,12 +6,12 @@ * https://github.com/wechaty/wechaty * */ -const { +import { Wechaty , Message , Config , log -} = require('../') +} from '../' const welcome = ` =============== Powered by Wechaty =============== @@ -38,7 +38,7 @@ Please wait... I'm trying to login in... ` console.log(welcome) -const bot = new Wechaty({ profile: Config.DEFAULT_PROFILE }) +const bot = Wechaty.instance({ profile: Config.DEFAULT_PROFILE }) bot .on('login' , user => log.info('Bot', `${user.name()} logined`)) diff --git a/example/image-bot.ts b/example/image-bot.ts index e647cace..291e1b56 100644 --- a/example/image-bot.ts +++ b/example/image-bot.ts @@ -6,8 +6,11 @@ * https://github.com/wechaty/wechaty * */ -const Wechaty = require('..') -const bot = new Wechaty({ profile: 'example-bot.wechaty.json' }) +import { + Message + , Wechaty +} from '../' +const bot = Wechaty.instance({ profile: 'example-bot.wechaty.json' }) bot .on('scan', ({url, code}) => { @@ -16,7 +19,7 @@ bot .on('message', m => { console.log(`RECV: ${m}`) - if (m.type() === Wechaty.Message.Type.IMAGE) { + if (m.type() === Message.TYPE['IMAGE']) { console.log('IMAGE url: ' + m.get('url')) const filename = m.id + '.jpg' console.log('IMAGE local filename: ' + filename) diff --git a/example/roger-bot.ts b/example/roger-bot.ts index aa1ee53e..25adc0e9 100644 --- a/example/roger-bot.ts +++ b/example/roger-bot.ts @@ -6,15 +6,15 @@ * https://github.com/wechaty/wechaty * */ -const Wechaty = require('..') -const bot = new Wechaty(/* no profile here because roger bot is too noisy */) +import { Wechaty } from '../' +const bot = Wechaty.instance(/* no profile here because roger bot is too noisy */) bot .on('scan', ({url, code}) => { console.log(`Use Wechat to Scan QR Code in url to login: ${code}\n${url}`) }) .on('message', m => { - (!bot.self(m)) && reply('roger') // 1. reply others' msg + (!bot.self(m)) && m.say('roger') // 1. reply others' msg .then(() => console.log(`RECV: ${m}, REPLY: "roger"`)) // 2. log message .catch(e => console.error(e)) // 3. catch exception }) diff --git a/example/room-bot.ts b/example/room-bot.ts index 9a6e66b3..948f07e4 100644 --- a/example/room-bot.ts +++ b/example/room-bot.ts @@ -76,7 +76,7 @@ bot log.info('Bot', `${user.name()} logined`) log.info('Bot', `setting to manageDingRoom() after 3 seconds ... `) - setTimeout(_ => manageDingRoom(), 3000) + setTimeout(manageDingRoom.bind(this), 3000) }) /** @@ -230,7 +230,7 @@ function manageDingRoom() { /** * Event: Join */ - room.on('join', (invitee, inviter) => + room.on('join', (invitee: Contact|Contact[], inviter: Contact) => checkRoomJoin.call(this, room, invitee, inviter) ) @@ -257,7 +257,10 @@ function manageDingRoom() { }) } -function checkRoomJoin(room: Room, invitee: Contact|Contact[], inviter: Contact) { +function checkRoomJoin(room: Room, invitee: Contact , inviter: Contact) +function checkRoomJoin(room: Room, invitee: Contact[] , inviter: Contact) +function checkRoomJoin(room: Room, invitee: Contact|Contact[] , inviter: Contact) { + log.info('Bot', 'checkRoomJoin(%s, %s, %s)' , room.topic() , Array.isArray(invitee) diff --git a/example/tuling123-bot.ts b/example/tuling123-bot.ts index 501f4fe9..85b15998 100644 --- a/example/tuling123-bot.ts +++ b/example/tuling123-bot.ts @@ -10,16 +10,17 @@ * Wechaty - https://github.com/zixia/wechaty * */ -const log = require('npmlog') -const co = require('co') const Tuling123 = require('tuling123-client') -const EventEmitter2 = require('eventemitter2') -const { - Wechaty - , Config -} = require -('../') +import { EventEmitter } from 'events' + +import { + Config + , Room + , Wechaty + , log +} from '../' + //log.level = 'verbose' // log.level = 'silly' @@ -32,9 +33,7 @@ const { const TULING123_API_KEY = '18f25157e0446df58ade098479f74b21' const brain = new Tuling123(TULING123_API_KEY) -const bot = new Wechaty({ - profile: Config.DEFAULT_PROFILE -}) +const bot = Wechaty.instance({ profile: Config.DEFAULT_PROFILE }) console.log(` Welcome to Tuling Wechaty Bot. @@ -52,12 +51,13 @@ bot .on('scan', ({url, code}) => { console.log(`Scan QR Code in url to login: ${code}\n${url}`) }) -.on('message', m => { +.on('message', async m => { if (bot.self(m)) return - co(function* () { - const msg = yield m.ready() - const room = Wechaty.Room.load(m.get('room')) + // co(function* () { + try { + const msg = await m.ready() + const room = Room.load(m.get('room')) if (room && /Wechaty/i.test(room.get('name'))) { log.info('Bot', 'talk: %s' , msg) @@ -65,8 +65,10 @@ bot } else { log.info('Bot', 'recv: %s' , msg) } - }) - .catch(e => log.error('Bot', 'on message rejected: %s' , e)) + // }).catch(e => { + } catch (e) { + log.error('Bot', 'on message rejected: %s' , e) + } }) bot.init() @@ -76,16 +78,20 @@ bot.init() process.exit(-1) }) -class Talker extends EventEmitter2 { - constructor(thinker) { - log.verbose('Talker()') +class Talker extends EventEmitter { + private obj: { + text: any + time: any + } + private timer: number + + constructor(private thinker) { super() - this.thinker = thinker + log.verbose('Talker()') this.obj = { text: [] , time: [] } - this.timer = null } save(text) { @@ -101,7 +107,7 @@ class Talker extends EventEmitter2 { return text } - updateTimer(delayTime) { + updateTimer(delayTime?) { delayTime = delayTime || this.delayTime() log.verbose('Talker', 'updateTimer(%s)', delayTime) diff --git a/src/wechaty-event.ts b/src/event-scope.ts similarity index 80% rename from src/wechaty-event.ts rename to src/event-scope.ts index fb2dc080..60109c2a 100755 --- a/src/wechaty-event.ts +++ b/src/event-scope.ts @@ -13,14 +13,20 @@ import Config from './config' import Contact from './contact' import Message from './message' -// import Room from './room' +import Room from './room' +import Wechaty from './wechaty' import log from './brolog-env' -type EventScope = { +type WechatyEventScope = { say: (content: string, replyTo?: Contact|Contact[]) => void } +type WechatyEventType = 'error' | 'heartbeat' + | 'login' | 'logout' + | 'message' | 'scan' | 'friend' + | 'room-join' | 'room-leave' | 'room-topic' + const EVENT_CONFIG = { error: wrapFilehelper , friend: wrapContact @@ -34,12 +40,12 @@ const EVENT_CONFIG = { , scan: null // NULL } -class WechatyEvent { +class EventScope { public static list() { return Object.keys(EVENT_CONFIG) } - public static wrap(event, callback) { + public static wrap(this: Wechaty|Room, event: WechatyEventType, callback: Function) { log.verbose('WechatyEvent', 'wrap(%s, %s)', event, typeof callback) // if (!(this instanceof Wechaty)) { @@ -98,7 +104,7 @@ function wrapContact(callback) { const contact = argList[0] - const eventScope = {} + const eventScope = {} eventScope.say = (content) => { const msg = new Message() msg.to(contact) @@ -114,23 +120,22 @@ function wrapContact(callback) { function wrapRoom(callback) { log.verbose('WechatyEvent', 'wrapRoom()') - return (...argList) => { - log.silly('WechatyEvent', 'wrapRoom() callback') - let room, contact + return (room: Room, ...argList) => { + log.silly('WechatyEvent', 'wrapRoom(%s, %s, %s, %s) callback', room.topic(), argList[0], argList[1], argList[2]) + + let contact for (let arg of argList) { - if (!room && isRoom(arg)) { - room = arg - } else if (!contact && isContact(arg)) { + if (!contact && isContact(arg)) { contact = arg } } - if (!room || !contact) { + if (!room || !isRoom(room) || !contact) { throw new Error('room or contact not found') } - const eventScope = {} - eventScope.say = (content, replyTo = null) => { + const eventScope = {} + eventScope.say = (content: string, replyTo?: Contact) => { if (!replyTo) { replyTo = contact } else if (!isContact(replyTo)) { @@ -139,7 +144,7 @@ function wrapRoom(callback) { return room.say(content, replyTo) } - return callback.apply(eventScope, argList) + return callback.apply(eventScope, [room, ...argList]) } } @@ -162,7 +167,7 @@ function wrapMessage(callback) { // const receiver = msg.to() const room = msg.room() - const eventScope = {} + const eventScope = {} eventScope.say = (content, replyTo) => { log.silly('WechatyEvent', 'wrapMessage() say("%s", "%s")', content, replyTo) @@ -187,7 +192,7 @@ function wrapFilehelper(callback) { return (...argList) => { log.silly('WechatyEvent', 'wrapFilehelper() callback') - const eventScope = {} + const eventScope = {} eventScope.say = (content) => { log.silly('WechatyEvent', 'wrapFilehelper() say(%s)', content) const msg = new Message() @@ -202,4 +207,4 @@ function wrapFilehelper(callback) { } // module.exports = WechatyEvent.default = WechatyEvent -export default WechatyEvent +export default EventScope diff --git a/src/puppet-web/firer.ts b/src/puppet-web/firer.ts index 0337e9f1..7323d5ef 100644 --- a/src/puppet-web/firer.ts +++ b/src/puppet-web/firer.ts @@ -21,7 +21,7 @@ const retryPromise = require('retry-promise').default import Contact from '../contact' -// import Message from '../message' +import Message from '../message' import log from '../brolog-env' import FriendRequest from './friend-request' @@ -53,12 +53,14 @@ const regexConfig = { , roomTopic: /^"?(.+?)"? changed the group name to "(.+)"$/ } -function fireFriendRequest(m) { +async function fireFriendRequest(m) { const info = m.rawObj.RecommendInfo log.verbose('PuppetWebFirer', 'fireFriendRequest(%s)', info) const request = new FriendRequest() request.receive(info) + + await request.contact.ready() this.emit('friend', request.contact, request) } @@ -74,7 +76,7 @@ function checkFriendConfirm(content) { } } -function fireFriendConfirm(m) { +async function fireFriendConfirm(m) { const content = m.content() log.silly('PuppetWebFirer', 'fireFriendConfirm(%s)', content) @@ -85,6 +87,7 @@ function fireFriendConfirm(m) { const contact = Contact.load(m.get('from')) request.confirm(contact) + await contact.ready() this.emit('friend', contact) } @@ -98,15 +101,16 @@ function fireFriendConfirm(m) { * "李卓桓.PreAngel" invited "Bruce LEE" to the group chat * "凌" invited "庆次、小桔妹" to the group chat */ -function checkRoomJoin(content): [string|string[], string] | boolean { +function checkRoomJoin(content: string): [string[], string] { log.verbose('PuppetWebFirer', 'checkRoomJoin()') const re = regexConfig.roomJoin const found = content.match(re) if (!found) { - return false + throw new Error('checkRoomJoin() not found') } + const [, inviter, inviteeStr] = found // "凌" invited "庆次、小桔妹" to the group chat @@ -115,19 +119,25 @@ function checkRoomJoin(content): [string|string[], string] | boolean { return [inviteeList, inviter] // put invitee at first place } -async function fireRoomJoin(m): Promise { +async function fireRoomJoin(m: Message): Promise { log.verbose('PuppetWebFirer', 'fireRoomJoin()') const room = m.room() const content = m.content() - let result = checkRoomJoin(content) - if (!result) { + let inviteeList: string[], inviter: string + try { + [inviteeList, inviter] = checkRoomJoin(content) + } catch (e) { // not a room join message return } - const [inviteeList, inviter] = <[string[], string]>result + log.silly('PuppetWebFirer', 'fireRoomJoin() inviteeList: %s, inviter: %s' + , inviteeList.join(',') + , inviter + ) - let inviterContact, inviteeContactList = [] + let inviterContact: Contact + let inviteeContactList: Contact[] = [] // co.call(this, function* () { try { @@ -147,18 +157,17 @@ async function fireRoomJoin(m): Promise { return room.refresh() .then(_ => { - log.silly('PuppetWebFirer', 'inviteeList: %s, inviter: %s' - , inviteeList.join(',') - , inviter - ) - let iDone, allDone = true for (let i in inviteeList) { iDone = inviteeContactList[i] instanceof Contact if (!iDone) { - inviteeContactList[i] = room.member(inviteeList[i]) - || (allDone = false) + let c = room.member(inviteeList[i]) + if (c) { + inviteeContactList[i] = c + } else { + allDone = false + } } } @@ -168,20 +177,20 @@ async function fireRoomJoin(m): Promise { if (allDone && inviterContact) { log.silly('PuppetWebFirer', 'fireRoomJoin() resolve() inviteeContactList: %s, inviterContact: %s' - , inviteeContactList.join(',') - , inviterContact + , inviteeContactList.map((c: Contact) => c.name()).join(',') + , inviterContact.name() ) return Promise.resolve() } else { log.silly('PuppetWebFirer', 'fireRoomJoin() reject() inviteeContactList: %s, inviterContact: %s' - , inviteeContactList.join(',') - , inviterContact + , inviteeContactList.map((c: Contact) => c.name()).join(',') + , inviterContact.name() ) return Promise.reject('not found(yet)') } }) .catch(e => { - log.error('PuppetWebFirer', 'fireRoomJoin9() retryPromise() room.refresh() rejected: %s', e.stack) + log.error('PuppetWebFirer', 'fireRoomJoin() retryPromise() room.refresh() rejected: %s', e.stack) throw e }) }) @@ -198,6 +207,7 @@ async function fireRoomJoin(m): Promise { await Promise.all(inviteeContactList.map(c => c.ready())) await inviterContact.ready() + await room.ready() if (inviteeContactList.length === 1) { this.emit('room-join', room , inviteeContactList[0], inviterContact) @@ -215,12 +225,12 @@ async function fireRoomJoin(m): Promise { return } -function checkRoomLeave(content) { +function checkRoomLeave(content: string): string { const re = regexConfig.roomLeave const found = content.match(re) if (!found) { - return false + return null } const [, leaver] = found return leaver @@ -283,32 +293,32 @@ async function fireRoomLeave(m) { return } - leaverContact.ready() - .then(_ => { - this.emit('room-leave', room, leaverContact) - room.emit('leave' , leaverContact) - room.refresh() - }) + await leaverContact.ready() + await room.ready() + this.emit('room-leave', room, leaverContact) + room.emit('leave' , leaverContact) + await room.refresh() } -function checkRoomTopic(content): [string, string] | boolean { +function checkRoomTopic(content): [string, string] { const re = regexConfig.roomTopic const found = content.match(re) if (!found) { - return false + throw new Error('checkRoomTopic() not found') } const [, changer, topic] = found return [topic, changer] } async function fireRoomTopic(m) { - const result = checkRoomTopic(m.content()) - if (!result) { + let topic, changer + try { + [topic, changer] = checkRoomTopic(m.content()) + } catch (e) { // not found return } - const [topic, changer] = <[string, string]>result const room = m.room() const oldTopic = room.topic() @@ -327,6 +337,7 @@ async function fireRoomTopic(m) { // co.call(this, function* () { try { await changerContact.ready() + await room.ready() this.emit('room-topic', room, topic, oldTopic, changerContact) room.emit('topic' , topic, oldTopic, changerContact) room.refresh() diff --git a/src/room.ts b/src/room.ts index 2fa0816e..d7e6618c 100644 --- a/src/room.ts +++ b/src/room.ts @@ -10,13 +10,13 @@ */ import { EventEmitter } from 'events' -import Config from './config' -import Contact from './contact' -import Message from './message' -import UtilLib from './util-lib' -import WechatyEvent from './wechaty-event' +import Config from './config' +import Contact from './contact' +import Message from './message' +import UtilLib from './util-lib' +import EventScope from './event-scope' -import log from './brolog-env' +import log from './brolog-env' type RoomObj = { id: string @@ -109,17 +109,19 @@ class Room extends EventEmitter { }) } - public on(event: string, listener: Function) { + public on( event: 'join' | 'leave' | 'topic' + , listener: Function + ) { log.verbose('Room', 'on(%s, %s)', event, typeof listener) /** * every room event must can be mapped to a global event. * such as: `join` to `room-join` */ - const wrapCallback = WechatyEvent.wrap.call(this, 'room-' + event, listener) + const callbackWithScope = EventScope.wrap.call(this, 'room-' + event, listener) // bind(this1, this2): the second this is for simulate the global room-* event - super.on(event, wrapCallback.bind(this, this)) + super.on(event, callbackWithScope.bind(this, this)) return this } @@ -297,7 +299,10 @@ class Room extends EventEmitter { } } - public member(name): Contact { + /** + * NickName / DisplayName / RemarkName of member + */ + public member(name: string): Contact { log.verbose('Room', 'member(%s)', name) if (!this.obj || !this.obj.memberList) { diff --git a/src/wechaty.ts b/src/wechaty.ts index 9712c540..f9042f94 100644 --- a/src/wechaty.ts +++ b/src/wechaty.ts @@ -23,7 +23,7 @@ import Message from './message' import Puppet from './puppet' import PuppetWeb from './puppet-web/index' import UtilLib from './util-lib' -import WechatyEvent from './wechaty-event' +import EventScope from './event-scope' import log from './brolog-env' @@ -155,7 +155,7 @@ class Wechaty extends EventEmitter { public on(event: string, listener: Function) { log.verbose('Wechaty', 'on(%s, %s)', event, typeof listener) - const wrapListener = WechatyEvent.wrap.call(this, event, listener) + const wrapListener = EventScope.wrap.call(this, event, listener) super.on(event, wrapListener) return this @@ -174,7 +174,7 @@ class Wechaty extends EventEmitter { throw new Error('Puppet unsupport(yet): ' + this.setting.type) } - WechatyEvent.list().map(e => { + EventScope.list().map(e => { // https://strongloop.com/strongblog/an-introduction-to-javascript-es6-arrow-functions/ // We’ve lost () around the argument list when there’s just one argument (rest arguments are an exception, eg (...args) => ...) puppet.on(e, (...args) => { diff --git a/tsconfig.json b/tsconfig.json index f04a76d0..e20db4d1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,8 +23,8 @@ ] , "include": [ "src/**/*.ts" - // , "bin/*.ts" - , "example/room-bot.ts" + , "bin/*.ts" + , "example/*.ts" // , "test/*.ts" ] } -- GitLab