wechaty-puppet-padplus
Version:
Puppet Padplus for Wechaty
329 lines (281 loc) • 9.44 kB
text/typescript
import { xmlToJson } from './xml-to-json'
import {
PuppetRoomJoinEvent,
YOU,
} from 'wechaty-puppet'
import {
PadplusMessagePayload,
PadplusMessageType,
} from '../schemas'
import {
isPayload,
isRoomId,
} from './is-type'
import {
splitChineseNameList,
splitEnglishNameList,
} from './split-name'
/**
*
* 1. Room Join Event
*
*
* try to find 'join' event for Room
*
* 1.
* 李卓桓 invited Huan to the group chat
* 李卓桓 invited 李佳芮, Huan to the group chat
* 李卓桓 invited you to a group chat with
* 李卓桓 invited you and Huan to the group chat
* 2.
* "李卓桓"邀请"Huan LI++"加入了群聊
* "李佳芮"邀请你加入了群聊,群聊参与人还有:小桔、桔小秘、小小桔、wuli舞哩客服、舒米
* "李卓桓"邀请你和"Huan LI++"加入了群聊
*/
const ROOM_JOIN_BOT_INVITE_OTHER_REGEX_LIST_ZH = [
/^你邀请"(.+)"加入了群聊/,
/^" ?(.+)"通过扫描你分享的二维码加入群聊/,
]
const ROOM_JOIN_BOT_INVITE_OTHER_REGEX_LIST_EN = [
/^You invited (.+) to the group chat/,
/^" ?(.+)" joined group chat via the QR code you shared/,
]
/* ----------------------------------------------- */
const ROOM_JOIN_OTHER_INVITE_BOT_REGEX_LIST_ZH = [
/^"([^"]+?)"邀请你加入了群聊/,
/^"([^"]+?)"邀请你和"(.+)"加入了群聊/,
]
const ROOM_JOIN_OTHER_INVITE_BOT_REGEX_LIST_EN = [
/^(.+) invited you to a group chat/,
/^(.+) invited you and (.+) to the group chat/,
]
/* ----------------------------------------------- */
const ROOM_JOIN_OTHER_INVITE_OTHER_REGEX_LIST_ZH = [
/^"(.+)"邀请"(.+)"加入了群聊/,
]
const ROOM_JOIN_OTHER_INVITE_OTHER_REGEX_LIST_EN = [
/^(.+?) invited (.+?) to (the|a) group chat/,
]
/* ----------------------------------------------- */
const ROOM_JOIN_OTHER_INVITE_OTHER_QRCODE_REGEX_LIST_ZH = [
/^" (.+)"通过扫描"(.+)"分享的二维码加入群聊/,
]
const ROOM_JOIN_OTHER_INVITE_OTHER_QRCODE_REGEX_LIST_EN = [
/^"(.+)" joined the group chat via the QR Code shared by "(.+)"/,
]
export async function roomJoinEventMessageParser (
rawPayload: PadplusMessagePayload,
): Promise<null | PuppetRoomJoinEvent> {
if (!isPayload(rawPayload)) {
return null
}
const roomId = rawPayload.fromUserName
if (!roomId) {
return null
}
if (!isRoomId(roomId)) {
return null
}
const timestamp = rawPayload.createTime
let content = rawPayload.content
/**
* when the message is a Recalled type, bot can undo the invitation
*/
if (rawPayload.msgType === PadplusMessageType.Recalled) {
/**
* content:
* ```
* 3453262102@chatroom:
* <sysmsg type="delchatroommember">
* ...
* </sysmsg>
* ```
*/
const tryXmlText = content.replace(/^[^\n]+\n/, '')
interface XmlSchema {
sysmsg: {
$: {
type: 'revokemsg' | 'delchatroommember' | 'multivoip',
},
delchatroommember?: {
plain : string,
text : string,
},
revokemsg?: {
replacemsg : string,
msgid : string,
newmsgid : string,
session : string,
},
}
}
const jsonPayload: XmlSchema = await xmlToJson(tryXmlText) // toJson(tryXmlText, { object: true }) as XmlSchema
try {
if (jsonPayload.sysmsg.$.type === 'delchatroommember') {
content = jsonPayload.sysmsg.delchatroommember!.plain
} else if (jsonPayload.sysmsg.$.type === 'revokemsg') {
content = jsonPayload.sysmsg.revokemsg!.replacemsg
} else if (jsonPayload.sysmsg.$.type === 'multivoip') {
return null
} else {
throw new Error('unknown jsonPayload sysmsg type: ' + jsonPayload.sysmsg.$.type)
}
} catch (e) {
console.error(e)
throw e
}
}
let matchesForBotInviteOtherEn = null as null | string[]
let matchesForOtherInviteBotEn = null as null | string[]
let matchesForOtherInviteOtherEn = null as null | string[]
let matchesForOtherInviteOtherQrcodeEn = null as null | string[]
let matchesForBotInviteOtherZh = null as null | string[]
let matchesForOtherInviteBotZh = null as null | string[]
let matchesForOtherInviteOtherZh = null as null | string[]
let matchesForOtherInviteOtherQrcodeZh = null as null | string[]
ROOM_JOIN_BOT_INVITE_OTHER_REGEX_LIST_EN.some(
regex => !!(matchesForBotInviteOtherEn = content.match(regex)),
)
ROOM_JOIN_OTHER_INVITE_BOT_REGEX_LIST_EN.some(
regex => !!(matchesForOtherInviteBotEn = content.match(regex)),
)
ROOM_JOIN_OTHER_INVITE_OTHER_REGEX_LIST_EN.some(
regex => !!(matchesForOtherInviteOtherEn = content.match(regex)),
)
ROOM_JOIN_OTHER_INVITE_OTHER_QRCODE_REGEX_LIST_EN.some(
regex => !!(matchesForOtherInviteOtherQrcodeEn = content.match(regex)),
)
ROOM_JOIN_BOT_INVITE_OTHER_REGEX_LIST_ZH.some(
regex => !!(matchesForBotInviteOtherZh = content.match(regex)),
)
ROOM_JOIN_OTHER_INVITE_BOT_REGEX_LIST_ZH.some(
regex => !!(matchesForOtherInviteBotZh = content.match(regex)),
)
ROOM_JOIN_OTHER_INVITE_OTHER_REGEX_LIST_ZH.some(
regex => !!(matchesForOtherInviteOtherZh = content.match(regex)),
)
ROOM_JOIN_OTHER_INVITE_OTHER_QRCODE_REGEX_LIST_ZH.some(
regex => !!(matchesForOtherInviteOtherQrcodeZh = content.match(regex)),
)
const matchesForBotInviteOther = matchesForBotInviteOtherEn || matchesForBotInviteOtherZh
const matchesForOtherInviteBot = matchesForOtherInviteBotEn || matchesForOtherInviteBotZh
const matchesForOtherInviteOther = matchesForOtherInviteOtherEn || matchesForOtherInviteOtherZh
const matchesForOtherInviteOtherQrcode = matchesForOtherInviteOtherQrcodeEn || matchesForOtherInviteOtherQrcodeZh
const languageEn = matchesForBotInviteOtherEn
|| matchesForOtherInviteBotEn
|| matchesForOtherInviteOtherEn
|| matchesForOtherInviteOtherQrcodeEn
const languageZh = matchesForBotInviteOtherZh
|| matchesForOtherInviteBotZh
|| matchesForOtherInviteOtherZh
|| matchesForOtherInviteOtherQrcodeZh
const matches = matchesForBotInviteOther
|| matchesForOtherInviteBot
|| matchesForOtherInviteOther
|| matchesForOtherInviteOtherQrcode
if (!matches) {
return null
}
/**
*
* Parse all Names From the Event Text
*
*/
if (matchesForBotInviteOther) {
/**
* 1. Bot Invite Other to join the Room
* (include invite via QrCode)
*/
const other = matches[1]
let inviteeNameList
if (languageEn) {
inviteeNameList = splitEnglishNameList(other)
} else if (languageZh) {
inviteeNameList = splitChineseNameList(other)
} else {
throw new Error('make typescript happy')
}
const inviterName: string | YOU = YOU
const joinEvent: PuppetRoomJoinEvent = {
inviteeNameList,
inviterName,
roomId,
timestamp,
}
return joinEvent
} else if (matchesForOtherInviteBot) {
/**
* 2. Other Invite Bot to join the Room
*/
// /^"([^"]+?)"邀请你加入了群聊/,
// /^"([^"]+?)"邀请你和"(.+?)"加入了群聊/,
const inviterName = matches[1]
let inviteeNameList: Array<YOU | string> = [YOU]
if (matches[2]) {
let nameList
if (languageEn) {
nameList = splitEnglishNameList(matches[2])
} else if (languageZh) {
nameList = splitChineseNameList(matches[2])
} else {
throw new Error('neither English nor Chinese')
}
inviteeNameList = inviteeNameList.concat(nameList)
}
const joinEvent: PuppetRoomJoinEvent = {
inviteeNameList,
inviterName,
roomId,
timestamp,
}
return joinEvent
} else if (matchesForOtherInviteOther) {
/**
* 3. Other Invite Other to a Room
* (NOT include invite via Qrcode)
*/
// /^"([^"]+?)"邀请"([^"]+)"加入了群聊$/,
// /^([^"]+?) invited ([^"]+?) to (the|a) group chat/,
const inviterName = matches[1]
let inviteeNameList: string[]
const other = matches[2]
if (languageEn) {
inviteeNameList = splitEnglishNameList(other)
} else if (languageZh) {
inviteeNameList = splitChineseNameList(other)
} else {
throw new Error('neither English nor Chinese')
}
const joinEvent: PuppetRoomJoinEvent = {
inviteeNameList,
inviterName,
roomId,
timestamp,
}
return joinEvent
} else if (matchesForOtherInviteOtherQrcode) {
/**
* 4. Other Invite Other via Qrcode to join a Room
* /^" (.+)"通过扫描"(.+)"分享的二维码加入群聊/,
*/
const inviterName = matches[2]
let inviteeNameList: string[]
const other = matches[1]
if (languageEn) {
inviteeNameList = splitEnglishNameList(other)
} else if (languageZh) {
inviteeNameList = splitChineseNameList(other)
} else {
throw new Error('neither English nor Chinese')
}
const joinEvent: PuppetRoomJoinEvent = {
inviteeNameList,
inviterName,
roomId,
timestamp,
}
return joinEvent
} else {
throw new Error('who invite who?')
}
}