chat admin

build moderation bots for groups, supergroups, channels, join requests, permissions, and forum topics.

ban from a reply

a simple admin command usually targets the user in the replied-to message. check permissions in your own guard before calling moderation methods.

ban.ts
bot.command("ban", async (ctx) => {
  const target = ctx.message?.reply_to_message?.from;
  if (!target || !ctx.chat) return ctx.reply("reply to a user first");

  await ctx.api.call("banChatMember", {
    chat_id: ctx.chat.id,
    user_id: target.id,
  });
});

approve or decline join requests

join requests are opt-in updates. include chat_join_request in allowedUpdates when using long polling.

join-request.ts
bot.on("chat_join_request", async (ctx) => {
  const request = ctx.update.chat_join_request!;

  if (await isAllowed(request.from.id)) {
    await ctx.api.call("approveChatJoinRequest", {
      chat_id: request.chat.id,
      user_id: request.from.id,
    });
  } else {
    await ctx.api.call("declineChatJoinRequest", {
      chat_id: request.chat.id,
      user_id: request.from.id,
    });
  }
});

track member changes

chat_member updates tell you when users join, leave, get promoted, or are restricted. they are useful for audit logs and permission caches.

chat-member.ts
bot.on("chat_member", async (ctx) => {
  const update = ctx.update.chat_member!;
  console.log(update.from.id, update.old_chat_member.status, "->", update.new_chat_member.status);
});

admin checklist

  • ask botfather for the permissions your bot actually needs.
  • check that the bot is an admin before promising moderation features.
  • handle supergroup migrations if your bot stores old group ids.
  • keep audit logs for destructive actions.
  • rate-limit public admin commands to avoid accidental spam.