Skip to content

Commit

Permalink
feat: bot.myStatus - to simplify my_chat_member
Browse files Browse the repository at this point in the history
  • Loading branch information
MKRhere committed Sep 2, 2023
1 parent 684c51a commit bfc94cb
Showing 1 changed file with 89 additions and 1 deletion.
90 changes: 89 additions & 1 deletion src/composer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,28 @@ interface CommandContextExtn {
args: string[]
}

interface StatusContextExtn {
/** Shorthand for old and new my_chat_member status */
status: {
/** */
change: StatusChange
/** Shorthand for update.my_chat_member.old_chat_member.status */
old: tg.ChatMember['status']
/** Shorthand for update.my_chat_member.new_chat_member.status */
new: tg.ChatMember['status']
}
}

type StatusChange =
| 'blocked'
| 'unblocked'
| 'joined'
| 'left'
| 'banned'
| 'restricted'
| 'promoted'
| 'demoted'

const anoop = always(Promise.resolve())

export class Composer<C extends Context> implements MiddlewareObj<C> {
Expand Down Expand Up @@ -161,7 +183,7 @@ export class Composer<C extends Context> implements MiddlewareObj<C> {
Middleware<NarrowedContext<C, tt.MountMap['text']> & CommandContextExtn>
>
) {
return this.use(Composer.command<C>(command, ...fns))
return this.use(Composer.command(command, ...fns))
}

/**
Expand Down Expand Up @@ -297,6 +319,23 @@ export class Composer<C extends Context> implements MiddlewareObj<C> {
return this.command('settings', ...fns)
}

/**
* Listen for the bot's status change in chats
*
* * `joined`, `left`, `promoted`, `demoted`, `banned`, `restricted` will only be triggered in non-private chats
* * `blocked`, `unblocked` will only be triggered in private chats
*/
myStatus(
change: MaybeArray<StatusChange>,
...fns: NonemptyReadonlyArray<
Middleware<
NarrowedContext<C, tt.MountMap['my_chat_member']> & StatusContextExtn
>
>
) {
return this.use(Composer.myStatus(change, Composer.compose(fns)))
}

middleware() {
return this.handler
}
Expand Down Expand Up @@ -917,6 +956,35 @@ export class Composer<C extends Context> implements MiddlewareObj<C> {
}
}
}

static myStatus<C extends Context>(
type: MaybeArray<StatusChange>,
...fns: NonemptyReadonlyArray<
Middleware<
NarrowedContext<C, tt.MountMap['my_chat_member']> & StatusContextExtn
>
>
): MiddlewareFn<C> {
const changes = Array.isArray(type) ? type : [type]
const handler = Composer.compose(fns)

return Composer.on('my_chat_member', async (ctx, next) => {
const status = {
new: ctx.myChatMember.new_chat_member.status,
old: ctx.myChatMember.old_chat_member.status,
}

for (const change of changes) {
// todo: decide whether to normalise and fire for all matching changes, or just the first matching one
// ref: https://github.com/telegraf/telegraf/issues/1872
if (checkStatusChange(change, ctx.chat.type, status.new, status.old))
return handler(
Object.assign(ctx, { status: Object.assign(status, { change }) }),
next
)
}
})
}
}

function escapeRegExp(s: string) {
Expand Down Expand Up @@ -950,6 +1018,7 @@ function getEntities(msg: tg.Message | undefined): tg.MessageEntity[] {
if ('entities' in msg) return msg.entities ?? []
return []
}

function getText(
msg: tg.Message | tg.CallbackQuery | undefined
): string | undefined {
Expand All @@ -969,4 +1038,23 @@ function normaliseTextArguments(argument: MaybeArray<string>, prefix = '') {
.map((arg) => prefix && typeof arg === 'string' && !arg.startsWith(prefix) ? `${prefix}${arg}` : arg)
}

function checkStatusChange(
change: StatusChange,
chatType: tg.Chat['type'],
current: tg.ChatMember['status'],
old: tg.ChatMember['status']
) {
if (chatType === 'private') {
if (change === 'blocked') return current === 'kicked'
if (change === 'unblocked') return current === 'member'
} else {
if (change === 'joined') return old === 'left' || old === 'kicked'
if (change === 'banned') return current === 'kicked'
if (change === 'left') return current === 'left'
if (change === 'restricted') return current === 'restricted'
if (change === 'promoted') return current === 'administrator'
if (change === 'demoted') return old === 'administrator'
}
}

export default Composer

0 comments on commit bfc94cb

Please sign in to comment.