> ## Documentation Index
> Fetch the complete documentation index at: https://comis-feature-skill-archive-import.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Telegram

> Connect Comis to Telegram with step-by-step setup

Connect your Comis agent to Telegram groups, channels, forum topics, and private chats.
Telegram supports reactions, inline buttons, HTML formatting, file attachments
up to 50 MB, and live-streaming responses that update in real time as your
agent thinks.

<Info>
  You don't need to understand the technical details to use this feature. The configuration examples below are copy-paste ready.
</Info>

## Prerequisites

* Comis installed and running ([Quickstart](/get-started/quickstart))

- A Telegram account

<Note>
  This page covers three Telegram chat types: **direct messages** (1:1), **groups**
  (multi-party conversation), and **channels** (broadcast feeds). Each has its own
  section below; the [Setup](#setup) flow gets the bot online for DMs, then the
  [Groups](#groups) and [Channels](#channels) sections add the chat-type specifics.
</Note>

<Note>
  **Setting this up for several people or a team?** See
  [Multiple users and teams](/channels/multi-user) for the privacy and isolation
  model - DMs are private per person, but a shared agent shares its learned memory,
  so route each person or group to their own agent for full separation.
</Note>

<Warning>
  **Group privacy mode is ON by default.** With the default in place, Telegram
  only forwards group messages to your bot when the message @-mentions it, replies
  to one of its messages, or is a `/cmd@<botname>` command. Plain group chatter
  never reaches Comis. If you want the bot to respond freely (or use
  `groupActivation: "always" | "custom"`), follow the
  [Disable BotFather privacy mode](#disable-botfather-privacy-mode) procedure -
  **toggling the setting alone is not enough**, you must kick and re-add the bot
  afterwards because Telegram caches the privacy flag at the moment the bot joins.
</Warning>

## Setup

<Steps>
  <Step title="Create a bot with BotFather">
    Open Telegram and search for **@BotFather** (the official bot for creating
    bots - verified with a blue check).

    Send `/newbot` and follow the prompts:

    1. Choose a display name for your bot (for example, **MyTeamBot**)
    2. Choose a username ending in `bot` (for example, `my_team_comis_bot`)

    BotFather will confirm creation and display your bot token.
  </Step>

  <Step title="Copy the bot token">
    BotFather replies with a token that looks like `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`.
    Copy it immediately and store it somewhere safe.

    This token is your bot's password. Anyone who has it can control your bot.
  </Step>

  <Step title="Configure Comis">
    Add the Telegram channel to your Comis configuration file (`~/.comis/config.yaml`):

    ```yaml theme={null}
    channels:
      telegram:
        enabled: true
        botToken: "${TELEGRAM_BOT_TOKEN}"
    ```

    Set the `TELEGRAM_BOT_TOKEN` environment variable in your `~/.comis/.env` file:

    ```bash theme={null}
    TELEGRAM_BOT_TOKEN=your-token-from-step-2
    ```

    <Warning>
      Never store API keys, tokens, or passwords directly in `config.yaml`. Use the `.env` file or [Secret Manager](/security/secrets) for credential management.
    </Warning>
  </Step>

  <Step title="Restart and verify">
    Restart the Comis daemon to pick up the new configuration:

    ```bash theme={null}
    comis daemon stop && comis daemon start
    ```

    Check the logs for a successful connection:

    ```bash theme={null}
    comis daemon logs
    ```

    Look for a line containing **"Telegram adapter connected"** or
    **"channel-telegram activated"**. If you see this, your bot is online.

    Open Telegram, find your bot by its username, and send it a message to
    confirm it responds.
  </Step>
</Steps>

## Configuration

These options go under `channels.telegram` in your `config.yaml`:

| Option                             | Type               | Default    | What it does                                                                              |
| ---------------------------------- | ------------------ | ---------- | ----------------------------------------------------------------------------------------- |
| `enabled`                          | boolean            | `false`    | Turns on the Telegram adapter                                                             |
| `botToken`                         | string / SecretRef | (required) | Bot authentication token from BotFather (env: `TELEGRAM_BOT_TOKEN`)                       |
| `webhookUrl`                       | string             | (optional) | Public webhook URL. When set, Telegram pushes updates over HTTPS instead of long-polling. |
| `allowFrom`                        | string\[]          | `[]` (all) | Restrict to specific Telegram user IDs. Empty means all users can talk to the bot.        |
| `mediaProcessing.transcribeAudio`  | boolean            | `true`     | Transcribe voice messages to text before passing to the agent                             |
| `mediaProcessing.analyzeImages`    | boolean            | `true`     | Describe images sent to the bot using AI vision                                           |
| `mediaProcessing.describeVideos`   | boolean            | `true`     | Extract descriptions from video content                                                   |
| `mediaProcessing.extractDocuments` | boolean            | `true`     | Extract text from PDFs, DOCX, and other documents                                         |
| `mediaProcessing.understandLinks`  | boolean            | `true`     | Fetch and summarize URLs included in messages                                             |

By default the adapter uses **long-polling** (Grammy runner with auto-retry on
HTTP 429). Set `TELEGRAM_WEBHOOK_SECRET` in your `.env` if you switch to
webhook delivery -- Comis uses it to verify the `X-Telegram-Bot-Api-Secret-Token`
header on incoming requests.

## What your agent can do

Once connected to Telegram, your agent can:

* Send, edit, and delete messages in any chat it has access to
* React to messages with emoji (Telegram limits the supported emoji set)
* Send inline buttons for user choices
* Send rich cards with formatted content
* Use HTML formatting (bold, italic, code, links, spoilers, blockquotes, custom emoji)
* Apply message effects (spoiler reveal, silent send)
* Send file attachments up to 50 MB
* Send native voice messages (audio attachments uploaded as Telegram voice notes)
* Stream responses with live editing (updates every 300 ms)
* Mention users in group chats
* Send native polls and stickers via [platform actions](/agent-tools/platform-actions) (`poll`, `sticker`)
* Receive location and venue messages -- coordinates appear in the agent's
  message metadata so the agent can react to "I'm at the office now"
* Pin and unpin messages, set chat title and description, ban or promote
  members, and manage forum topics (create, edit, close, reopen)

Telegram supports native forum topics (threads) in supergroups. It does **not**
support fetching message history (Bot API limitation) or read receipts.

<Tip>
  **File reference guard.** Markdown like `config.go` or `README.md` looks like a
  domain name to Telegram's link previewer, which generates broken preview cards.
  Comis automatically wraps such filenames in `<code>` tags before sending so
  your messages never contain phantom link cards. No configuration is needed.
</Tip>

## Platform limits

| Limit           | Value            | What Comis does about it                                                           |
| --------------- | ---------------- | ---------------------------------------------------------------------------------- |
| Message length  | 4,096 characters | Automatically splits long responses into multiple messages at paragraph boundaries |
| Attachment size | 50 MB            | Files over 50 MB are rejected with a user-friendly error message                   |

## Groups

Telegram **groups** (and **supergroups**) are multi-party chats where many users
talk together. The bot is just another member, and Telegram applies an extra
filter - **privacy mode** - that determines which messages the bot can see at
all. The Comis activation policy then decides which of those messages should
trigger a reply. Both layers matter; misconfiguring either one results in the
bot looking "broken."

### How addressing works (default)

Out of the box, your agent activates in a group when **any** of these is true:

* The message contains `@<your_bot_username>` parsed as a Telegram mention entity
* The message is a reply to one of the bot's previous messages
* The message is a slash command targeted at the bot: `/cmd@<your_bot_username>`

Plain group chatter (no mention, no reply, no command) is silently recorded as
history context but does **not** activate the agent. This is the
`mention-gated` activation mode and is the default for `autoReplyEngine.groupActivation`.

### Setting up a Telegram group

<Steps>
  <Step title="Complete the base Setup section first">
    Confirm the bot is online and replying to DMs (the
    [Setup](#setup) flow above). Group setup builds on a working DM bot.
  </Step>

  <Step title="Add the bot to your group">
    In Telegram, open the group → tap the group name → **Add Members** →
    search for `@<your_bot_username>` → tap the bot → **Add**. The bot does
    **not** need to be an administrator unless you turn off privacy mode
    (next step) or your agent uses platform actions like ban/promote/pin
    that require admin rights.
  </Step>

  <Step title="(Recommended) Disable BotFather privacy mode">
    Required only if you want the bot to see **all** group messages - for
    example, when running with `groupActivation: "always"` or `"custom"`,
    or when your agent passively monitors group chatter. If you only need
    mention-gated behavior, **skip this step** and leave privacy on.

    See [Disable BotFather privacy mode](#disable-botfather-privacy-mode)
    immediately below for the full procedure (including the mandatory
    kick-and-readd step).
  </Step>

  <Step title="Restrict who can talk to the bot (optional)">
    By default, **any** user in the group can activate the bot. To
    restrict it to specific Telegram user IDs, add them to `allowFrom`
    in `~/.comis/config.yaml`:

    ```yaml theme={null}
    channels:
      telegram:
        enabled: true
        botToken: "${TELEGRAM_BOT_TOKEN}"
        allowFrom:
          - "678314278"      # Alice
          - "5900067809"     # Bob
    ```

    `allowFrom` is sender-keyed, not chat-keyed. Adding the group's chat ID
    to `allowFrom` does **not** whitelist the group - every individual user
    you want to enable must be listed by their Telegram user ID. To find a
    user's ID, ask them to send any message in the group while you tail
    `pm2 logs comis` (the `senderId` field is logged on every inbound).
    Leave `allowFrom: []` (or omit it) to allow all users.
  </Step>

  <Step title="Restart the daemon and verify">
    Restart the Comis daemon to pick up the new configuration:

    ```bash theme={null}
    comis daemon stop && comis daemon start
    ```

    Check the logs for a successful connection:

    ```bash theme={null}
    comis daemon logs
    ```

    Look for a line containing **"Telegram adapter connected"** or
    **"channel-telegram activated"**. In the group, send a fresh
    `@<your_bot_username> hello` (when typing `@`, tap the suggestion popup
    so Telegram parses it as a mention entity - typing the text alone is not
    enough). The bot should reply within seconds.
  </Step>
</Steps>

### Disable BotFather privacy mode

Permanently disable privacy mode so the bot sees **all** group messages
reliably.

<Steps>
  <Step title="Toggle the setting in BotFather">
    Open Telegram, message **@BotFather**, then:

    `/mybots` → select `@<your_bot_username>` → **Bot Settings** → **Group Privacy** → **Turn off**

    BotFather confirms `Privacy mode is disabled for <bot>`.
  </Step>

  <Step title="Kick and re-add the bot in every existing group">
    **This step is mandatory.** Telegram caches the privacy flag at the
    moment the bot joins a group. Toggling the setting in BotFather does
    **not** retroactively unlock messages in groups the bot is already in.

    For every group where you want the bot to see all messages:

    1. Open the group → tap the group name → **Members**
    2. Find the bot → swipe (iOS) or long-press (Android) → **Remove**
    3. Re-add the bot via **Add Members** → `@<your_bot_username>` → **Add**

    From this point on, the bot receives every message in those groups.
  </Step>

  <Step title="Verify the flag is off">
    Confirm via the Bot API directly:

    ```bash theme={null}
    TOKEN=$(grep '^TELEGRAM_BOT_TOKEN' ~/.comis/.env | cut -d= -f2- | tr -d '"')
    curl -s "https://api.telegram.org/bot${TOKEN}/getMe" | python3 -m json.tool
    ```

    Look for `"can_read_all_group_messages": true`. If it still says
    `false`, BotFather hasn't propagated the change yet - wait a minute
    and try again.
  </Step>
</Steps>

<Warning>
  **Privacy off = bot sees everything.** Once disabled, the bot receives
  every message in the group, including DMs between members that get
  quoted, file attachments, location pins, and so on. Comis still applies
  its own activation policy (so it doesn't *reply* to everything), but the
  data flows into the agent's history buffer. Only disable privacy if you
  need it.
</Warning>

### Group activation modes

Comis decides whether to activate the agent based on the
`autoReplyEngine.groupActivation` config (top level of `config.yaml`):

```yaml theme={null}
autoReplyEngine:
  enabled: true
  groupActivation: mention-gated   # default - recommended
  customPatterns: []               # used only when groupActivation: custom
  historyInjection: true           # silently buffer non-trigger messages as context
  maxHistoryInjections: 50
  maxGroupHistoryMessages: 20
```

| Mode                      | When the agent activates                                            | Privacy mode requirement |
| ------------------------- | ------------------------------------------------------------------- | ------------------------ |
| `mention-gated` (default) | Message @-mentions the bot, replies to it, or uses `/cmd@<botname>` | Privacy on is fine       |
| `always`                  | Every group message                                                 | **Privacy must be off**  |
| `custom`                  | Message text matches one of `customPatterns` (regex)                | **Privacy must be off**  |

`historyInjection: true` silently records non-trigger group messages into a
ring buffer per session, so when the agent does activate, it has the recent
context. Set to `false` to drop them entirely.

`custom` example - wake the agent on either a regex trigger or any question:

```yaml theme={null}
autoReplyEngine:
  groupActivation: custom
  customPatterns:
    - "^hey bot\\b"
    - "\\?$"
```

### Routing different groups to different agents

If you want a single bot to serve multiple agents - one per group, or one per
user - use top-level `routing` bindings. The
[Multi-agent routing](#multi-agent-routing) section below has the full schema
and examples.

### Finding a group's chat ID

You'll need the group's numeric chat ID (looks like `-1001234567890` or
`-5152588116`) for routing bindings, log filters, or sending posts
programmatically.

```bash theme={null}
# Send any message in the group with the bot present, then:
pm2 logs comis --lines 50 --nostream | grep -E '"chatId":"-[0-9]+"' | tail -3
```

Or via the API:

```bash theme={null}
TOKEN=$(grep '^TELEGRAM_BOT_TOKEN' ~/.comis/.env | cut -d= -f2- | tr -d '"')
curl -s "https://api.telegram.org/bot${TOKEN}/getUpdates" \
  | python3 -m json.tool | grep -A1 '"chat":' | head -20
```

Group chat IDs are negative; supergroup IDs are large negative numbers
(typically starting with `-100`).

## Channels

Telegram **channels** are one-way broadcast feeds: one or more administrators
post; subscribers read. Channels are not chats - there are no member messages
to respond to. Use a channel when you want the agent to publish status
updates, daily summaries, monitoring alerts, or any kind of scheduled feed.

Use a [group](#groups) instead if you want a conversational bot.

### Setting up a Telegram channel

<Steps>
  <Step title="Create the channel in Telegram">
    **iOS / Android:** tap the **pencil icon** (top right on iOS, ✏️
    floating button on Android) → **New Channel**.
    **Desktop / Web:** click the **menu icon** (☰) → **New Channel**.

    Set channel name, optional description and photo, then choose
    **Public** (gets a `t.me/<handle>` link, anyone can find it) or
    **Private** (invite-only via link).
  </Step>

  <Step title="Add the bot as an administrator">
    Channels do not have plain "members" for bots - bots must be
    administrators or they cannot post.

    Open the channel → tap the channel name (header) → **Administrators**
    → **Add Administrator** → search `@<your_bot_username>` → tap to
    select. Grant at minimum **Post Messages**. For richer behavior also
    enable **Edit Messages**, **Delete Messages**, and (if your agent
    manages subscribers) **Add Subscribers**. Save.
  </Step>

  <Step title="Find the channel's chat ID">
    Post any message in the channel as the bot's owner, then check logs
    or hit the API:

    ```bash theme={null}
    TOKEN=$(grep '^TELEGRAM_BOT_TOKEN' ~/.comis/.env | cut -d= -f2- | tr -d '"')
    curl -s "https://api.telegram.org/bot${TOKEN}/getUpdates" \
      | python3 -m json.tool | grep -B1 -A2 '"type": "channel"' | head -20
    ```

    Channel chat IDs are large negative numbers, typically
    `-1001234567890`.
  </Step>

  <Step title="Have the agent post into the channel">
    Comis treats channels as ordinary delivery targets. Your agent can
    post via the messaging tool (`message` skill), background tasks, or
    the gateway HTTP API. Use the channel's numeric chat ID as the
    target:

    ```bash theme={null}
    # Manual test from the host:
    TOKEN=$(grep '^TELEGRAM_BOT_TOKEN' ~/.comis/.env | cut -d= -f2- | tr -d '"')
    CHANNEL_ID="-1001234567890"
    curl -s "https://api.telegram.org/bot${TOKEN}/sendMessage" \
      -d "chat_id=${CHANNEL_ID}" \
      -d "text=Hello from the bot!"
    ```

    For scheduled posts, wire a [heartbeat or cron task](/agent-tools/scheduling)
    that calls the messaging tool with `channelType: "telegram"` and
    `channelId: "<channel-id>"`.
  </Step>
</Steps>

<Note>
  **Channel privacy mode does not apply.** The BotFather privacy toggle
  governs *groups*, not channels. Bot admins in channels see exactly the
  posts you'd expect to see - there's nothing extra to enable.
</Note>

### Inbound from channels

Telegram emits `channel_post` updates for messages authored in the channel.
Comis normalizes these the same way as group messages: `chatType: "channel"`
in the prompt context, `telegramChatType: "channel"` in metadata. The auto-reply
gate also applies, so if you want the agent to react to channel posts (rare -
usually channels are write-only from the agent's perspective), set
`groupActivation: "always"` or `"custom"` and target the channel's chat ID
in your routing bindings.

## Multi-agent routing

A single Telegram bot can serve multiple agents. Comis resolves which agent
handles a given message via the top-level `routing` config, with bindings
ranked by specificity (`peerId` 8 > `channelId` 4 > `guildId` 2 > `channelType` 1).

```yaml theme={null}
agents:
  default:
    model: claude-opus-4-7
  research:
    model: claude-sonnet-4-6
  ops:
    model: claude-haiku-4-5

routing:
  defaultAgentId: default
  bindings:
    # Per-chat: this group always routes to research agent
    - channelType: telegram
      channelId: "-5152588116"
      agentId: research

    # Per-user: Alice always hits ops agent (in any chat)
    - channelType: telegram
      peerId: "678314278"
      agentId: ops

    # Per-user-in-chat: Bob in the research group goes to default
    - channelType: telegram
      channelId: "-5152588116"
      peerId: "111222333"
      agentId: default
```

`mention-gated` and `allowFrom` apply **per resolved agent** - first the bot
receives the message, then the router picks the agent, then the agent's gate
runs. Multi-agent setups don't change addressing rules; they just change which
agent answers.

Routing to separate agents is also how you isolate **memory** between people:
each agent keeps its own long-term memory, secrets, and budget, so two users on
different agents never share learned facts. For the full multi-user model - what
is private by default and what isn't - see
[Multiple users and teams](/channels/multi-user).

If you need a literally separate bot identity per agent (different
`@username`, different command menus), run one Comis daemon per bot:

```bash theme={null}
mkdir -p ~/.comis-research && cp ~/.comis/config.yaml ~/.comis-research/config.yaml
# Edit to use a different TELEGRAM_BOT_TOKEN and a single agent
COMIS_CONFIG_PATHS="$HOME/.comis-research/config.yaml" \
  pm2 start packages/daemon/dist/daemon.js --name comis-research
```

The schema currently allows one `channels.telegram` entry per daemon, so
multi-bot in a single daemon is not yet supported.

## Forum Topics

Telegram supergroups can enable **forum mode**, which organizes conversations into
topics -- similar to channels within a Discord server. Each topic is a separate
conversation thread with its own name, icon, and message history. When forum mode
is enabled, your agent automatically detects which topic a message came from and
routes its replies to the same topic.

### Setting up forum topics

<Steps>
  <Step title="Enable forum mode in your Telegram group">
    Open your Telegram supergroup, go to **Settings** (tap the group name) >
    **Topics** > **Enable**. The group must be a supergroup -- regular groups
    do not support forums.
  </Step>

  <Step title="Make the bot an administrator">
    Your bot needs admin permissions to manage forum topics. Go to
    **Settings** > **Administrators** > **Add Administrator** and select your bot.
    Grant at least **Manage Topics** permission.
  </Step>

  <Step title="No Comis configuration needed">
    Forum topic support is automatic. When your bot receives a message from a
    forum topic, Comis routes replies to that topic. No changes to
    `config.yaml` are required.
  </Step>
</Steps>

### How it works

When a user sends a message in a forum topic:

1. Comis detects the topic and attaches thread metadata to the message
2. The agent processes the message as usual
3. All replies -- including multi-part responses, media, and voice -- go to the same topic
4. Typing indicators appear in the correct topic

Each topic gets its own session by default, so conversations in different topics
stay separate. See [Sessions](/agents/sessions) for details on per-topic session
isolation and how to configure it.

### General Topic

Every forum group has a **General** topic that exists by default. Comis handles
the General Topic automatically -- no special configuration is needed. Messages
sent to the General Topic work the same as messages in any other topic.

<Tip>
  Your agent can create, edit, close, and reopen forum topics using
  [platform actions](/agent-tools/platform-actions). This lets the agent organize
  conversations programmatically -- for example, creating a new topic for each
  support ticket.
</Tip>

## Complete walkthrough: from zero to first reply

Here is a top-to-bottom run for a brand-new bot called **MyTeamBot**:

<Steps>
  <Step title="Create the bot">
    Open Telegram, message **@BotFather**, send `/newbot`, type **MyTeamBot**
    as the display name, then `my_team_comis_bot` as the username.
    BotFather replies with a token like
    `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`.
  </Step>

  <Step title="Wire it into Comis">
    Add to `~/.comis/.env`:

    ```bash theme={null}
    TELEGRAM_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
    ```

    Add to `~/.comis/config.yaml` under `channels`:

    ```yaml theme={null}
    channels:
      telegram:
        enabled: true
        botToken: "${TELEGRAM_BOT_TOKEN}"
    ```
  </Step>

  <Step title="Restart the daemon and verify">
    Restart Comis:

    ```bash theme={null}
    comis daemon stop && comis daemon start
    ```

    Tail the logs:

    ```bash theme={null}
    comis daemon logs
    ```

    You should see a line like
    `{"level":30,"module":"channel-telegram","msg":"Telegram adapter connected"}`.
  </Step>

  <Step title="Send the first message">
    In Telegram, search for `@my_team_comis_bot`, tap **Start**, and send
    `Hello!`. The bot shows a typing indicator, then replies with whatever
    your agent's persona dictates -- streamed live with edits every 300 ms
    until the response is complete.
  </Step>
</Steps>

## Troubleshooting

The fastest diagnostic for "bot didn't reply in a group" is to tail the
daemon log while you send the test message:

```bash theme={null}
pm2 logs comis --lines 0 | grep -E 'Inbound message|Group message did not activate|Group message ignored|autoreply:activated|Execution complete|Delivery complete'
```

Three possible outcomes tell you which layer is failing:

1. **No `Inbound message` log at all** → Telegram never forwarded the
   message to the bot. This is a Telegram-side filter (privacy mode, bot
   not in group, mention not parsed as an entity). See the first
   accordion below.
2. **`Inbound message` followed by `Group message did not activate
   agent`** → Comis received the message but the activation policy
   suppressed it. The log line includes `isBotMentioned`, `replyToBot`,
   and `activationMode` so you can see exactly why. See the second
   accordion.
3. **`Inbound message` → `autoreply:activated` → `Execution complete`
   → `Delivery complete`** → Working as designed. If the user still
   doesn't see a reply, see the delivery accordion.

<AccordionGroup>
  <Accordion title="No 'Inbound message' log at all (Telegram-side filter)">
    **What happened:** Telegram never sent the message to the bot.
    Most common causes:

    * **Privacy mode is on AND the message wasn't a recognized mention,
      reply, or `/cmd@<botname>`.** With privacy on, Telegram filters
      every other message before it reaches the bot. Typing
      `@<your_bot_username>` as plain text is **not** enough - your
      Telegram client must parse it as a mention entity at send time
      (look for the in-app suggestion popup when you type the `@`).
    * **The bot isn't actually in the group.** Check the member list.
      Re-add it via the group's **Add Members** flow.
    * **The bot was added to the group while privacy mode was on, then
      privacy was disabled.** The flag is cached at join time - kick and
      re-add the bot. See [Disable BotFather privacy mode](#disable-botfather-privacy-mode).

    **Verify privacy state directly:**

    ```bash theme={null}
    TOKEN=$(grep '^TELEGRAM_BOT_TOKEN' ~/.comis/.env | cut -d= -f2- | tr -d '"')
    curl -s "https://api.telegram.org/bot${TOKEN}/getMe" | python3 -m json.tool
    ```

    `"can_read_all_group_messages": false` means privacy is on (the
    BotFather default).

    **Quick test that bypasses privacy mode entirely:** send
    `/start@<your_bot_username>` in the group. `/cmd@<botname>` always
    reaches the bot regardless of privacy. If that fires the agent, your
    code path is fine and the issue was Telegram-side filtering on the
    earlier test.
  </Accordion>

  <Accordion title="Inbound logged, then 'Group message did not activate agent'">
    **What happened:** Comis received the message, but the auto-reply
    gate suppressed it. The diagnostic log spells out why:

    ```
    {"msg":"Group message did not activate agent",
     "isBotMentioned": false, "replyToBot": false,
     "reason":"group-not-mentioned", "activationMode":"mention-gated", ...}
    ```

    Common causes:

    * `activationMode: "mention-gated"` and the message didn't
      `@`-mention the bot. Either type `@<your_bot_username>` properly
      (tap the suggestion) or switch to `groupActivation: "always"`
      (privacy must be off - see the [Groups](#groups) section).
    * The message was an edit. Telegram doesn't always re-emit `mention`
      entities for edits; send a fresh message instead.
    * Your activation policy expects a `custom` regex that didn't match.
      Inspect the log's `reason` field.

    To make every group message activate the agent, set:

    ```yaml theme={null}
    autoReplyEngine:
      groupActivation: always
    ```

    and disable BotFather privacy mode.
  </Accordion>

  <Accordion title="Inbound logged, but sender is blocked by allowFrom">
    **What happened:** A user other than yourself tried to talk to the
    bot, but their Telegram user ID isn't in `channels.telegram.allowFrom`.
    You'll see this log line:

    ```
    {"msg":"Sender blocked by allowFrom filter",
     "senderId":"<their-id>", "errorKind":"auth", ...}
    ```

    **How to fix it:** add their user ID to `allowFrom`, or remove
    `allowFrom` (or set it to `[]`) to allow all senders. `allowFrom`
    only matches sender IDs - putting a group's chat ID there does
    nothing.
  </Accordion>

  <Accordion title="Bot token rejected">
    **What happened:** The token is expired, revoked, or was copied incorrectly.

    **How to fix it:** Open Telegram, send `/token` to **@BotFather**, and select
    your bot to regenerate the token. Update the token in your `~/.comis/.env`
    file and restart the daemon.
  </Accordion>

  <Accordion title="Bot replies in DM but not in groups, even after disabling privacy">
    **What happened:** The privacy flag is per-bot in BotFather, but
    Telegram caches it on the bot's group membership at the time of
    joining. Disabling privacy in BotFather does **not** retroactively
    apply to groups the bot is already in.

    **How to fix it:** kick the bot from each affected group, then
    re-add it. See [Disable BotFather privacy mode](#disable-botfather-privacy-mode)
    for the full procedure plus the API call to verify the flag flipped.
  </Accordion>

  <Accordion title="Messages take a long time to arrive">
    **What happened:** Telegram uses long-polling for bot updates, which can
    occasionally have brief delays.

    **How to fix it:** This is normal Telegram behavior, not a Comis issue. If
    delays exceed several seconds consistently, check your server's network
    connection and firewall rules for outbound HTTPS traffic.
  </Accordion>
</AccordionGroup>

<CardGroup cols={2}>
  <Card title="Delivery Infrastructure" icon="truck-fast" href="/channels/delivery">
    How streaming, typing indicators, and retry logic work under the hood.
  </Card>

  <Card title="All Channels" icon="message-dots" href="/channels">
    Compare all 10 supported platforms side by side.
  </Card>

  <Card title="Agent Configuration" icon="robot" href="/agents">
    Set up your agent's personality, tools, and behavior.
  </Card>

  <Card title="Secret Management" icon="key" href="/security/secrets">
    Learn how to manage API keys and tokens securely.
  </Card>
</CardGroup>
