Skip to content

Commit 4b268f8

Browse files
authored
fix: offload message deletion with raw api call (#95)
* fix: offload message deletion with raw api call * fix: avoid throwing if message promise rejects
1 parent eb431ea commit 4b268f8

12 files changed

Lines changed: 40 additions & 43 deletions

File tree

src/commands/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const commands = new ManagedCommands<Role, Context, TelemetryContextFlavo
3939
logger.info(
4040
`[ManagedCommands] Command '/${command.trigger}' with scope '${command.scope}' invoked by ${printCtxFrom(context)} in a '${context.chat.type}' chat`
4141
)
42-
await ephemeral(
42+
void ephemeral(
4343
context.reply(
4444
fmt(
4545
({ n }) =>
@@ -55,7 +55,7 @@ export const commands = new ManagedCommands<Role, Context, TelemetryContextFlavo
5555
`[ManagedCommands] Command '/${command.trigger}' invoked by ${printCtxFrom(context)} without permissions`
5656
)
5757
// Inform the user of restricted access
58-
await ephemeral(context.reply(fmt(({ n }) => n`You are not allowed to execute this command`)))
58+
void ephemeral(context.reply(fmt(({ n }) => n`You are not allowed to execute this command`)))
5959
},
6060
conversationBegin: async ({ context, command, conversation }) => {
6161
const now = await conversation.now()

src/commands/invite.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ export const invite = new CommandsCollection<Role>().createCommand({
1313
const inviteLink =
1414
chat.invite_link ?? (await api.tg.groups.getById.query({ telegramId: context.chatId }).catch(() => null))?.link
1515

16-
if (!inviteLink)
17-
return await ephemeral(context.reply(fmt(({ n }) => n`❌ Cannot retrieve the invite link`)), 10_000)
16+
if (!inviteLink) return void ephemeral(context.reply(fmt(({ n }) => n`❌ Cannot retrieve the invite link`)), 10_000)
1817

19-
await ephemeral(context.reply(fmt(({ n }) => n`🔗 ${inviteLink}`)))
18+
void ephemeral(context.reply(fmt(({ n }) => n`🔗 ${inviteLink}`)))
2019
},
2120
})

src/commands/link-admin-dashboard.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,6 @@ export const linkAdminDashboard = new CommandsCollection<Role>().createCommand({
109109
)
110110
}
111111

112-
await ephemeral(msg)
112+
void ephemeral(msg)
113113
},
114114
})

src/commands/moderation/ban.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export const ban = new CommandsCollection<Role>("Banning")
3232
handler: async ({ args, context, repliedTo }) => {
3333
const userOverload = await getOverloadUser(context, repliedTo, args.reasonOrUser, args.reason)
3434
if (userOverload.isErr()) {
35-
await ephemeral(
35+
void ephemeral(
3636
context.reply(
3737
repliedTo
3838
? fmt(({ n }) => n`There was an error`)
@@ -53,7 +53,7 @@ export const ban = new CommandsCollection<Role>("Banning")
5353
repliedTo ? [repliedTo] : undefined,
5454
reason
5555
)
56-
if (res.isErr()) await ephemeral(context.reply(res.error.fmtError))
56+
if (res.isErr()) void ephemeral(context.reply(res.error.fmtError))
5757
},
5858
})
5959
.createCommand({
@@ -89,7 +89,7 @@ export const ban = new CommandsCollection<Role>("Banning")
8989
[repliedTo],
9090
args.reason
9191
)
92-
if (res.isErr()) await ephemeral(context.reply(res.error.fmtError))
92+
if (res.isErr()) void ephemeral(context.reply(res.error.fmtError))
9393
},
9494
})
9595
.createCommand({
@@ -108,18 +108,16 @@ export const ban = new CommandsCollection<Role>("Banning")
108108

109109
if (!userId) {
110110
logger.debug(`unban: no userId for username ${args.username}`)
111-
await ephemeral(context.reply(fmt(({ b }) => b`@${context.from.username} user not found`)))
112-
return
111+
return void ephemeral(context.reply(fmt(({ b }) => b`@${context.from.username} user not found`)))
113112
}
114113

115114
const user = await getUser(userId, context)
116115
if (!user) {
117116
logger.error({ userId }, "UNBAN: cannot retrieve the user")
118-
await ephemeral(context.reply(fmt(({ n }) => [n`Error: cannot find this user`])))
119-
return
117+
return void ephemeral(context.reply(fmt(({ n }) => [n`Error: cannot find this user`])))
120118
}
121119

122120
const res = await Moderation.unban(user, context.chat, context.from)
123-
if (res.isErr()) await ephemeral(context.reply(res.error.fmtError))
121+
if (res.isErr()) void ephemeral(context.reply(res.error.fmtError))
124122
},
125123
})

