Skip to content

Commit

Permalink
PuppetPadchat: FriendRequest.accept() & Fix + Decode error. (#1254 #…
Browse files Browse the repository at this point in the history
  • Loading branch information
huan committed Jun 9, 2018
1 parent d9e218a commit 197b19e
Show file tree
Hide file tree
Showing 16 changed files with 94 additions and 73 deletions.
6 changes: 4 additions & 2 deletions examples/friend-bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ bot
case FriendRequest.Type.Receive:
if (request.hello() === 'ding') {
logMsg = 'accepted automatically because verify messsage is "ding"'
request.accept()
console.log('before accept')
await request.accept()
console.log('after accept')

} else {
logMsg = 'not auto accepted, because verify message is: ' + request.hello
logMsg = 'not auto accepted, because verify message is: ' + request.hello()
}
break

Expand Down
2 changes: 1 addition & 1 deletion examples/hot-import-bot/listeners/on-friend.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ export default async function onFriend (contact, request) {
let name = contact.name()
// await request.accept()

console.log(`Contact: ${name} send request ${request.hello}`)
console.log(`Contact: ${name} send request ${request.hello()}`)
}
}
2 changes: 1 addition & 1 deletion examples/hot-reload-bot/listener/friend.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ exports = module.exports = async function onFriend (contact, request) {
let name = contact.name();
await request.accept();

console.log(`Contact: ${name} send request ${request.hello}`);
console.log(`Contact: ${name} send request ${request.hello()}`);
}
}
2 changes: 1 addition & 1 deletion examples/monster/listeners/on-friend.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ export default async function onFriend (contact, request) {
let name = contact.name()
// await request.accept()

console.log(`Contact: ${name} send request ${request.hello}`)
console.log(`Contact: ${name} send request ${request.hello()}`)
}
}
2 changes: 1 addition & 1 deletion src/friend-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export class FriendRequest extends Accessory {

log.silly('FriendRequest', 'accept() to %s', this.payload.contactId)

await this.puppet.friendRequestAccept(this.payload.contactId, this.payload.ticket)
await this.puppet.friendRequestAccept(this.id)

const contact = this.contact()

Expand Down
5 changes: 2 additions & 3 deletions src/puppet-mock/puppet-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,10 +404,9 @@ export class PuppetMock extends Puppet {
}

public async friendRequestAccept(
contactId : string,
ticket : string,
friendRequestId : string,
): Promise<void> {
log.verbose('PuppetMock', 'friendRequestAccept(%s, %s)', contactId, ticket)
log.verbose('PuppetMock', 'friendRequestAccept(%s)', friendRequestId)
}

public ding(data?: any): Promise<string> {
Expand Down
25 changes: 9 additions & 16 deletions src/puppet-padchat/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,16 +156,10 @@ export class Bridge extends PadchatRpc {
// log.silly('PuppetPadchatBridge', 'start() padchatRpc.on(message)')
// this.emit('message', messageRawPayload)
// })

// No need to call logout() in bridge, because PupetPadchat will call logout() when received the 'logout' event
// this.padchatRpc.on('logout', data => {
this.on('logout', data => {
log.silly('PuppetPadchatBridge', 'start() on(logout, %s)', data)
if (this.selfId) {
this.selfId = undefined
this.logout()
} else {
log.warn('PuppetPadchatBridge', 'start() on(logout) received `logout` event when no `selfId`')
}
})
// this.on('logout', () => this.logout())

await this.loadAutoData()

Expand All @@ -183,17 +177,18 @@ export class Bridge extends PadchatRpc {

this.state.off('pending')

if (this.loginTimer) {
clearTimeout(this.loginTimer)
this.loginTimer = undefined
}

// await this.padchatRpc.stop()
await super.stop()

this.releaseCache()

this.selfId = undefined
this.loginScanQrCode = undefined
if (this.loginTimer) {
clearTimeout(this.loginTimer)
this.loginTimer = undefined
}

this.state.off(true)
}
Expand Down Expand Up @@ -225,8 +220,6 @@ export class Bridge extends PadchatRpc {
this.selfId = undefined
this.releaseCache()

this.emit('logout')

this.startLogin()
}

Expand Down Expand Up @@ -278,6 +271,7 @@ export class Bridge extends PadchatRpc {
this.loginScanQrCode = undefined
this.loginScanStatus = undefined
waitUserResponse = false
continue
}

switch (result.status) {
Expand Down Expand Up @@ -483,7 +477,6 @@ export class Bridge extends PadchatRpc {
selfId,
)
this.autoData.wxData = (await this.WXGenerateWxDat()).data
this.autoData.wxData = (await this.WXGenerateWxDat()).data
}

// Check 62 data. If has then use, or save 62 data here.
Expand Down
35 changes: 25 additions & 10 deletions src/puppet-padchat/padchat-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,10 @@ export class PadchatRpc extends EventEmitter {
// "userId": "test"
// }

const tencentPayloadList: PadchatMessagePayload[] = JSON.parse(decodeURIComponent(payload.data))
// https://stackoverflow.com/a/24417399/1123955
const data = payload.data.replace(/\+/g, '%20')

const tencentPayloadList: PadchatMessagePayload[] = JSON.parse(decodeURIComponent(data))

if (!Array.isArray(tencentPayloadList)) {
throw new Error('not array')
Expand All @@ -267,7 +270,10 @@ export class PadchatRpc extends EventEmitter {
let result: any

if (padchatPayload.data) {
result = JSON.parse(decodeURIComponent(padchatPayload.data))
// https://stackoverflow.com/a/24417399/1123955
const data = padchatPayload.data.replace(/\+/g, '%20')

result = JSON.parse(decodeURIComponent(data))
} else {
log.silly('PadchatRpc', 'onServerMessagePadchat() discard empty payload.data for apiName: %s', padchatPayload.apiName)
result = {}
Expand Down Expand Up @@ -511,7 +517,10 @@ export class PadchatRpc extends EventEmitter {
const result = await this.WXGetContact(id)

if (result.member) {
result.member = JSON.parse(decodeURIComponent(result.member))
// https://stackoverflow.com/a/24417399/1123955
const data = result.member.replace(/\+/g, '%20')

result.member = JSON.parse(decodeURIComponent(data))
}

return result
Expand Down Expand Up @@ -558,13 +567,19 @@ export class PadchatRpc extends EventEmitter {
// tslint:disable-next-line:max-line-length
// change '[{"big_head":"http://wx.qlogo.cn/mmhead/ver_1/DpS0ZssJ5s8tEpSr9JuPTRxEUrCK0USrZcR3PjOMfUKDwpnZLxWXlD4Q38bJpcXBtwXWwevsul1lJqwsQzwItQ/0","chatroom_nick_name":"","invited_by":"wxid_7708837087612","nick_name":"李佳芮","small_head":"http://wx.qlogo.cn/mmhead/ver_1/DpS0ZssJ5s8tEpSr9JuPTRxEUrCK0USrZcR3PjOMfUKDwpnZLxWXlD4Q38bJpcXBtwXWwevsul1lJqwsQzwItQ/132","user_name":"qq512436430"},{"big_head":"http://wx.qlogo.cn/mmhead/ver_1/kcBj3gSibfFd2I9vQ8PBFyQ77cpPIfqkFlpTdkFZzBicMT6P567yj9IO6xG68WsibhqdPuG82tjXsveFATSDiaXRjw/0","chatroom_nick_name":"","invited_by":"wxid_7708837087612","nick_name":"梦君君","small_head":"http://wx.qlogo.cn/mmhead/ver_1/kcBj3gSibfFd2I9vQ8PBFyQ77cpPIfqkFlpTdkFZzBicMT6P567yj9IO6xG68WsibhqdPuG82tjXsveFATSDiaXRjw/132","user_name":"mengjunjun001"},{"big_head":"http://wx.qlogo.cn/mmhead/ver_1/3CsKibSktDV05eReoAicV0P8yfmuHSowfXAMvRuU7HEy8wMcQ2eibcaO1ccS95PskZchEWqZibeiap6Gpb9zqJB1WmNc6EdD6nzQiblSx7dC1eGtA/0","chatroom_nick_name":"","invited_by":"wxid_7708837087612","nick_name":"苏轼","small_head":"http://wx.qlogo.cn/mmhead/ver_1/3CsKibSktDV05eReoAicV0P8yfmuHSowfXAMvRuU7HEy8wMcQ2eibcaO1ccS95PskZchEWqZibeiap6Gpb9zqJB1WmNc6EdD6nzQiblSx7dC1eGtA/132","user_name":"wxid_zj2cahpwzgie12"},{"big_head":"http://wx.qlogo.cn/mmhead/ver_1/piaHuicak41b6ibmcEVxoWKnnhgGDG5EbaD0hibwkrRvKeDs3gs7XQrkym3Q5MlUeSKY8vw2FRVVstialggUxf2zic2O8CvaEsicSJcghf41nibA940/0","chatroom_nick_name":"","invited_by":"wxid_zj2cahpwzgie12","nick_name":"王宁","small_head":"http://wx.qlogo.cn/mmhead/ver_1/piaHuicak41b6ibmcEVxoWKnnhgGDG5EbaD0hibwkrRvKeDs3gs7XQrkym3Q5MlUeSKY8vw2FRVVstialggUxf2zic2O8CvaEsicSJcghf41nibA940/132","user_name":"wxid_7708837087612"}]'
// to Array (PadchatRoomRawMember[])
if (Array.isArray(JSON.parse(decodeURIComponent(result.member)))) {
result.member = JSON.parse(decodeURIComponent(result.member)) as PadchatRoomMemberPayload[]

// https://stackoverflow.com/a/24417399/1123955
const data = result.member.data.replace(/\+/g, '%20')
const tryMemberList = JSON.parse(decodeURIComponent(data)) as PadchatRoomMemberPayload[]

if (Array.isArray(tryMemberList)) {
result.member = tryMemberList
} else {
log.warn('PadchatRpc', 'WXGetChatRoomMember(%s) member is not array: %s', roomId, JSON.stringify(result.member))
// throw Error('faild to parse chatroom member!')
result.member = []
}

} catch (e) {
// 18:27:54 SILL Puppet contactPayload(shanzhifeng644634) cache MISS
// tslint:disable-next-line:max-line-length
Expand Down Expand Up @@ -600,7 +615,7 @@ export class PadchatRpc extends EventEmitter {
}

if (result.status === 0) {
log.info('PadchatRpc', 'WXQRCodeLogin, login successfully!')
log.silly('PadchatRpc', 'WXQRCodeLogin, login successfully!')
// this.username = result.user_name
// this.nickname = result.nick_name
// this.loginSucceed = true
Expand Down Expand Up @@ -635,7 +650,7 @@ export class PadchatRpc extends EventEmitter {
}

if (result && result.status === WXCheckQRCodeStatus.WaitConfirm) {
log.info('PadchatRpc', 'checkQrcode: Had scan the Qrcode, but not Login!')
log.silly('PadchatRpc', 'checkQrcode: Had scan the Qrcode, but not Login!')

setTimeout(() => {
this.checkQrcode()
Expand All @@ -645,7 +660,7 @@ export class PadchatRpc extends EventEmitter {
}

if (result && result.status === WXCheckQRCodeStatus.Confirmed) {
log.info('PadchatRpc', 'checkQrcode: Trying to login... please wait')
log.silly('PadchatRpc', 'checkQrcode: Trying to login... please wait')

if (!result.user_name || !result.password) {
throw Error('PadchatRpc, checkQrcode, cannot get username or password here, return!')
Expand All @@ -660,12 +675,12 @@ export class PadchatRpc extends EventEmitter {
}

if (result && result.status === WXCheckQRCodeStatus.Timeout) {
log.info('PadchatRpc', 'checkQrcode: Timeout')
log.silly('PadchatRpc', 'checkQrcode: Timeout')
return
}

if (result && result.status === WXCheckQRCodeStatus.Cancel) {
log.info('PadchatRpc', 'checkQrcode: Cancel by user')
log.silly('PadchatRpc', 'checkQrcode: Cancel by user')
return
}

Expand Down
41 changes: 23 additions & 18 deletions src/puppet-padchat/puppet-padchat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,11 @@ export class PuppetPadchat extends Puppet {

this.state.on(true)
this.emit('start')
}

protected async login(selfId: string): Promise<void> {
await super.login(selfId)
this.bridge.syncContactsAndRooms()
}

public async startBridge(): Promise<void> {
Expand All @@ -213,19 +217,10 @@ export class PuppetPadchat extends Puppet {
// this.bridge.on('ding' , Event.onDing.bind(this))
// this.bridge.on('error' , e => this.emit('error', e))
// this.bridge.on('log' , Event.onLog.bind(this))
this.bridge.on('login', (userId: string) => {
this.bridge.syncContactsAndRooms()
this.login(userId)
})
this.bridge.on('logout', () => {
this.logout()
})
this.bridge.on('message', (rawPayload: PadchatMessagePayload) => {
this.onPadchatMessage(rawPayload)
})
this.bridge.on('scan', (qrCode: string, status: number, data?: string) => {
this.emit('scan', qrCode, status, data)
})
this.bridge.on('scan', (qrCode: string, status: number, data?: string) => this.emit('scan', qrCode, status, data))
this.bridge.on('login', (userId: string) => this.login(userId))
this.bridge.on('message', (rawPayload: PadchatMessagePayload) => this.onPadchatMessage(rawPayload))
this.bridge.on('logout', () => this.logout())

await this.bridge.start()
}
Expand All @@ -238,7 +233,10 @@ export class PuppetPadchat extends Puppet {
)
switch (rawPayload.sub_type) {
case PadchatMessageType.VerifyMsg:
this.cachePadchatFriendRequestPayload.set(rawPayload.msg_id, rawPayload)
this.cachePadchatFriendRequestPayload.set(
rawPayload.msg_id,
rawPayload,
)
this.emit('friend', rawPayload.msg_id)
break

Expand Down Expand Up @@ -381,6 +379,8 @@ export class PuppetPadchat extends Puppet {
*/

public async messageFile(id: string): Promise<FileBox> {
log.warn('PuppetPadchat', 'messageFile(%s) not implemented yet', id)

// const rawPayload = await this.messageRawPayload(id)

// TODO
Expand Down Expand Up @@ -418,7 +418,7 @@ export class PuppetPadchat extends Puppet {
}

public async messageRawPayloadParser(rawPayload: PadchatMessagePayload): Promise<MessagePayload> {
log.verbose('PuppetPadChat', 'messageRawPayloadParser(rawPayload.msg_id=%s)', rawPayload.msg_id)
log.verbose('PuppetPadChat', 'messageRawPayloadParser({msg_id="%s"})', rawPayload.msg_id)

const payload: MessagePayload = pfHelper.messageRawPayloadParser(rawPayload)

Expand Down Expand Up @@ -705,18 +705,23 @@ export class PuppetPadchat extends Puppet {

const payload = await this.friendRequestPayload(friendRequestId) as FriendRequestPayloadReceive

console.log('friendRequestAccept: ', payload)

if (!payload.ticket) {
throw new Error('no ticket')
}
if (!payload.stranger) {
throw new Error('no stranger')
}

await this.bridge.WXAcceptUser(
payload.contactId,
payload.stranger,
payload.ticket,
)
}

public async friendRequestRawPayloadParser(rawPayload: PadchatMessagePayload) : Promise<FriendRequestPayload> {
log.verbose('PuppetPadchat', 'friendRequestRawPayloadParser(%s)', rawPayload)
log.verbose('PuppetPadchat', 'friendRequestRawPayloadParser({id=%s})', rawPayload.msg_id)

const payload: FriendRequestPayload = await pfHelper.friendRequestRawPayloadParser(rawPayload)
return payload
Expand All @@ -727,7 +732,7 @@ export class PuppetPadchat extends Puppet {

const rawPayload = this.cachePadchatFriendRequestPayload.get(friendRequestId)
if (!rawPayload) {
throw new Error('no rawPayload')
throw new Error('no rawPayload for id ' + friendRequestId)
}

return rawPayload
Expand Down
8 changes: 7 additions & 1 deletion src/puppet-padchat/pure-function-helper.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,18 @@ test('contactRawPayloadParser', async t => {

test('friendRequestRawPayloadParser()', async t => {
const DATA = '%5B%7B%22content%22%3A%22%3Cmsg+fromusername%3D%5C%22lizhuohuan%5C%22+encryptusername%3D%5C%22v1_cf269def9b946093f9d131a5e733ba169351013c95e46a860cddecaf485c4b10%40stranger%5C%22+fromnickname%3D%5C%22%E6%9D%8E%E5%8D%93%E6%A1%93%5C%22+content%3D%5C%22xixixi%5C%22+fullpy%3D%5C%22lizhuohuan%5C%22+shortpy%3D%5C%22LZH%5C%22+imagestatus%3D%5C%223%5C%22+scene%3D%5C%226%5C%22+country%3D%5C%22CN%5C%22+province%3D%5C%22Beijing%5C%22+city%3D%5C%22Haidian%5C%22+sign%3D%5C%22PreAngel%E6%8A%95%E8%B5%84%E4%BA%BA%E3%80%82%E6%B0%B4%E6%9C%A8%E6%B8%85%E5%8D%8EBBS%E7%AB%99%E9%95%BF%E3%80%82%E6%8A%95%E8%B5%84%E4%BA%BA%E4%B8%AD%E6%9C%80%E4%BC%9A%E9%A3%9E%E7%9A%84AI%E7%A8%8B%E5%BA%8F%E5%91%98%E3%80%82%5C%22+percard%3D%5C%221%5C%22+sex%3D%5C%221%5C%22+alias%3D%5C%22%5C%22+weibo%3D%5C%22%5C%22+weibonickname%3D%5C%22%5C%22+albumflag%3D%5C%220%5C%22+albumstyle%3D%5C%220%5C%22+albumbgimgid%3D%5C%22913943270785024_913943270785024%5C%22+snsflag%3D%5C%22177%5C%22+snsbgimgid%3D%5C%22http%3A%2F%2Fshmmsns.qpic.cn%2Fmmsns%2FNoFChqEQomEyhyNjzExH3v78BHSVmIzHBIdOECg9jgcTpRNwThgXJicCsGicI6Kib4xLETc2PuKwhM%2F0%5C%22+snsbgobjectid%3D%5C%2212683064081608282338%5C%22+mhash%3D%5C%22d98b28f4cb1708bb584f3e66078e0a0d%5C%22+mfullhash%3D%5C%22d98b28f4cb1708bb584f3e66078e0a0d%5C%22+bigheadimgurl%3D%5C%22http%3A%2F%2Fwx.qlogo.cn%2Fmmhead%2Fver_1%2FciaaFRTCqfHIKLY0wBjv3h0LSPkCEEcJ0fo6kQkMxQLBiahJWFk7rS9G4VLU5n9OfAnXWlMaIV01oeTITYS0OHlg%2F0%5C%22+smallheadimgurl%3D%5C%22http%3A%2F%2Fwx.qlogo.cn%2Fmmhead%2Fver_1%2FciaaFRTCqfHIKLY0wBjv3h0LSPkCEEcJ0fo6kQkMxQLBiahJWFk7rS9G4VLU5n9OfAnXWlMaIV01oeTITYS0OHlg%2F96%5C%22+ticket%3D%5C%22v2_1a0d2cf325e64b6f74bed09e944529e7cc7a7580cb323475050664566dd0302d89b8e2ed95b596b459cf762d94a0ce606da39babbae0dc26b18a62e079bfc120%40stranger%5C%22+opcode%3D%5C%222%5C%22+googlecontact%3D%5C%22%5C%22+qrticket%3D%5C%22%5C%22+chatroomusername%3D%5C%22%5C%22+sourceusername%3D%5C%22%5C%22+sourcenickname%3D%5C%22%5C%22%3E%3Cbrandlist+count%3D%5C%220%5C%22+ver%3D%5C%22652101432%5C%22%3E%3C%2Fbrandlist%3E%3C%2Fmsg%3E%22%2C%22continue%22%3A1%2C%22description%22%3A%22%22%2C%22from_user%22%3A%22fmessage%22%2C%22msg_id%22%3A%222957327798149218888%22%2C%22msg_source%22%3A%22%22%2C%22msg_type%22%3A5%2C%22status%22%3A1%2C%22sub_type%22%3A37%2C%22timestamp%22%3A1528557626%2C%22to_user%22%3A%22wxid_5zj4i5htp9ih22%22%2C%22uin%22%3A1928023446%7D%5D%0A'
const TENCENT_PAYLOAD_LIST: PadchatMessagePayload[] = JSON.parse(decodeURIComponent(DATA))

// https://stackoverflow.com/a/24417399/1123955
const data = DATA.replace(/\+/g, '%20')

const TENCENT_PAYLOAD_LIST: PadchatMessagePayload[] = JSON.parse(decodeURIComponent(data))
const PADCHAT_MESSAGE_PAYLOAD = TENCENT_PAYLOAD_LIST[0]
const EXPECTED_FRIEND_REQUEST_PAYLOAD = {
id : '2957327798149218888',
contactId : 'lizhuohuan',
hello : 'xixixi',
stranger : 'v1_cf269def9b946093f9d131a5e733ba169351013c95e46a860cddecaf485c4b10@stranger',

ticket : 'v2_1a0d2cf325e64b6f74bed09e944529e7cc7a7580cb323475050664566dd0302d89b8e2ed95b596b459cf762d94a0ce606da39babbae0dc26b18a62e079bfc120@stranger',
type : FriendRequestType.Receive,
}
Expand Down
6 changes: 3 additions & 3 deletions src/puppet-padchat/pure-function-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,13 +280,13 @@ export class PadchatPureFunctionHelper {
})
})

console.log(padchatFriendRequestPayload)
// console.log(padchatFriendRequestPayload)

const friendRequestPayload: FriendRequestPayload = {
id : rawPayload.msg_id,
// use v1 stranger id as contactid at here:
contactId : padchatFriendRequestPayload.encryptusername,
contactId : padchatFriendRequestPayload.fromusername,
hello : padchatFriendRequestPayload.content,
stranger : padchatFriendRequestPayload.encryptusername,
ticket : padchatFriendRequestPayload.ticket,
type : FriendRequestType.Receive,
}
Expand Down
9 changes: 5 additions & 4 deletions src/puppet-puppeteer/puppet-puppeteer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1190,13 +1190,14 @@ export class PuppetPuppeteer extends Puppet {
}

public async friendRequestAccept(
contactId : string,
ticket : string,
friendRequestId : string,
): Promise<void> {
const payload = await this.friendRequestPayload(friendRequestId) as FriendRequestPayloadReceive

try {
await this.bridge.verifyUserOk(contactId, ticket)
await this.bridge.verifyUserOk(payload.contactId, payload.ticket)
} catch (e) {
log.warn('PuppetPuppeteer', 'bridge.verifyUserOk(%s, %s) rejected: %s', contactId, ticket, e.message)
log.warn('PuppetPuppeteer', 'bridge.verifyUserOk(%s, %s) rejected: %s', payload.contactId, payload.ticket, e.message)
Raven.captureException(e)
throw e
}
Expand Down

0 comments on commit 197b19e

Please sign in to comment.