wechaty-puppet-wechat4u
Version:
Wechat4u Puppet for Wechaty
109 lines (93 loc) • 3.59 kB
text/typescript
import { WebMessageRawPayload, WebMessageType } from '../../web-schemas.js'
import type * as PUPPET from 'wechaty-puppet'
import { isRoomId } from '../utils/is-type.js'
import type { EventPayload } from './event.js'
import { executeRunners } from '../utils/runner.js'
const YOU_REMOVE_OTHER_REGEX_LIST = [
/^(你)将"(.+)"移出了群聊/,
/^(You) removed "(.+)" from the group chat/,
]
const OTHER_REMOVE_YOU_REGEX_LIST = [
/^(你)被"([^"]+?)"移出群聊/,
/^(You) were removed from the group chat by "([^"]+)"/,
]
const roomLeaveDebounceMap: Map<string, ReturnType<typeof setTimeout>> = new Map()
const DEBOUNCE_TIMEOUT = 3600 * 1000 // 1 hour
function roomLeaveDebounceKey (roomId: string, removeeId: string) {
return `${roomId}:${removeeId}`
}
function roomLeaveAddDebounce (roomId: string, removeeId: string) {
const key = roomLeaveDebounceKey(roomId, removeeId)
const oldTimeout = roomLeaveDebounceMap.get(key)
if (oldTimeout) {
clearTimeout(oldTimeout)
}
const timeout = setTimeout(() => {
roomLeaveDebounceMap.delete(key)
}, DEBOUNCE_TIMEOUT)
roomLeaveDebounceMap.set(key, timeout)
}
// to fix: https://github.com/padlocal/wechaty-puppet-padlocal/issues/43
export function removeRoomLeaveDebounce (roomId: string, removeeId: string) {
const key = roomLeaveDebounceKey(roomId, removeeId)
roomLeaveDebounceMap.delete(key)
}
export function isRoomLeaveDebouncing (roomId: string, removeeId: string): boolean {
const key = roomLeaveDebounceKey(roomId, removeeId)
return roomLeaveDebounceMap.get(key) !== undefined
}
export default async (puppet: PUPPET.Puppet, message: WebMessageRawPayload): Promise<EventPayload> => {
const roomId = message.FromUserName
if (!isRoomId(roomId) || ![ WebMessageType.SYS ].includes(message.MsgType)) {
return null
}
/**
* 1. 我将别人移除
* /^(你)将"(.+)"移出了群聊/,
* 我移除别人是 10002: https://gist.github.com/padlocal/5676b96ad0ca918fdd53849417eff422
*/
const youRemoveOther = async () => {
let matches: null | string[] = null
YOU_REMOVE_OTHER_REGEX_LIST.some((re) => !!(matches = message.Content.match(re)))
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (matches) {
const removerName = matches[2]!
const removerId = (await puppet.roomMemberSearch(roomId, removerName))[0]!
return {
removeeIdList: [ removerId ],
removerId: puppet.currentUserId,
roomId,
timestamp: message.CreateTime,
} as PUPPET.payloads.EventRoomLeave
}
return null
}
/**
* 2. 别人移除我
* /^(你)被"([^"]+?)"移出群聊/,
* // 我被别人移除是 10000:https://gist.github.com/padlocal/60be89334d4d743937f07023da20291e
*/
const otherRemoveYou = async () => {
let matches: null | string[] = null
OTHER_REMOVE_YOU_REGEX_LIST.some((re) => !!(matches = message.Content.match(re)))
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (matches) {
const removerName = matches[2]!
const removerId = (await puppet.roomMemberSearch(roomId, removerName))[0]!
return {
removeeIdList: [ puppet.currentUserId ],
removerId,
roomId,
timestamp: message.CreateTime,
} as PUPPET.payloads.EventRoomLeave
}
return null
}
const ret = await executeRunners<PUPPET.payloads.EventRoomLeave>([ youRemoveOther, otherRemoveYou ])
if (ret) {
ret.removeeIdList.forEach((leaverId) => {
roomLeaveAddDebounce(roomId, leaverId)
})
}
return ret
}