feat(dispatcher): support usernames and me/self in userId and chatId filters

This commit is contained in:
teidesu 2021-06-19 19:53:31 +03:00
parent f2671d3c0b
commit f44bf77a07

View file

@ -344,26 +344,50 @@ export namespace filters {
> => (msg) => msg.chat.type === type > => (msg) => msg.chat.type === type
/** /**
* Filter updates by chat ID(s) * Filter updates by chat ID(s) or username(s)
*/ */
export const chatId = (id: MaybeArray<number>): UpdateFilter<Message> => { export const chatId = (
id: MaybeArray<number | string>
): UpdateFilter<Message> => {
if (Array.isArray(id)) { if (Array.isArray(id)) {
const index: Record<number, true> = {} const index: Record<number | string, true> = {}
id.forEach((id) => (index[id] = true)) let matchSelf = false
id.forEach((id) => {
if (id === 'me' || id === 'self') {
matchSelf = true
} else {
index[id] = true
}
})
return (msg) => msg.chat.id in index return (msg) =>
(matchSelf && msg.chat.isSelf) ||
msg.chat.id in index ||
msg.chat.username! in index
}
if (id === 'me' || id === 'self') {
return (msg) => msg.chat.isSelf
}
if (typeof id === 'string') {
return (msg) => msg.chat.username === id
} }
return (msg) => msg.chat.id === id return (msg) => msg.chat.id === id
} }
/** /**
* Filter updates by user ID(s) * Filter updates by user ID(s) or username(s)
*
* Usernames are not supported for UserStatusUpdate
* and UserTypingUpdate.
*
* *
* For chat member updates, uses `user.id` * For chat member updates, uses `user.id`
*/ */
export const userId = ( export const userId = (
id: MaybeArray<number> id: MaybeArray<number | string>
): UpdateFilter< ): UpdateFilter<
| Message | Message
| InlineQuery | InlineQuery
@ -375,54 +399,111 @@ export namespace filters {
| UserTypingUpdate | UserTypingUpdate
> => { > => {
if (Array.isArray(id)) { if (Array.isArray(id)) {
const index: Record<number, true> = {} const index: Record<number | string, true> = {}
id.forEach((id) => (index[id] = true)) let matchSelf = false
id.forEach((id) => {
if (id === 'me' || id === 'self') {
matchSelf = true
} else {
index[id] = true
}
})
return (upd) => { return (upd) => {
const ctor = upd.constructor const ctor = upd.constructor
if (ctor === Message) { if (ctor === Message) {
return (upd as Message).sender.id in index const sender = (upd as Message).sender
return (
(matchSelf && sender.isSelf) ||
sender.id in index ||
sender.username! in index
)
} else { } else {
if ( if (
ctor === UserStatusUpdate || ctor === UserStatusUpdate ||
ctor === UserTypingUpdate ctor === UserTypingUpdate
) { ) {
return ( const id = (upd as UserStatusUpdate | UserTypingUpdate).userId
(upd as UserStatusUpdate | UserTypingUpdate) return matchSelf && id === upd.client['_userId'] || id in index
.userId in index
)
} else { } else {
const user = (upd as Exclude<
typeof upd,
Message | UserStatusUpdate | UserTypingUpdate
>).user
return ( return (
(upd as Exclude< (matchSelf && user.isSelf) ||
typeof upd, user.id in index ||
Message | UserStatusUpdate | UserTypingUpdate user.username! in index
>).user.id in index
) )
} }
} }
} }
} }
if (id === 'me' || id === 'self') {
return (upd) => {
const ctor = upd.constructor
if (ctor === Message) {
return (upd as Message).sender.isSelf
} else if (
ctor === UserStatusUpdate ||
ctor === UserTypingUpdate
) {
return (
(upd as UserStatusUpdate | UserTypingUpdate).userId ===
upd.client['_userId']
)
} else {
return (upd as Exclude<
typeof upd,
Message | UserStatusUpdate | UserTypingUpdate
>).user.isSelf
}
}
}
if (typeof id === 'string') {
return (upd) => {
const ctor = upd.constructor
if (ctor === Message) {
return (upd as Message).sender.username === id
} else if (
ctor === UserStatusUpdate ||
ctor === UserTypingUpdate
) {
// username is not available
return false
} else {
return (
(upd as Exclude<
typeof upd,
Message | UserStatusUpdate | UserTypingUpdate
>).user.username === id
)
}
}
}
return (upd) => { return (upd) => {
const ctor = upd.constructor const ctor = upd.constructor
if (ctor === Message) { if (ctor === Message) {
return (upd as Message).sender.id === id return (upd as Message).sender.id === id
} else if (ctor === UserStatusUpdate || ctor === UserTypingUpdate) {
return (
(upd as UserStatusUpdate | UserTypingUpdate).userId === id
)
} else { } else {
if (ctor === UserStatusUpdate || ctor === UserTypingUpdate) { return (
return ( (upd as Exclude<
(upd as UserStatusUpdate | UserTypingUpdate).userId === typeof upd,
id Message | UserStatusUpdate | UserTypingUpdate
) >).user.id === id
} else { )
return (
(upd as Exclude<
typeof upd,
Message | UserStatusUpdate | UserTypingUpdate
>).user.id === id
)
}
} }
} }
} }
@ -750,11 +831,10 @@ export namespace filters {
if (!msg.client['_botUsername']) { if (!msg.client['_botUsername']) {
// need to fetch it first // need to fetch it first
return msg.client.getUsers('self') return msg.client.getUsers('self').then((self) => {
.then((self) => { msg.client['_botUsername'] = self.username!
msg.client['_botUsername'] = self.username! return check(msg)
return check(msg) })
})
} }
if (m[1] !== msg.client['_botUsername']) return false if (m[1] !== msg.client['_botUsername']) return false