src/commands/moderation/del.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ export const del = new CommandsCollection<Role>("Deletion").createCommand({
2424
})
2525

2626
const res = await Moderation.deleteMessages([repliedTo], context.from, "Command /del")
27-
if (res.isErr()) await ephemeral(context.reply(fmt(({ n }) => n`Cannot delete the message`)))
27+
if (res.isErr()) void ephemeral(context.reply(fmt(({ n }) => n`Cannot delete the message`)))
2828
},
2929
})

src/commands/moderation/kick.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ export const kick = new CommandsCollection<Role>("Kicking").createCommand({
2222
}
2323

2424
const res = await Moderation.kick(repliedTo.from, context.chat, context.from, [repliedTo], args.reason)
25-
if (res.isErr()) await ephemeral(context.reply(res.error.fmtError))
25+
if (res.isErr()) void ephemeral(context.reply(res.error.fmtError))
2626
},
2727
})

src/commands/moderation/mute.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export const mute = new CommandsCollection<Role>("Muting")
4242
[repliedTo],
4343
args.reason
4444
)
45-
if (res.isErr()) await ephemeral(context.reply(res.error.fmtError))
45+
if (res.isErr()) void ephemeral(context.reply(res.error.fmtError))
4646
},
4747
})
4848
.createCommand({
@@ -68,7 +68,7 @@ export const mute = new CommandsCollection<Role>("Muting")
6868
handler: async ({ args, context, repliedTo }) => {
6969
const userOverload = await getOverloadUser(context, repliedTo, args.reasonOrUser, args.reason)
7070
if (userOverload.isErr()) {
71-
await ephemeral(
71+
void ephemeral(
7272
context.reply(
7373
repliedTo
7474
? fmt(({ n }) => n`There was an error`)
@@ -89,7 +89,7 @@ export const mute = new CommandsCollection<Role>("Muting")
8989
repliedTo ? [repliedTo] : undefined,
9090
reason
9191
)
92-
if (res.isErr()) await ephemeral(context.reply(res.error.fmtError))
92+
if (res.isErr()) void ephemeral(context.reply(res.error.fmtError))
9393
},
9494
})
9595
.createCommand({
@@ -108,19 +108,17 @@ export const mute = new CommandsCollection<Role>("Muting")
108108
if (!userId) {
109109
logger.debug(`unmute: no userId for username ${args.username}`)
110110
const msg = await context.reply(fmt(({ b }) => b`@${context.from.username} user not found`))
111-
await ephemeral(msg)
112-
return
111+
return void ephemeral(msg)
113112
}
114113

115114
const user = await getUser(userId, context)
116115
if (!user) {
117116
const msg = await context.reply(fmt(({ n }) => n`Error: cannot find this user`))
118117
logger.error({ userId }, "UNMUTE: cannot retrieve the user")
119-
await ephemeral(msg)
120-
return
118+
return void ephemeral(msg)
121119
}
122120

123121
const res = await Moderation.unmute(user, context.chat, context.from)
124-
if (res.isErr()) await ephemeral(context.reply(res.error.fmtError))
122+
if (res.isErr()) void ephemeral(context.reply(res.error.fmtError))
125123
},
126124
})

src/commands/pin.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { CommandsCollection } from "@/lib/managed-commands"
2-
import { logger } from "@/logger"
32
import { fmt } from "@/utils/format"
43
import { ephemeral } from "@/utils/messages"
54
import type { Role } from "@/utils/types"
@@ -17,18 +16,18 @@ export const pin = new CommandsCollection<Role>()
1716
handler: async ({ context, repliedTo }) => {
1817
const member = await context.getChatMember(context.me.id)
1918
if (member.status !== "administrator")
20-
return await ephemeral(context.reply(fmt(({ n }) => n`❌ The bot is not an admin`)), 10_000)
19+
return void ephemeral(context.reply(fmt(({ n }) => n`❌ The bot is not an admin`)), 10_000)
2120

2221
if (!member.can_pin_messages)
23-
return await ephemeral(
22+
return void ephemeral(
2423
context.reply(fmt(({ n, code }) => n`❌ The bot is missing the ${code`Pin messages`} permission.`)),
2524
10_000
2625
)
2726

2827
const res = await context.pinChatMessage(repliedTo.message_id).catch(() => false)
29-
if (!res) return await ephemeral(context.reply(fmt(({ n }) => n`❌ Cannot pin the message`)), 10_000)
28+
if (!res) return void ephemeral(context.reply(fmt(({ n }) => n`❌ Cannot pin the message`)), 10_000)
3029

31-
await ephemeral(context.reply(fmt(({ n }) => n`✅ Message pinned`)), 10_000)
30+
void ephemeral(context.reply(fmt(({ n }) => n`✅ Message pinned`)), 10_000)
3231
},
3332
})
3433
.createCommand({
@@ -43,17 +42,17 @@ export const pin = new CommandsCollection<Role>()
4342
handler: async ({ context, repliedTo }) => {
4443
const member = await context.getChatMember(context.me.id)
4544
if (member.status !== "administrator")
46-
return await ephemeral(context.reply(fmt(({ n }) => n`❌ The bot is not an admin`)), 10_000)
45+
return void ephemeral(context.reply(fmt(({ n }) => n`❌ The bot is not an admin`)), 10_000)
4746

4847
if (!member.can_pin_messages)
49-
return await ephemeral(
48+
return void ephemeral(
5049
context.reply(fmt(({ n, code }) => n`❌ The bot is missing the ${code`Pin messages`} permission.`)),
5150
10_000
5251
)
5352

5453
const res = await context.unpinChatMessage(repliedTo.message_id).catch(() => false)
55-
if (!res) return await ephemeral(context.reply(fmt(({ n }) => n`❌ Cannot unpin the message`)), 10_000)
54+
if (!res) return void ephemeral(context.reply(fmt(({ n }) => n`❌ Cannot unpin the message`)), 10_000)
5655

57-
await ephemeral(context.reply(fmt(({ n }) => n`✅ Message unpinned`)), 10_000)
56+
void ephemeral(context.reply(fmt(({ n }) => n`✅ Message unpinned`)), 10_000)
5857
},
5958
})

src/lib/managed-commands/index.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -365,13 +365,11 @@ export class ManagedCommands<
365365
)
366366

367367
this.composer.command("help", async (ctx) => {
368-
if (ctx.chat.type !== "private") {
369-
await ephemeral(
368+
if (ctx.chat.type !== "private")
369+
return void ephemeral(
370370
ctx.reply(fmt(({ n, code }) => n`You can only send ${code`/help`} in private chat with the bot.`)),
371371
10_000
372372
)
373-
return
374-
}
375373

376374
const text = ctx.message?.text ?? ""
377375

src/utils/messages.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type { MessageXFragment } from "@grammyjs/hydrate/out/data/message"
21
import type { Message, User } from "grammy/types"
3-
import type { MaybePromise } from "./types"
2+
import { modules } from "@/modules"
3+
import type { MaybePromise, PartialMessage } from "./types"
44
import { wait } from "./wait"
55

66
type TextReturn<M extends Message> = M extends { text: string }
@@ -47,9 +47,10 @@ export function createFakeMessage(chatId: number, messageId: number, from: User,
4747
* @param timeout Timeout in ms, defaults to 20 seconds
4848
* @returns a void promise that resolves after the message is deleted (or if the deletion fails)
4949
*/
50-
export async function ephemeral(message: MaybePromise<MessageXFragment>, timeout = 20000): Promise<void> {
51-
const msg = await Promise.resolve(message)
50+
export async function ephemeral(message: MaybePromise<PartialMessage>, timeout = 20000): Promise<void> {
51+
const msg = await Promise.resolve(message).catch(() => null)
52+
if (!msg) return
5253
await wait(timeout)
53-
.then(() => msg.delete())
54+
.then(() => modules.shared.api.deleteMessage(msg.chat.id, msg.message_id))
5455
.catch(() => {})
5556
}

0 commit comments

Comments
 (0)