From 10f307197e5f4cbebcdc76da10ce750b7c194997 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Sat, 11 Apr 2026 16:47:27 +0200 Subject: [PATCH 1/2] feat: pin and unpin commands --- src/commands/index.ts | 3 +- src/commands/pin.ts | 69 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/commands/pin.ts diff --git a/src/commands/index.ts b/src/commands/index.ts index 6d05682..6da4994 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -14,6 +14,7 @@ import { printCtxFrom } from "@/utils/users" import { linkAdminDashboard } from "./link-admin-dashboard" import { management } from "./management" import { moderation } from "./moderation" +import { pin } from "./pin" import { report } from "./report" import { search } from "./search" @@ -136,4 +137,4 @@ export const commands = new ManagedCommands() + .createCommand({ + trigger: "pin", + description: "Pin a message in a group", + scope: "group", + reply: "required", + permissions: { + allowGroupAdmins: true, + allowedRoles: ["direttivo", "owner"], + }, + handler: async ({ context, repliedTo }) => { + if (!repliedTo.from) { + logger.error("report: no repliedTo.from field (the msg was sent in a channel)") + return + } + + const member = await context.getChatMember(context.me.id) + if (member.status !== "administrator") + return await ephemeral(context.reply(fmt(({ n }) => n`❌ The bot is not an admin`)), 10_000) + + if (!member.can_pin_messages) + return await ephemeral( + context.reply(fmt(({ n, code }) => n`❌ The bot is missing the ${code`Pin messages`} permission.`)), + 10_000 + ) + + const res = await context.pinChatMessage(repliedTo.message_id).catch(() => false) + if (!res) return await ephemeral(context.reply(fmt(({ n }) => n`❌ Cannot pin the message`)), 10_000) + + await ephemeral(context.reply(fmt(({ n }) => n`✅ Message pinned`)), 10_000) + }, + }) + .createCommand({ + trigger: "unpin", + description: "Unpin a message in a group", + scope: "group", + reply: "required", + permissions: { + allowGroupAdmins: true, + allowedRoles: ["direttivo", "owner"], + }, + handler: async ({ context, repliedTo }) => { + if (!repliedTo.from) { + logger.error("report: no repliedTo.from field (the msg was sent in a channel)") + return + } + + const member = await context.getChatMember(context.me.id) + if (member.status !== "administrator") + return await ephemeral(context.reply(fmt(({ n }) => n`❌ The bot is not an admin`)), 10_000) + + if (!member.can_pin_messages) + return await ephemeral( + context.reply(fmt(({ n, code }) => n`❌ The bot is missing the ${code`Pin messages`} permission.`)), + 10_000 + ) + + const res = await context.unpinChatMessage(repliedTo.message_id).catch(() => false) + if (!res) return await ephemeral(context.reply(fmt(({ n }) => n`❌ Cannot unpin the message`)), 10_000) + + await ephemeral(context.reply(fmt(({ n }) => n`✅ Message pinned`)), 10_000) + }, + }) From c2efd0fd371840ff65dd4f1b5fe59a910bf81b19 Mon Sep 17 00:00:00 2001 From: Lorenzo Corallo Date: Sat, 11 Apr 2026 16:53:42 +0200 Subject: [PATCH 2/2] fix: remove repliedTo.from check, typo --- src/commands/pin.ts | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/commands/pin.ts b/src/commands/pin.ts index b5a70b1..ccc76de 100644 --- a/src/commands/pin.ts +++ b/src/commands/pin.ts @@ -15,11 +15,6 @@ export const pin = new CommandsCollection() allowedRoles: ["direttivo", "owner"], }, handler: async ({ context, repliedTo }) => { - if (!repliedTo.from) { - logger.error("report: no repliedTo.from field (the msg was sent in a channel)") - return - } - const member = await context.getChatMember(context.me.id) if (member.status !== "administrator") return await ephemeral(context.reply(fmt(({ n }) => n`❌ The bot is not an admin`)), 10_000) @@ -46,11 +41,6 @@ export const pin = new CommandsCollection() allowedRoles: ["direttivo", "owner"], }, handler: async ({ context, repliedTo }) => { - if (!repliedTo.from) { - logger.error("report: no repliedTo.from field (the msg was sent in a channel)") - return - } - const member = await context.getChatMember(context.me.id) if (member.status !== "administrator") return await ephemeral(context.reply(fmt(({ n }) => n`❌ The bot is not an admin`)), 10_000) @@ -64,6 +54,6 @@ export const pin = new CommandsCollection() const res = await context.unpinChatMessage(repliedTo.message_id).catch(() => false) if (!res) return await ephemeral(context.reply(fmt(({ n }) => n`❌ Cannot unpin the message`)), 10_000) - await ephemeral(context.reply(fmt(({ n }) => n`✅ Message pinned`)), 10_000) + await ephemeral(context.reply(fmt(({ n }) => n`✅ Message unpinned`)), 10_000) }, })