IntegrationsAdvanced

How to build an AI moderator bot for a Telegram group

Let a bot read group messages, classify them with an LLM, and remove or warn on rule-breaking content.

12 minAdvanced

A moderator bot watches a group, sends each message to a model that judges whether it breaks the rules, and acts on the verdict. This guide builds one that warns on borderline content and deletes clear violations. It needs careful permissions and a conservative prompt to avoid false positives.

What you need

  • A bot that is an admin of the group with Delete Messages and Ban Users rights
  • An LLM API key (Anthropic Claude here)
  • Privacy Mode turned off so the bot sees all messages
  • Node 18 or newer

Step 1: Disable Privacy Mode

By default a bot only sees commands and replies in groups. To moderate everything, open BotFather, run /setprivacy, pick the bot, and choose Disable. Then remove and re-add the bot so the change takes effect.

Chat with @BotFather
You
/setprivacy
Agent
Choose a bot to change group messages settings.
You
@order_helper_bot
Agent
'Disable' - your bot will receive all messages. Current status is: ENABLED
You
Disable
Agent
Success! The new status is: DISABLED.

Step 2: Classify each message

Ask the model for a strict, machine-readable verdict. Forcing JSON output keeps the parsing reliable and the actions predictable.

moderate.mjs
import TelegramBot from "node-telegram-bot-api";
import Anthropic from "@anthropic-ai/sdk";

const bot = new TelegramBot(process.env.TELEGRAM_BOT_TOKEN, {
  polling: true,
});
const ai = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

const RULES =
  "Rules: no spam links, no insults, no NSFW. " +
  "Reply ONLY as JSON: {\"verdict\":\"ok|warn|remove\",\"reason\":\"...\"}";

async function classify(text) {
  const r = await ai.messages.create({
    model: "claude-opus-4-5",
    max_tokens: 150,
    system: RULES,
    messages: [{ role: "user", content: text }],
  });
  const raw = r.content.find((b) => b.type === "text")?.text ?? "{}";
  try {
    return JSON.parse(raw);
  } catch {
    return { verdict: "ok", reason: "unparseable" };
  }
}

Step 3: Act on the verdict

Wire the classifier to the message event. Warnings get a public reply, removals delete the offending message. Always be conservative: when unsure, do nothing.

moderate.mjs (continued)
bot.on("message", async (msg) => {
  if (!msg.text || msg.chat.type === "private") return;

  const { verdict, reason } = await classify(msg.text);

  if (verdict === "warn") {
    await bot.sendMessage(
      msg.chat.id,
      `Heads up: ${reason}. Please keep it friendly.`,
      { reply_to_message_id: msg.message_id }
    );
  } else if (verdict === "remove") {
    await bot.deleteMessage(msg.chat.id, msg.message_id);
    await bot.sendMessage(
      msg.chat.id,
      "A message was removed for breaking the rules."
    );
  }
});
Tune before you trust it
An over-eager moderator drives people away faster than spam does. Start in warn-only mode, log every verdict, review the false positives, then enable deletions once you trust the prompt.
Telegram - group action
You
click here to win free crypto >> spam.link
Agent
A message was removed for breaking the rules.
Cost control
Classifying every message costs an API call each time. Filter cheaply first (skip very short messages, known-good members) and only send the rest to the model.

Result

The bot now reads the group, judges each message against your rules, and takes graded action. With logging and a conservative prompt it handles the obvious cases so your human mods focus on the gray ones.

Watch related tutorials

Tags
#telegram#moderation#ai#group#bot