Skip to content
This repository has been archived by the owner on Jun 1, 2020. It is now read-only.

Add implementation for room-invite event #107

Merged
merged 7 commits into from
Jul 24, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"tslint": "^5.10.0",
"tslint-config-standard": "^7.1.0",
"typescript": "^2.9.2",
"wechaty": "^0.17.133"
"wechaty": "^0.19.107"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to notify you that this is a BREAKING change and you should bump your MINOR version number when you changing the dependence to wechaty 0.17 to 0.19

},
"git": {
"scripts": {
Expand All @@ -78,7 +78,7 @@
},
"peerDependencies": {
"file-box": "^0.8.22",
"wechaty-puppet": "^0.8.2"
"wechaty-puppet": "^0.9.19"
},
"homepage": "https://github.com/lijiarui/wechaty-puppet-padchat#readme",
"dependencies": {
Expand All @@ -98,7 +98,6 @@
"request-promise": "^4.2.2",
"rx-queue": "^0.4.26",
"rxjs": "^6.2.1",
"wechaty-puppet": "^0.8.5",
"ws": "^5.2.1",
"xml2json": "^0.11.2"
}
Expand Down
50 changes: 50 additions & 0 deletions src/padchat-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
PadchatContactPayload,
PadchatContinue,

PadchatRoomInvitationPayload,
PadchatRoomInviteEvent,
PadchatRoomMemberPayload,
PadchatRoomPayload,
} from './padchat-schemas'
Expand Down Expand Up @@ -70,6 +72,7 @@ export class PadchatManager extends PadchatRpc {
[contactId: string]: PadchatRoomMemberPayload,
}>
private cacheRoomRawPayload? : FlashStoreSync<string, PadchatRoomPayload>
private cacheRoomInvitationRawPayload? : FlashStoreSync<string, PadchatRoomInvitationPayload>

