From e418ccc83ad0a8a5e26be6c52d372d4e63fa4458 Mon Sep 17 00:00:00 2001 From: Huan LI Date: Sat, 9 Jun 2018 03:37:32 +0800 Subject: [PATCH] room.topic() from sync to async, with default values (#1295) --- examples/api-ai-bot.ts | 4 +- examples/gist-bot/on-message.ts | 2 +- examples/gist-bot/on-room-join.ts | 4 +- examples/hot-reload-bot/listener/message.js | 2 +- examples/monster/listeners/on-message.js | 2 +- examples/room-bot.ts | 18 +++---- examples/self-testing-bot.ts | 23 +++++---- src/message.ts | 7 ++- src/puppet-padchat/bridge.ts | 56 +++++++++++++++------ src/puppet-padchat/padchat-rpc.ts | 8 +-- src/puppet-padchat/pure-function-helper.ts | 2 + src/puppet-puppeteer/puppeteer-room.spec.ts | 2 +- src/puppet/puppet.ts | 19 ++++--- src/room.ts | 25 ++++++--- 14 files changed, 112 insertions(+), 62 deletions(-) diff --git a/examples/api-ai-bot.ts b/examples/api-ai-bot.ts index 4499cdc0..bffd61a2 100644 --- a/examples/api-ai-bot.ts +++ b/examples/api-ai-bot.ts @@ -79,14 +79,14 @@ bot }) .on('login' , user => log.info('Bot', `bot login: ${user}`)) .on('logout' , user => log.info('Bot', 'bot %s logout.', user)) -.on('message', m => { +.on('message', async m => { if (m.self()) { return } // co(function* () { // const msg = yield m.load() const room = m.room() - if (room && /Wechaty/i.test(room.topic())) { + if (room && /Wechaty/i.test(await room.topic())) { log.info('Bot', 'talk: %s' , m) talk(m) } else { diff --git a/examples/gist-bot/on-message.ts b/examples/gist-bot/on-message.ts index 64048d81..dee607d0 100644 --- a/examples/gist-bot/on-message.ts +++ b/examples/gist-bot/on-message.ts @@ -33,7 +33,7 @@ export async function onMessage(this: Wechaty, message: Message): Promise const sender = message.from() const content = message.text() - console.log((room ? '[' + room.topic() + ']' : '') + console.log((room ? '[' + await room.topic() + ']' : '') + '<' + sender.name() + '>' + ':' + message, ) diff --git a/examples/gist-bot/on-room-join.ts b/examples/gist-bot/on-room-join.ts index 9923abbc..de0d1466 100644 --- a/examples/gist-bot/on-room-join.ts +++ b/examples/gist-bot/on-room-join.ts @@ -42,8 +42,8 @@ export async function onRoomJoin( * */ - if (room.topic() !== 'ding') { - await this.say('Room ' + room.topic() + if (await room.topic() !== 'ding') { + await this.say('Room ' + await room.topic() + ' got new memeber ' + inviteeName + ' invited by ' + inviter.name(), ) diff --git a/examples/hot-reload-bot/listener/message.js b/examples/hot-reload-bot/listener/message.js index 305c6b63..66741a7e 100644 --- a/examples/hot-reload-bot/listener/message.js +++ b/examples/hot-reload-bot/listener/message.js @@ -21,7 +21,7 @@ exports = module.exports = async function onMessage (message) { const sender = message.from(); const content = message.text(); - const topic = room ? '[' + room.topic() + ']' : ''; + const topic = room ? '[' + await room.topic() + ']' : ''; console.log(`${topic} <${sender.name()}> : ${message.toStringDigest()}`); diff --git a/examples/monster/listeners/on-message.js b/examples/monster/listeners/on-message.js index 81e590d1..23eeaf7a 100644 --- a/examples/monster/listeners/on-message.js +++ b/examples/monster/listeners/on-message.js @@ -35,7 +35,7 @@ export default async function onMessage (message) { const room = message.room() const sender = message.from() const content = message.text() - const roomName = room ? `[${room.topic()}] ` : '' + const roomName = room ? `[${await room.topic()}] ` : '' process.stdout.write( `${roomName}<${sender.name()}>(${message.type()}:${message.typeSub()}): `) diff --git a/examples/room-bot.ts b/examples/room-bot.ts index cd3e7ce9..1e636250 100644 --- a/examples/room-bot.ts +++ b/examples/room-bot.ts @@ -121,9 +121,9 @@ bot /** * Global Event: room-join */ -.on('room-join', function(this, room, inviteeList, inviter) { +.on('room-join', async function(this, room, inviteeList, inviter) { log.info( 'Bot', 'EVENT: room-join - Room %s got new member %s, invited by %s', - room.topic(), + await room.topic(), inviteeList.map(c => c.name()).join(','), inviter.name(), ) @@ -132,9 +132,9 @@ bot /** * Global Event: room-leave */ -.on('room-leave', function(this, room, leaverList) { +.on('room-leave', async function(this, room, leaverList) { log.info('Bot', 'EVENT: room-leave - Room %s lost member %s', - room.topic(), + await room.topic(), leaverList.map(c => c.name()).join(','), ) }) @@ -163,7 +163,7 @@ bot const sender = message.from() const content = message.text() - console.log((room ? '[' + room.topic() + ']' : '') + console.log((room ? '[' + await room.topic() + ']' : '') + '<' + sender.name() + '>' + ':' + message, ) @@ -182,7 +182,7 @@ bot * in-room message */ if (room) { - if (/^ding/i.test(room.topic())) { + if (/^ding/i.test(await room.topic())) { /** * move contact out of room */ @@ -297,7 +297,7 @@ async function manageDingRoom() { async function checkRoomJoin(room: Room, inviteeList: Contact[], inviter: Contact) { log.info('Bot', 'checkRoomJoin(%s, %s, %s)', - room.topic(), + await room.topic(), inviteeList.map(c => c.name()).join(','), inviter.name(), ) @@ -315,7 +315,7 @@ async function checkRoomJoin(room: Room, inviteeList: Contact[], inviter: Contac inviteeList, ) - room.topic('ding - warn ' + inviter.name()) + await room.topic('ding - warn ' + inviter.name()) setTimeout( _ => inviteeList.forEach(c => room.del(c)), 10 * 1000, @@ -337,7 +337,7 @@ async function checkRoomJoin(room: Room, inviteeList: Contact[], inviter: Contac } async function putInRoom(contact: Contact, room: Room) { - log.info('Bot', 'putInRoom(%s, %s)', contact.name(), room.topic()) + log.info('Bot', 'putInRoom(%s, %s)', contact.name(), await room.topic()) try { await room.add(contact) diff --git a/examples/self-testing-bot.ts b/examples/self-testing-bot.ts index 4249434c..444db790 100644 --- a/examples/self-testing-bot.ts +++ b/examples/self-testing-bot.ts @@ -96,26 +96,29 @@ bot const from = msg.from() // Room.findAll() - if (/^testRoom$/.test(text)) { + if (/^testRoom$/i.test(text)) { const roomList = await bot.Room.findAll() + const topicList = await Promise.all( + roomList.map(async room => await room.topic()), + ) + let n = 0 - from.say( - roomList - .map(room => room.topic()) - .map(topic => n++ + '. ' + topic) + await from.say( + topicList + .map(topic => ++n + '. ' + topic) .join('\n'), ) return } // Contact.findAll() - if (/^testContact$/.test(text)) { + if (/^testContact$/i.test(text)) { const contactList = await bot.Contact.findAll() let n = 0 - from.say( + await from.say( contactList .map(contact => contact.name()) - .map(name => n++ + '. ' + name) + .map(name => ++n + '. ' + name) .join('\n'), ) return @@ -131,14 +134,14 @@ bot console.error('contact not found') return } - msg.forward(contact) + await msg.forward(contact) return } if (/^froom$/.test(text)) { console.log('begin to check msg forward room') const room = bot.Room.load('6350854677@chatroom') - msg.forward(room) + await msg.forward(room) return } diff --git a/src/message.ts b/src/message.ts index c577dad5..b7fef044 100644 --- a/src/message.ts +++ b/src/message.ts @@ -156,7 +156,6 @@ export class Message extends Accessory implements Sayable { const msgStrList = [ 'Message', - // `#${MessageDirection[this.direction]}`, `#${MessageType[this.type()]}`, '(', this.room() ? (this.room() + '▲') : '', @@ -177,7 +176,11 @@ export class Message extends Accessory implements Sayable { } const filename = this.payload.filename if (!filename) { - throw new Error('no file for message id: ' + this.id + ' with type: ' + this.payload.type) + throw new Error( + 'no file for message id: ' + this.id + + ' with type: ' + Message.Type[this.payload.type] + + '(' + this.payload.type + ')', + ) } msgStrList.push(`<${filename}>`) } diff --git a/src/puppet-padchat/bridge.ts b/src/puppet-padchat/bridge.ts index 18609e73..123cb2a5 100644 --- a/src/puppet-padchat/bridge.ts +++ b/src/puppet-padchat/bridge.ts @@ -124,11 +124,19 @@ export class Bridge extends EventEmitter { await this.padchatRpc.start() this.padchatRpc.on('message', messageRawPayload => { - log.silly('PuppetPadchatBridge', `start() padchatRpc.on('message')`) + log.silly('PuppetPadchatBridge', 'start() padchatRpc.on(message)') this.emit('message', messageRawPayload) }) + this.padchatRpc.on('logout', data => { + log.silly('PuppetPadchatBridge', 'start() padchatRpc.on(logout, %s)', data) + if (this.selfId) { + this.selfId = undefined + this.emit('logout', data) + } else { + log.warn('PuppetPadchatBridge', 'start() padchatRpc.on(logout) received `logout` event when no `selfId`') + } + }) - // TODO: 顺序变一下,要check user_name 的 await this.loadAutoData() const restoreSucceed = await this.restoreLogin() @@ -228,6 +236,8 @@ export class Bridge extends EventEmitter { if (result.expired_time && result.expired_time < 10) { // result.expire_time is second // emit new qrcode before the old one expired + this.loginScanQrCode = undefined + this.loginScanStatus = undefined waitUserResponse = false } @@ -331,6 +341,24 @@ export class Bridge extends EventEmitter { * "user_name": "wxid_5zj4i5htp9ih22" * } */ + + /** + * WXAutoLoginresult: { + * "email": "", + * "external": "", + * "long_link_server": "", + * "message": "\n�\u0002\n1\n\n + * \n30\n<![CDATA[]]>\n4\n + * 0\n0\n\n\n\n", + * "nick_name": "", + * "phone_number": "", + * "qq": 0, + * "short_link_server": "", + * "status": -2023, + * "uin": 4763975, + * "user_name": "lizhuohuan" + * } + */ const autoLoginResult = await this.padchatRpc.WXAutoLogin(this.autoData.token) if (!autoLoginResult) { @@ -538,12 +566,10 @@ export class Bridge extends EventEmitter { continue } - log.verbose('PuppetPadchatBridge', 'syncContactsAndRooms() sync contact, got new/total: %d/%d', - syncContactList.length, - ( - Object.keys(this.cacheContactRawPayload).length - + Object.keys(this.cacheRoomRawPayload).length - ), + log.verbose('PuppetPadchatBridge', 'syncContactsAndRooms() adding new %d to Contact(%d) & Room(%d) ...', + syncContactList.length, + Object.keys(this.cacheContactRawPayload).length, + Object.keys(this.cacheRoomRawPayload).length, ) for (const syncContact of syncContactList) { @@ -555,16 +581,14 @@ export class Bridge extends EventEmitter { } if (syncContact.msg_type === PadchatContactMsgType.Contact) { - log.verbose('PuppetPadchatBridge', 'syncContactsAndRooms() sync for %s(%s)', - syncContact.nick_name, - syncContact.user_name, - ) - if (pfHelper.isRoomId(syncContact.user_name)) { // /@chatroom$/.test(syncContact.user_name)) { /** * Room */ - // user_name or chatroom_id ? + log.verbose('PuppetPadchatBridge', 'syncContactsAndRooms() sync Room %s(%s)', + syncContact.nick_name, + syncContact.user_name, + ) const roomId = syncContact.user_name const roomPayload = syncContact as PadchatRoomPayload @@ -575,6 +599,10 @@ export class Bridge extends EventEmitter { /** * Contact */ + log.verbose('PuppetPadchatBridge', 'syncContactsAndRooms() sync Contact %s(%s)', + syncContact.nick_name, + syncContact.user_name, + ) const contactPayload = syncContact as PadchatContactPayload const contactId = contactPayload.user_name diff --git a/src/puppet-padchat/padchat-rpc.ts b/src/puppet-padchat/padchat-rpc.ts index c4d52c6e..e8f93115 100644 --- a/src/puppet-padchat/padchat-rpc.ts +++ b/src/puppet-padchat/padchat-rpc.ts @@ -188,7 +188,7 @@ export class PadchatRpc extends EventEmitter { apiName : string, ...params : string[] ): Promise { - log.silly('PadchatRpc', 'rpcCall(%s, %s)', apiName, JSON.stringify(params)) + log.silly('PadchatRpc', 'rpcCall(%s, %s)', apiName, JSON.stringify(params).substr(0, 500)) return await this.jsonRpc.request(apiName, params) } @@ -200,11 +200,13 @@ export class PadchatRpc extends EventEmitter { // console.log('server payload:', payload) if (payload.type === PadchatPayloadType.Logout) { - log.verbose('PadchatRpc', 'onSocket(payload.type=%s) logout, payload=%s', + // {"type":-1,"msg":"掉线了"} + log.verbose('PadchatRpc', 'onSocket(payload.type=%s) logout, payload=%s(%s)', + PadchatPayloadType[payload.type], payload.type, JSON.stringify(payload), ) - this.emit('logout') + this.emit('logout', payload.msg) return } diff --git a/src/puppet-padchat/pure-function-helper.ts b/src/puppet-padchat/pure-function-helper.ts index b0d1aa60..7d0179b4 100644 --- a/src/puppet-padchat/pure-function-helper.ts +++ b/src/puppet-padchat/pure-function-helper.ts @@ -135,6 +135,8 @@ export class PadchatPureFunctionHelper { rawPayload: PadchatMessagePayload, ): MessagePayload { + console.log(rawPayload) + let type: MessageType switch (rawPayload.sub_type) { diff --git a/src/puppet-puppeteer/puppeteer-room.spec.ts b/src/puppet-puppeteer/puppeteer-room.spec.ts index 371ae4e1..9c789267 100755 --- a/src/puppet-puppeteer/puppeteer-room.spec.ts +++ b/src/puppet-puppeteer/puppeteer-room.spec.ts @@ -106,7 +106,7 @@ test('Room smok testing', async t => { // t.is((r as any).payload[.('encryId') , EXPECTED.encryId, 'should set EncryChatRoomId') - t.is(room.topic(), ROOM_EXPECTED.topic, 'should set topic/NickName') + t.is(await room.topic(), ROOM_EXPECTED.topic, 'should set topic/NickName') const contact1 = new wechaty.Contact(ROOM_EXPECTED.memberId1) const alias1 = await room.alias(contact1) diff --git a/src/puppet/puppet.ts b/src/puppet/puppet.ts index 84dba8d8..c1eaa472 100644 --- a/src/puppet/puppet.ts +++ b/src/puppet/puppet.ts @@ -445,9 +445,9 @@ export abstract class Puppet extends EventEmitter implements Sayable { const cachedPayload = this.cacheContactPayload.get(contactId) if (cachedPayload) { - log.silly('Puppet', 'contactPayload() cache HIT') + log.silly('Puppet', 'contactPayload(%s) cache HIT', contactId) } else { - log.silly('Puppet', 'contactPayload() cache MISS') + log.silly('Puppet', 'contactPayload(%s) cache MISS', contactId) } return cachedPayload @@ -508,9 +508,9 @@ export abstract class Puppet extends EventEmitter implements Sayable { const cachedPayload = this.cacheFriendRequestPayload.get(friendRequestId) if (cachedPayload) { - log.silly('Puppet', 'friendRequestPayload() cache HIT') + log.silly('Puppet', 'friendRequestPayload(%s) cache HIT', friendRequestId) } else { - log.silly('Puppet', 'friendRequestPayload() cache MISS') + log.silly('Puppet', 'friendRequestPayload(%s) cache MISS', friendRequestId) } return cachedPayload @@ -571,9 +571,9 @@ export abstract class Puppet extends EventEmitter implements Sayable { } const cachedPayload = this.cacheMessagePayload.get(messageId) if (cachedPayload) { - log.silly('Puppet', 'messagePayloadCache() cache HIT') + log.silly('Puppet', 'messagePayloadCache(%s) cache HIT', messageId) } else { - log.silly('Puppet', 'messagePayloadCache() cache MISS') + log.silly('Puppet', 'messagePayloadCache(%s) cache MISS', messageId) } return cachedPayload @@ -717,7 +717,6 @@ export abstract class Puppet extends EventEmitter implements Sayable { id => this.roomPayload(id), ), ) - console.log('roomPayload resolved.') const filterFunction = this.roomQueryFilterFactory(query) @@ -725,7 +724,7 @@ export abstract class Puppet extends EventEmitter implements Sayable { .filter(filterFunction) .map(payload => payload.id) - console.log('roomIdList filtered. result length=' + roomIdList.length) + log.silly('Puppet', 'roomSearch() roomIdList filtered. result length=%d', roomIdList.length) return roomIdList } @@ -772,9 +771,9 @@ export abstract class Puppet extends EventEmitter implements Sayable { } const cachedPayload = this.cacheRoomPayload.get(roomId) if (cachedPayload) { - log.silly('Puppet', 'roomPayloadCache() cache HIT') + log.silly('Puppet', 'roomPayloadCache(%s) cache HIT', roomId) } else { - log.silly('Puppet', 'roomPayloadCache() cache MISS') + log.silly('Puppet', 'roomPayloadCache(%s) cache MISS', roomId) } return cachedPayload diff --git a/src/room.ts b/src/room.ts index a6c5d695..d1d1b45a 100644 --- a/src/room.ts +++ b/src/room.ts @@ -470,14 +470,14 @@ export class Room extends Accessory implements Sayable { await this.puppet.roomQuit(this.id) } - public topic() : string - public topic(newTopic: string): Promise + public async topic() : Promise + public async topic(newTopic: string): Promise /** * SET/GET topic from the room * * @param {string} [newTopic] If set this para, it will change room topic. - * @returns {(string | void)} + * @returns {Promise} * * @example When you say anything in a room, it will get room topic. * const bot = Wechaty.instance() @@ -485,7 +485,7 @@ export class Room extends Accessory implements Sayable { * .on('message', async m => { * const room = m.room() * if (room) { - * const topic = room.topic() + * const topic = await room.topic() * console.log(`room topic is : ${topic}`) * } * }) @@ -502,7 +502,7 @@ export class Room extends Accessory implements Sayable { * } * }) */ - public topic(newTopic?: string): string | Promise { + public async topic(newTopic?: string): Promise { log.verbose('Room', 'topic(%s)', newTopic ? newTopic : '') if (!this.isReady()) { log.warn('Room', 'topic() room not ready') @@ -510,7 +510,20 @@ export class Room extends Accessory implements Sayable { } if (typeof newTopic === 'undefined') { - return this.payload && this.payload.topic || '' + if (this.payload && this.payload.topic) { + return this.payload.topic + } else { + const memberIdList = await this.puppet.roomMemberList(this.id) + const memberList = memberIdList + .filter(id => id !== this.puppet.selfId()) + .map(id => this.wechaty.Contact.load(id)) + + let defaultTopic = memberList[0].name() + for (let i = 1; i < 3 && memberList[i]; i++) { + defaultTopic += ',' + memberList[i].name() + } + return defaultTopic + } } const future = this.puppet -- GitLab