private readonly state : StateSwitch
private readonly delayQueueExecutor : DelayQueueExector
Expand Down Expand Up @@ -106,6 +109,7 @@ export class PadchatManager extends PadchatRpc {
if ( this.cacheContactRawPayload
|| this.cacheRoomMemberRawPayload
|| this.cacheRoomRawPayload
|| this.cacheRoomInvitationRawPayload
) {
throw new Error('cache exists')
}
Expand All @@ -130,11 +134,13 @@ export class PadchatManager extends PadchatRpc {
this.cacheContactRawPayload = new FlashStoreSync(path.join(baseDir, 'contact-raw-payload'))
this.cacheRoomMemberRawPayload = new FlashStoreSync(path.join(baseDir, 'room-member-raw-payload'))
this.cacheRoomRawPayload = new FlashStoreSync(path.join(baseDir, 'room-raw-payload'))
this.cacheRoomInvitationRawPayload = new FlashStoreSync(path.join(baseDir, 'room-invitation-raw-payload'))

await Promise.all([
this.cacheContactRawPayload.ready(),
this.cacheRoomMemberRawPayload.ready(),
this.cacheRoomRawPayload.ready(),
this.cacheRoomInvitationRawPayload.ready(),
])

const roomMemberTotalNum = [...this.cacheRoomMemberRawPayload.values()].reduce(
Expand All @@ -158,18 +164,21 @@ export class PadchatManager extends PadchatRpc {
if ( this.cacheContactRawPayload
&& this.cacheRoomMemberRawPayload
&& this.cacheRoomRawPayload
&& this.cacheRoomInvitationRawPayload
) {
log.silly('PuppetPadchatManager', 'releaseCache() closing caches ...')

await Promise.all([
this.cacheContactRawPayload.close(),
this.cacheRoomMemberRawPayload.close(),
this.cacheRoomRawPayload.close(),
this.cacheRoomInvitationRawPayload.close(),
])

this.cacheContactRawPayload = undefined
this.cacheRoomMemberRawPayload = undefined
this.cacheRoomRawPayload = undefined
this.cacheRoomInvitationRawPayload = undefined

log.silly('PuppetPadchatManager', 'releaseCache() cache closed.')
} else {
Expand Down Expand Up @@ -987,6 +996,47 @@ export class PadchatManager extends PadchatRpc {
return rawPayload
}

public async roomInvitationRawPayload (roomInvitationId: string): Promise<PadchatRoomInvitationPayload> {
log.verbose('PuppetPadchatManager', 'roomInvitationRawPayload(%s)', roomInvitationId)
if (!this.cacheRoomInvitationRawPayload) {
throw new Error('no cache')
}

const payload = await this.cacheRoomInvitationRawPayload.get(roomInvitationId)

if (payload) {
return payload
} else {
throw new Error(`can not get invitation with invitation id: ${roomInvitationId}`)
}
}

public async roomInvitationRawPayloadDirty (roomInvitationId: string): Promise<void> {
log.verbose('PuppetPadchatManager', 'roomInvitationRawPayloadDirty(%s)', roomInvitationId)
if (!this.cacheRoomInvitationRawPayload) {
throw new Error('no cache')
}

await this.cacheRoomInvitationRawPayload.delete(roomInvitationId)
}

public async saveRoomInvitationRawPayload (roomInvitation: PadchatRoomInviteEvent): Promise<void> {
log.verbose('PuppetPadchatManager', 'saveRoomInvitationRawPayload(%s)', JSON.stringify(roomInvitation))
const { msgId, roomName, url, fromUser, timestamp } = roomInvitation

if (!this.cacheRoomInvitationRawPayload) {
throw new Error('no cache')
}

this.cacheRoomInvitationRawPayload.set(msgId, {
fromUser,
id: msgId,
roomName,
timestamp,
url,
})
}

public ding (data?: string): void {
log.verbose('PuppetPadchatManager', 'ding(%s)', data || '')
// TODO: healthy check
Expand Down
42 changes: 42 additions & 0 deletions src/padchat-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
import {
ContactGender,
FriendshipType,
} from 'wechaty-puppet'

// 1 when use WXSyncContact, 0 when use WXGetContact
Expand Down Expand Up @@ -438,6 +439,14 @@ export interface PadchatRoomMemberListPayload {
// sourcenickname: '' },
// brandlist: [ [Object] ] } }

export interface PadchatRoomInvitationPayload {
id: string,
fromUser: string,
roomName: string,
timestamp: number,
url: string,
}

export interface PadchatFriendshipPayload {
fromusername : string, // 'lizhuohuan'
encryptusername : string, // v1_xxx@stranger'
Expand All @@ -452,3 +461,36 @@ export interface PadchatRequestTokenPayload {
share_url : string,
status : number,
}

export interface PadchatRoomInviteEvent {
fromUser: string,
msgId: string,
roomName: string,
timestamp: number,
url: string,
}

export interface FriendshipPayloadBase {
id : string,

contactId : string,
hello? : string,
}

export type FriendshipPayloadConfirm = FriendshipPayloadBase & {
type : FriendshipType.Confirm,
}

export type FriendshipPayloadReceive = FriendshipPayloadBase & {
stranger? : string,
ticket : string,
type : FriendshipType.Receive,
}

export type FriendshipPayloadVerify = FriendshipPayloadBase & {
type : FriendshipType.Verify,
}

export type FriendshipPayload = FriendshipPayloadConfirm
| FriendshipPayloadReceive
| FriendshipPayloadVerify
111 changes: 58 additions & 53 deletions src/puppet-padchat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
*/

import path from 'path'
import path from 'path'

import flatten from 'array-flatten'
import LRU from 'lru-cache'
Expand All @@ -31,7 +31,6 @@ import {
ContactType,

FriendshipPayload,
FriendshipPayloadReceive,

MessagePayload,
MessageType,
Expand All @@ -40,7 +39,7 @@ import {

PuppetOptions,
Receiver,
RoomInvitation,
RoomInvitationPayload,
RoomMemberPayload,
RoomPayload,
} from 'wechaty-puppet'
Expand Down Expand Up @@ -83,9 +82,11 @@ import {
} from './padchat-manager'

import {
FriendshipPayloadReceive,
PadchatContactPayload,
PadchatMessagePayload,
PadchatMessageType,
PadchatRoomInvitationPayload,
PadchatRoomMemberPayload,
PadchatRoomPayload,
} from './padchat-schemas'
Expand Down Expand Up @@ -212,7 +213,7 @@ export class PuppetPadchat extends Puppet {
throw new Error('no padchat manager')
}
await super.login(selfId)
// await this.padchatManager.syncContactsAndRooms()
await this.padchatManager.syncContactsAndRooms()
}

public async startManager (manager: PadchatManager): Promise<void> {
Expand Down Expand Up @@ -322,7 +323,6 @@ export class PuppetPadchat extends Puppet {
}

protected async onPadchatMessageRoomInvitation (rawPayload: PadchatMessagePayload): Promise<void> {
console.log(rawPayload)
log.verbose('PuppetPadchat', 'onPadchatMessageRoomInvitation(%s)', rawPayload)
const roomInviteEvent = roomInviteEventMessageParser(rawPayload)

Expand All @@ -331,54 +331,9 @@ export class PuppetPadchat extends Puppet {
}

if (roomInviteEvent) {
try {
const shareUrl = roomInviteEvent.url

const response = await this.padchatManager.WXGetRequestToken(this.selfId(), shareUrl)

const roomInvitation: RoomInvitation = {
accept: async () => {
try {
const res = await require('request-promise')({
method: 'POST',
uri: response.full_url
})

let succeed = false
let resultCode = 'UNKNOWN'
let message = ''

if (res.indexOf('你无法查看被转发过的邀请') !== -1 || res.indexOf('Unable to view forwarded invitations')) {
resultCode = 'FORWARDED'
message = 'Accept invitation failed, this is a forwarded invitation, can not be accepted'
} else if (res.indexOf('你未开通微信支') !== -1 || res.indexOf('You haven\'t enabled WeChat Pay')) {
resultCode = 'WXPAY'
message = 'The user need to enable wechaty pay(微信支付) to join the room, this is requested by Wechat.'
} else if (res.indexOf('该邀请已过期') !== -1 || res.indexOf('Invitation expired')) {
resultCode = 'EXPIRED'
message = 'The invitation is expired, please requuest the user to send again'
} else {
resultCode = 'DONE'
succeed = true
message = 'Accept Invitation succeed'
}
return { message, resultCode, succeed }
} catch (e) {
return {
message: 'Failed with exception: ' + e,
resultCode: 'FAILED',
succeed: false,
}
}
},
fromUser: rawPayload.from_user,
roomName: roomInviteEvent.roomName,
timestamp: rawPayload.timestamp,
}
this.emit('room-invite', roomInvitation)
} catch (e) {
console.error(e)
}
await this.padchatManager.saveRoomInvitationRawPayload(roomInviteEvent)

this.emit('room-invite', roomInviteEvent.msgId)
}
}

Expand Down Expand Up @@ -1308,6 +1263,56 @@ export class PuppetPadchat extends Puppet {
}
}

public async roomInvitationRawPayload (roomInvitationId: string): Promise<PadchatRoomInvitationPayload> {
if (!this.padchatManager) {
throw new Error('no padchat manager')
}

return this.padchatManager.roomInvitationRawPayload(roomInvitationId)
}

public async roomInvitationRawPayloadParser (rawPayload: PadchatRoomInvitationPayload): Promise<RoomInvitationPayload> {
return {
id: rawPayload.id,
inviterId: rawPayload.fromUser,
roomMemberCount: 0,
roomMemberIdList: [],
roomTopic: rawPayload.roomName,
timestamp: rawPayload.timestamp
}
}

public async roomInvitationAccept (roomInvitationId: string): Promise<void> {

if (!this.padchatManager) {
throw new Error('no padcaht manager')
}

let res: string = ''
try {
const payload = await this.padchatManager.roomInvitationRawPayload(roomInvitationId)
const shareUrl = payload.url

const response = await this.padchatManager.WXGetRequestToken(this.selfId(), shareUrl)

res = await require('request-promise')({
method: 'POST',
simple: false,
uri: response.full_url,
})
} catch (e) {
throw new Error('UNKNOWN: Unexpected error happened when trying to accept invitation\n' + e)
}
console.log(res)
if (res.indexOf('你无法查看被转发过的邀请') !== -1 || res.indexOf('Unable to view forwarded invitations')) {
throw new Error('FORWARDED: Accept invitation failed, this is a forwarded invitation, can not be accepted')
} else if (res.indexOf('你未开通微信支') !== -1 || res.indexOf('You haven\'t enabled WeChat Pay')) {
throw new Error('WXPAY: The user need to enable wechaty pay(微信支付) to join the room, this is requested by Wechat.')
} else if (res.indexOf('该邀请已过期') !== -1 || res.indexOf('Invitation expired')) {
throw new Error('EXPIRED: The invitation is expired, please request the user to send again')
}
}

/**
*
* Friendship
Expand Down
8 changes: 4 additions & 4 deletions src/pure-function-helpers/friendship-raw-payload-parser.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { toJson } from 'xml2json'

import {
FriendshipType
} from 'wechaty-puppet'

import {
FriendshipPayload,
FriendshipPayloadConfirm,
FriendshipPayloadReceive,
FriendshipPayloadVerify,
FriendshipType,
} from 'wechaty-puppet'

import {
PadchatFriendshipPayload,
PadchatMessagePayload,
} from '../padchat-schemas'
Expand Down
Empty file.