Mainstream messaging

Telegram

Готово к production для личных сообщений бота и групп через grammY. Режим длинного опроса используется по умолчанию; режим Webhook необязателен.

Быстрая настройка

  • Create the bot token in BotFather

    Откройте Telegram и начните чат с @BotFather (убедитесь, что имя точно @BotFather).

    Выполните /newbot, следуйте подсказкам и сохраните токен.

  • Configure token and DM policy

    json5
    {channels: {telegram: {  enabled: true,  botToken: "123:abc",  dmPolicy: "pairing",  groups: { "*": { requireMention: true } },},},}

    Резервный вариант через окружение: TELEGRAM_BOT_TOKEN=... (только учетная запись по умолчанию). Telegram не использует openclaw channels login telegram; настройте токен в конфигурации/окружении, затем запустите Gateway.

  • Start gateway and approve first DM

    bash
    openclaw gatewayopenclaw pairing list telegramopenclaw pairing approve telegram <CODE>

    Коды сопряжения истекают через 1 час.

  • Add the bot to a group

    Добавьте бота в свою группу, затем получите оба ID, которые нужны для доступа к группе:

    • ваш ID пользователя Telegram, используемый в allowFrom / groupAllowFrom
    • ID группового чата Telegram, используемый как ключ в channels.telegram.groups

    При первой настройке получите ID группового чата из openclaw logs --follow, бота для пересланных ID или Bot API getUpdates. После разрешения группы /whoami@<bot_username> может подтвердить ID пользователя и группы.

    Отрицательные ID супергрупп Telegram, начинающиеся с -100, являются ID групповых чатов. Помещайте их в channels.telegram.groups, а не в groupAllowFrom.

  • Настройки на стороне Telegram

    Privacy mode and group visibility

    Боты Telegram по умолчанию используют режим приватности, который ограничивает, какие групповые сообщения они получают.

    Если бот должен видеть все групповые сообщения, либо:

    • отключите режим приватности через /setprivacy, либо
    • сделайте бота администратором группы.

    При переключении режима приватности удалите и заново добавьте бота в каждую группу, чтобы Telegram применил изменение.

    Group permissions

    Статус администратора управляется в настройках группы Telegram.

    Боты-администраторы получают все групповые сообщения, что полезно для постоянно включенного поведения в группе.

    Helpful BotFather toggles
    • /setjoingroups для разрешения/запрета добавления в группы
    • /setprivacy для поведения видимости в группах

    Контроль доступа и активация

    Идентичность группового бота

    В группах и темах форумов Telegram явное упоминание настроенного имени бота (например, @my_bot) считается обращением к выбранному агенту OpenClaw, даже если имя персоны агента отличается от имени пользователя Telegram. Политика молчания в группе все равно применяется к нерелевантному групповому трафику, но само имя бота не считается «кем-то другим».

    DM policy

    channels.telegram.dmPolicy управляет доступом к личным сообщениям:

    • pairing (по умолчанию)
    • allowlist (требует хотя бы один ID отправителя в allowFrom)
    • open (требует, чтобы allowFrom включал "*")
    • disabled

    dmPolicy: "open" с allowFrom: ["*"] позволяет любой учетной записи Telegram, которая найдет или угадает имя пользователя бота, отдавать ему команды. Используйте это только для намеренно публичных ботов с жестко ограниченными инструментами; боты с одним владельцем должны использовать allowlist с числовыми ID пользователей.

    channels.telegram.allowFrom принимает числовые ID пользователей Telegram. Префиксы telegram: / tg: принимаются и нормализуются. В конфигурациях с несколькими учетными записями ограничительный верхнеуровневый channels.telegram.allowFrom считается границей безопасности: записи уровня учетной записи allowFrom: ["*"] не делают эту учетную запись публичной, если эффективный список разрешенных учетной записи после объединения все еще не содержит явный wildcard. dmPolicy: "allowlist" с пустым allowFrom блокирует все личные сообщения и отклоняется проверкой конфигурации. Настройка запрашивает только числовые ID пользователей. Если вы обновились и ваша конфигурация содержит записи списка разрешенных @username, выполните openclaw doctor --fix, чтобы разрешить их (по мере возможности; требуется токен бота Telegram). Если раньше вы полагались на файлы списка разрешенных из хранилища сопряжений, openclaw doctor --fix может восстановить записи в channels.telegram.allowFrom в потоках со списком разрешенных (например, когда dmPolicy: "allowlist" еще не имеет явных ID).

    Для ботов с одним владельцем предпочитайте dmPolicy: "allowlist" с явными числовыми ID allowFrom, чтобы политика доступа была надежно закреплена в конфигурации (вместо зависимости от предыдущих одобрений сопряжения).

    Частая путаница: одобрение сопряжения в личных сообщениях не означает «этот отправитель авторизован везде». Сопряжение предоставляет доступ к личным сообщениям. Если владельца команд еще нет, первое одобренное сопряжение также задает commands.ownerAllowFrom, чтобы команды только для владельца и одобрения exec имели явную учетную запись оператора. Авторизация отправителей в группах по-прежнему берется из явных списков разрешенных в конфигурации. Если вы хотите «я авторизован один раз, и работают и личные сообщения, и групповые команды», поместите свой числовой ID пользователя Telegram в channels.telegram.allowFrom; для команд только для владельца убедитесь, что commands.ownerAllowFrom содержит telegram:<your user id>.

    Поиск вашего ID пользователя Telegram

    Безопаснее (без стороннего бота):

    1. Напишите своему боту в личные сообщения.
    2. Выполните openclaw logs --follow.
    3. Прочитайте from.id.

    Официальный метод Bot API:

    bash
    curl "https://api.telegram.org/bot<bot_token>/getUpdates"

    Сторонний метод (менее приватный): @userinfobot или @getidsbot.

    Group policy and allowlists

    Два элемента управления применяются вместе:

    1. Какие группы разрешены (channels.telegram.groups)

      • нет конфигурации groups:
        • с groupPolicy: "open": любая группа может пройти проверки ID группы
        • с groupPolicy: "allowlist" (по умолчанию): группы блокируются, пока вы не добавите записи groups (или "*")
      • groups настроен: работает как список разрешенных (явные ID или "*")
    2. Какие отправители разрешены в группах (channels.telegram.groupPolicy)

      • open
      • allowlist (по умолчанию)
      • disabled

    groupAllowFrom используется для фильтрации отправителей в группах. Если он не задан, Telegram возвращается к allowFrom. Записи groupAllowFrom должны быть числовыми ID пользователей Telegram (префиксы telegram: / tg: нормализуются). Не помещайте ID групповых чатов или супергрупп Telegram в groupAllowFrom. Отрицательные ID чатов должны находиться в channels.telegram.groups. Нечисловые записи игнорируются при авторизации отправителей. Граница безопасности (2026.2.25+): авторизация отправителей в группах не наследует одобрения из хранилища сопряжений личных сообщений. Сопряжение остается только для личных сообщений. Для групп задайте groupAllowFrom или allowFrom на уровне группы/темы. Если groupAllowFrom не задан, Telegram возвращается к конфигурационному allowFrom, а не к хранилищу сопряжений. Практичный шаблон для ботов с одним владельцем: укажите свой ID пользователя в channels.telegram.allowFrom, оставьте groupAllowFrom незаданным и разрешите целевые группы в channels.telegram.groups. Примечание о runtime: если channels.telegram полностью отсутствует, runtime по умолчанию закрывается отказом с groupPolicy="allowlist", если channels.defaults.groupPolicy не задан явно.

    Настройка группы только для владельца:

    json5
    {channels: {telegram: {  enabled: true,  dmPolicy: "pairing",  allowFrom: ["&lt;YOUR_TELEGRAM_USER_ID&gt;"],  groupPolicy: "allowlist",  groups: {    "&lt;GROUP_CHAT_ID&gt;": {      requireMention: true,    },  },},},}

    Проверьте это из группы с @<bot_username> ping. Обычные групповые сообщения не запускают бота, пока requireMention: true.

    Пример: разрешить любого участника в одной конкретной группе:

    json5
    {channels: {telegram: {  groups: {    "-1001234567890": {      groupPolicy: "open",      requireMention: false,    },  },},},}

    Пример: разрешить только определенных пользователей внутри одной конкретной группы:

    json5
    {channels: {telegram: {  groups: {    "-1001234567890": {      requireMention: true,      allowFrom: ["8734062810", "745123456"],    },  },},},}

    Mention behavior

    Ответы в группах по умолчанию требуют упоминания.

    Упоминание может поступать из:

    • нативного упоминания @botusername, или
    • шаблонов упоминаний в:
      • agents.list[].groupChat.mentionPatterns
      • messages.groupChat.mentionPatterns

    Переключатели команд на уровне сессии:

    • /activation always
    • /activation mention

    Они обновляют только состояние сессии. Для постоянного поведения используйте конфигурацию.

    Пример постоянной конфигурации:

    json5
    {channels: {telegram: {  groups: {    "*": { requireMention: false },  },},},}

    Контекст истории группы всегда включен для групп и ограничен historyLimit. Задайте channels.telegram.historyLimit: 0, чтобы отключить окно истории группы Telegram. Устаревший ключ includeGroupHistoryContext удаляется командой openclaw doctor --fix.

    Получение ID группового чата:

    • переслать групповое сообщение в @userinfobot / @getidsbot
    • или прочитать chat.id из openclaw logs --follow
    • или просмотреть Bot API getUpdates
    • после разрешения группы выполнить /whoami@<bot_username>, если нативные команды включены

    Поведение runtime

    • Telegram принадлежит процессу Gateway.
    • Маршрутизация детерминирована: входящие ответы Telegram возвращаются в Telegram (модель не выбирает каналы).
    • Входящие сообщения нормализуются в общий конверт канала с метаданными ответа, заполнителями медиа и сохраненным контекстом цепочки ответов для ответов Telegram, которые наблюдал Gateway.
    • Групповые сеансы изолируются по ID группы. Темы форума добавляют :topic:<threadId>, чтобы изолировать темы.
    • Сообщения DM могут содержать message_thread_id; OpenClaw сохраняет его для ответов. Сеансы тем DM разделяются только когда Telegram getMe сообщает has_topics_enabled: true для бота; иначе DM остаются в плоском сеансе.
    • Долгий polling использует grammY runner с последовательной обработкой по чату/потоку. Общая конкуррентность runner sink использует agents.defaults.maxConcurrent.
    • Запуск нескольких аккаунтов ограничивает параллельные пробы Telegram getMe, чтобы большие парки ботов не запускали пробы всех аккаунтов одновременно.
    • Долгий polling защищен внутри каждого процесса Gateway, поэтому только один активный poller может использовать токен бота одновременно. Если вы все еще видите конфликты getUpdates 409, вероятно, другой Gateway OpenClaw, скрипт или внешний poller использует тот же токен.
    • Перезапуски watchdog для long-polling по умолчанию срабатывают после 120 секунд без завершенного сигнала работоспособности getUpdates. Увеличивайте channels.telegram.pollingStallThresholdMs только если ваше развертывание все еще видит ложные перезапуски из-за остановки polling во время длительной работы. Значение задается в миллисекундах и допускается от 30000 до 600000; поддерживаются переопределения для отдельных аккаунтов.
    • Telegram Bot API не поддерживает отметки о прочтении (sendReadReceipts не применяется).

    Справочник функций

    Предпросмотр live stream (правки сообщений)

    OpenClaw может транслировать частичные ответы в реальном времени:

    • прямые чаты: сообщение предпросмотра + editMessageText
    • группы/темы: сообщение предпросмотра + editMessageText

    Требование:

    • channels.telegram.streamingoff | partial | block | progress (по умолчанию: partial)
    • короткие начальные предпросмотры ответа подавляются debounce, затем материализуются после ограниченной задержки, если запуск все еще активен
    • progress сохраняет один редактируемый черновик статуса для хода выполнения инструментов, показывает стабильную метку статуса, когда активность ответа приходит до хода выполнения инструментов, очищает его при завершении и отправляет финальный ответ как обычное сообщение
    • streaming.preview.toolProgress управляет тем, используют ли обновления инструментов/прогресса то же редактируемое сообщение предпросмотра (по умолчанию: true, когда активна потоковая передача предпросмотра)
    • streaming.preview.commandText управляет деталями command/exec внутри этих строк прогресса инструмента: raw (по умолчанию, сохраняет поведение выпущенной версии) или status (только метка инструмента)
    • streaming.progress.commentary (по умолчанию: false) включает текст комментария/преамбулы ассистента во временном черновике прогресса
    • устаревшие channels.telegram.streamMode, булевы значения streaming и выведенные из использования ключи нативного черновика предпросмотра обнаруживаются; запустите openclaw doctor --fix, чтобы перенести их в текущую конфигурацию потоковой передачи

    Обновления предпросмотра прогресса инструмента — это короткие строки статуса, показываемые во время выполнения инструментов, например выполнение команд, чтение файлов, обновления планирования, сводки патчей или текст преамбулы/комментариев Codex в режиме Codex app-server. Telegram оставляет их включенными по умолчанию, чтобы соответствовать поведению OpenClaw, выпущенному в v2026.4.22 и позже.

    Чтобы оставить редактируемый предпросмотр для текста ответа, но скрыть строки прогресса инструмента, задайте:

    json
    {  "channels": {    "telegram": {      "streaming": {        "mode": "partial",        "preview": {          "toolProgress": false        }      }    }  }}

    Чтобы оставить прогресс инструмента видимым, но скрыть текст command/exec, задайте:

    json
    {  "channels": {    "telegram": {      "streaming": {        "mode": "partial",        "preview": {          "commandText": "status"        }      }    }  }}

    Используйте режим progress, когда хотите видеть прогресс инструмента без редактирования финального ответа в то же сообщение. Поместите политику текста команд в streaming.progress:

    json
    {  "channels": {    "telegram": {      "streaming": {        "mode": "progress",        "progress": {          "toolProgress": true,          "commandText": "status"        }      }    }  }}

    Используйте streaming.mode: "off" только когда нужна доставка только финального ответа: правки предпросмотра Telegram отключаются, а общая болтовня инструментов/прогресса подавляется вместо отправки отдельными сообщениями статуса. Запросы подтверждения, медиа-пayload и ошибки все равно проходят через обычную финальную доставку. Используйте streaming.preview.toolProgress: false, когда нужно сохранить только правки предпросмотра ответа, скрыв строки статуса прогресса инструмента.

    Для текстовых ответов:

    • короткие предпросмотры DM/группы/темы: OpenClaw сохраняет то же сообщение предпросмотра и выполняет финальную правку на месте
    • длинные финальные тексты, разбиваемые на несколько сообщений Telegram, по возможности повторно используют существующий предпросмотр как первый финальный фрагмент, затем отправляют только оставшиеся фрагменты
    • финальные ответы в режиме progress очищают черновик статуса и используют обычную финальную доставку вместо редактирования черновика в ответ
    • если финальная правка завершается ошибкой до подтверждения завершенного текста, OpenClaw использует обычную финальную доставку и очищает устаревший предпросмотр

    Для сложных ответов (например, медиа-payload) OpenClaw откатывается к обычной финальной доставке, а затем очищает сообщение предпросмотра.

    Потоковая передача предпросмотра отделена от блочной потоковой передачи. Когда блочная потоковая передача явно включена для Telegram, OpenClaw пропускает поток предпросмотра, чтобы избежать двойной потоковой передачи.

    Поведение потока рассуждений:

    • /reasoning stream использует путь предпросмотра рассуждений поддерживаемого канала; в Telegram он транслирует рассуждения в live-предпросмотр во время генерации
    • предпросмотр рассуждений удаляется после финальной доставки; используйте /reasoning on, когда рассуждения должны оставаться видимыми
    • финальный ответ отправляется без текста рассуждений
    Расширенное форматирование сообщений

    Исходящий текст по умолчанию использует стандартные HTML-сообщения Telegram, чтобы ответы оставались читаемыми в актуальных клиентах Telegram. Этот режим совместимости поддерживает обычный жирный шрифт, курсив, ссылки, код, спойлеры и цитаты, но не rich-only блоки Bot API 10.1, такие как нативные таблицы, подробности, расширенные медиа и формулы.

    Задайте channels.telegram.richMessages: true, чтобы включить расширенные сообщения Bot API 10.1:

    json5
    {channels: {telegram: {  richMessages: true,},},}

    Когда включено:

    • Агенту сообщается, что расширенные сообщения Telegram доступны для этого бота/аккаунта.
    • Текст Markdown рендерится через Markdown IR OpenClaw и отправляется как расширенный HTML Telegram.
    • Явные расширенные HTML-payload сохраняют поддерживаемые теги Bot API 10.1, такие как заголовки, таблицы, подробности, расширенные медиа и формулы.
    • Подписи к медиа все еще используют HTML-подписи Telegram, потому что расширенные сообщения не заменяют подписи.

    Это удерживает текст модели от сигилов Telegram Rich Markdown, поэтому суммы вроде $400-600K не разбираются как математика. Длинный расширенный текст автоматически разделяется с учетом лимитов Telegram на расширенный текст и расширенные блоки. Таблицы, превышающие лимит Telegram по столбцам, отправляются как блоки кода.

    По умолчанию: выключено для совместимости клиентов. Расширенные сообщения требуют совместимых клиентов Telegram; некоторые актуальные клиенты Desktop, Web, Android и сторонние клиенты отображают принятые расширенные сообщения как неподдерживаемые. Оставляйте эту опцию отключенной, если каждый клиент, используемый с ботом, не может их отобразить. /status показывает, включены или выключены расширенные сообщения для текущего сеанса Telegram.

    Предпросмотры ссылок включены по умолчанию. channels.telegram.linkPreview: false пропускает автоматическое обнаружение сущностей для расширенного текста.

    Нативные команды и пользовательские команды

    Регистрация меню команд Telegram выполняется при запуске с помощью setMyCommands.

    Значения нативных команд по умолчанию:

    • commands.native: "auto" включает нативные команды для Telegram

    Добавьте пользовательские пункты меню команд:

    json5
    {channels: {telegram: {  customCommands: [    { command: "backup", description: "Git backup" },    { command: "generate", description: "Create an image" },  ],},},}

    Правила:

    • имена нормализуются (удаляется начальный /, приводятся к нижнему регистру)
    • допустимый шаблон: a-z, 0-9, _, длина 1..32
    • пользовательские команды не могут переопределять нативные команды
    • конфликты/дубликаты пропускаются и логируются

    Примечания:

    • пользовательские команды — это только пункты меню; они не реализуют поведение автоматически
    • команды plugin/skill все еще могут работать при вводе, даже если они не показаны в меню Telegram

    Если нативные команды отключены, встроенные удаляются. Пользовательские команды/plugin могут по-прежнему регистрироваться, если настроены.

    Распространенные ошибки настройки:

    • setMyCommands failed с BOT_COMMANDS_TOO_MUCH означает, что меню Telegram все еще переполнилось после обрезки; сократите команды plugin/skill/пользовательские команды или отключите channels.telegram.commands.native.
    • Сбой deleteWebhook, deleteMyCommands или setMyCommands с 404: Not Found, когда прямые команды curl к Bot API работают, может означать, что channels.telegram.apiRoot был задан как полный endpoint /bot&lt;TOKEN&gt;. apiRoot должен быть только корнем Bot API, а openclaw doctor --fix удаляет случайный хвостовой /bot&lt;TOKEN&gt;.
    • getMe returned 401 означает, что Telegram отклонил настроенный токен бота. Обновите botToken, tokenFile или TELEGRAM_BOT_TOKEN текущим токеном BotFather; OpenClaw останавливается до polling, поэтому это не сообщается как ошибка очистки webhook.
    • setMyCommands failed с сетевыми/fetch-ошибками обычно означает, что исходящие DNS/HTTPS к api.telegram.org заблокированы.

    Команды сопряжения устройств (plugin device-pair)

    Когда plugin device-pair установлен:

    1. /pair генерирует код настройки
    2. вставьте код в приложение iOS
    3. /pair pending перечисляет ожидающие запросы (включая роль/области доступа)
    4. подтвердите запрос:
      • /pair approve <requestId> для явного подтверждения
      • /pair approve, когда есть только один ожидающий запрос
      • /pair approve latest для самого последнего

    Код настройки содержит короткоживущий bootstrap-токен. Встроенный bootstrap кода настройки возвращает долговечный токен узла с scopes: [] плюс ограниченный токен передачи управления оператору для доверенного мобильного онбординга. Этот токен оператора может читать нативную конфигурацию во время настройки, но не предоставляет области доступа для мутации сопряжения или operator.admin.

    Если устройство повторяет попытку с измененными данными аутентификации (например, ролью/областями доступа/публичным ключом), предыдущий ожидающий запрос заменяется, а новый запрос использует другой requestId. Повторно выполните /pair pending перед подтверждением.

    Подробнее: Сопряжение.

    Inline buttons

    Настройте область действия встроенной клавиатуры:

    json5
    {channels: {telegram: {  capabilities: {    inlineButtons: "allowlist",  },},},}

    Переопределение для отдельной учетной записи:

    json5
    {channels: {telegram: {  accounts: {    main: {      capabilities: {        inlineButtons: "allowlist",      },    },  },},},}

    Области действия:

    • off
    • dm
    • group
    • all
    • allowlist (по умолчанию)

    Устаревшее capabilities: ["inlineButtons"] сопоставляется с inlineButtons: "all".

    Пример действия сообщения:

    json5
    {action: "send",channel: "telegram",to: "123456789",message: "Choose an option:",buttons: [[  { text: "Yes", callback_data: "yes" },  { text: "No", callback_data: "no" },],[{ text: "Cancel", callback_data: "cancel" }],],}

    Пример кнопки Mini App:

    json5
    {action: "send",channel: "telegram",to: "123456789",message: "Open app:",presentation: {blocks: [  {    type: "buttons",    buttons: [{ label: "Launch", web_app: { url: "https://example.com/app" } }],  },],},}

    Кнопки Telegram web_app работают только в приватных чатах между пользователем и ботом.

    Нажатия callback, которые не обрабатываются зарегистрированным интерактивным обработчиком Plugin, передаются агенту как текст: callback_data: <value>

    Telegram message actions for agents and automation

    Действия инструмента Telegram включают:

    • sendMessage (to, content, необязательные mediaUrl, replyToMessageId, messageThreadId)
    • react (chatId, messageId, emoji)
    • deleteMessage (chatId, messageId)
    • editMessage (chatId, messageId, content или caption, необязательные встроенные кнопки presentation; правки только кнопок обновляют разметку ответа)
    • createForumTopic (chatId, name, необязательные iconColor, iconCustomEmojiId)

    Действия сообщений канала предоставляют удобные псевдонимы (send, react, delete, edit, sticker, sticker-search, topic-create).

    Элементы управления доступом:

    • channels.telegram.actions.sendMessage
    • channels.telegram.actions.deleteMessage
    • channels.telegram.actions.reactions
    • channels.telegram.actions.sticker (по умолчанию: отключено)

    Примечание: edit и topic-create сейчас включены по умолчанию и не имеют отдельных переключателей channels.telegram.actions.*. Отправки во время выполнения используют активный снимок конфигурации/секретов (запуск/перезагрузка), поэтому пути действий не выполняют специальное повторное разрешение SecretRef при каждой отправке.

    Семантика удаления реакций: /tools/reactions

    Reply threading tags

    Telegram поддерживает явные теги цепочек ответов в сгенерированном выводе:

    • [[reply_to_current]] отвечает на вызвавшее сообщение
    • [[reply_to:<id>]] отвечает на конкретный ID сообщения Telegram

    channels.telegram.replyToMode управляет обработкой:

    • off (по умолчанию)
    • first
    • all

    Когда цепочки ответов включены и исходный текст или подпись Telegram доступны, OpenClaw автоматически включает фрагмент нативной цитаты Telegram. Telegram ограничивает текст нативной цитаты 1024 кодовыми единицами UTF-16, поэтому более длинные сообщения цитируются с начала и откатываются к обычному ответу, если Telegram отклоняет цитату.

    Примечание: off отключает неявные цепочки ответов. Явные теги [[reply_to_*]] все равно учитываются.

    Forum topics and thread behavior

    Форумные супергруппы:

    • ключи сессий тем добавляют :topic:<threadId>
    • ответы и индикатор набора направляются в цепочку темы
    • путь конфигурации темы: channels.telegram.groups.<chatId>.topics.<threadId>

    Особый случай общей темы (threadId=1):

    • отправки сообщений опускают message_thread_id (Telegram отклоняет sendMessage(...thread_id=1))
    • действия набора текста все еще включают message_thread_id

    Наследование тем: записи тем наследуют настройки группы, если они не переопределены (requireMention, allowFrom, skills, systemPrompt, enabled, groupPolicy). agentId относится только к теме и не наследуется из настроек группы по умолчанию. topics."*" задает значения по умолчанию для каждой темы в этой группе; точные ID тем все равно имеют приоритет над "*".

    Маршрутизация агентов по темам: каждая тема может маршрутизироваться к другому агенту через настройку agentId в конфигурации темы. Это дает каждой теме собственное изолированное рабочее пространство, память и сессию. Пример:

    json5
    {  channels: {    telegram: {      groups: {        "-1001234567890": {          topics: {            "1": { agentId: "main" },      // General topic → main agent            "3": { agentId: "zu" },        // Dev topic → zu agent            "5": { agentId: "coder" }      // Code review → coder agent          }        }      }    }  }}

    Затем у каждой темы есть собственный ключ сессии: agent:zu:telegram:group:-1001234567890:topic:3

    Постоянная привязка тем ACP: форумные темы могут закреплять сессии ACP harness через типизированные привязки ACP верхнего уровня (bindings[] с type: "acp" и match.channel: "telegram", peer.kind: "group" и квалифицированным по теме ID, например -1001234567890:topic:42). Сейчас область действия ограничена форумными темами в группах/супергруппах. См. Агенты ACP.

    Запуск ACP, привязанный к цепочке, из чата: /acp spawn <agent> --thread here|auto привязывает текущую тему к новой сессии ACP; последующие сообщения маршрутизируются туда напрямую. OpenClaw закрепляет подтверждение запуска внутри темы. Требуется, чтобы channels.telegram.threadBindings.spawnSessions оставался включенным (по умолчанию: true).

    Контекст шаблона предоставляет MessageThreadId и IsForum. DM-чаты с message_thread_id сохраняют метаданные ответа; они используют ключи сессий с учетом цепочек только тогда, когда Telegram getMe сообщает has_topics_enabled: true для бота. Прежние переопределения dm.threadReplies и direct.*.threadReplies намеренно выведены из использования; используйте режим цепочек BotFather как единственный источник истины и выполните openclaw doctor --fix, чтобы удалить устаревшие ключи конфигурации.

    Audio, video, and stickers

    Аудиосообщения

    Telegram различает голосовые заметки и аудиофайлы.

    • по умолчанию: поведение аудиофайла
    • тег [[audio_as_voice]] в ответе агента принудительно отправляет голосовую заметку
    • входящие транскрипты голосовых заметок оформляются в контексте агента как машинно сгенерированный, недоверенный текст; обнаружение упоминаний все равно использует необработанный транскрипт, поэтому голосовые сообщения с доступом по упоминанию продолжают работать.

    Пример действия сообщения:

    json5
    {action: "send",channel: "telegram",to: "123456789",media: "https://example.com/voice.ogg",asVoice: true,}

    Видеосообщения

    Telegram различает видеофайлы и видеозаметки.

    Пример действия сообщения:

    json5
    {action: "send",channel: "telegram",to: "123456789",media: "https://example.com/video.mp4",asVideoNote: true,}

    Видеозаметки не поддерживают подписи; предоставленный текст сообщения отправляется отдельно.

    Стикеры

    Обработка входящих стикеров:

    • статический WEBP: скачивается и обрабатывается (заполнитель <media:sticker>)
    • анимированный TGS: пропускается
    • видео WEBM: пропускается

    Поля контекста стикера:

    • Sticker.emoji
    • Sticker.setName
    • Sticker.fileId
    • Sticker.fileUniqueId
    • Sticker.cachedDescription

    Описания стикеров кэшируются в состоянии Plugin SQLite OpenClaw, чтобы сократить повторные вызовы vision.

    Включение действий со стикерами:

    json5
    {channels: {telegram: {  actions: {    sticker: true,  },},},}

    Действие отправки стикера:

    json5
    {action: "sticker",channel: "telegram",to: "123456789",fileId: "CAACAgIAAxkBAAI...",}

    Поиск кэшированных стикеров:

    json5
    {action: "sticker-search",channel: "telegram",query: "cat waving",limit: 5,}
    Уведомления о реакциях

    Реакции Telegram поступают как обновления message_reaction (отдельно от полезной нагрузки сообщений).

    Когда включено, OpenClaw ставит в очередь системные события вроде:

    • Telegram reaction added: 👍 by Alice (@alice) on msg 42

    Конфигурация:

    • channels.telegram.reactionNotifications: off | own | all (по умолчанию: own)
    • channels.telegram.reactionLevel: off | ack | minimal | extensive (по умолчанию: minimal)

    Примечания:

    • own означает только реакции пользователей на сообщения, отправленные ботом (по возможности через кэш отправленных сообщений).
    • События реакций по-прежнему соблюдают средства контроля доступа Telegram (dmPolicy, allowFrom, groupPolicy, groupAllowFrom); неавторизованные отправители отбрасываются.
    • Telegram не предоставляет ID тредов в обновлениях реакций.
      • группы без форума маршрутизируются в сессию группового чата
      • форумные группы маршрутизируются в сессию общей темы группы (:topic:1), а не в точную исходную тему

    allowed_updates для polling/webhook автоматически включает message_reaction.

    Ack-реакции

    ackReaction отправляет emoji подтверждения, пока OpenClaw обрабатывает входящее сообщение. ackReactionScope определяет, когда этот emoji фактически отправляется.

    Порядок разрешения emoji (ackReaction):

    • channels.telegram.accounts.<accountId>.ackReaction
    • channels.telegram.ackReaction
    • messages.ackReaction
    • резервный emoji идентичности агента (agents.list[].identity.emoji, иначе "👀")

    Примечания:

    • Telegram ожидает unicode emoji (например, "👀").
    • Используйте "", чтобы отключить реакцию для канала или аккаунта.

    Область действия (messages.ackReactionScope):

    Провайдер Telegram читает область действия из messages.ackReactionScope (по умолчанию "group-mentions"). На сегодня переопределения на уровне аккаунта Telegram или канала Telegram нет.

    Значения: "all" (личные сообщения + группы), "direct" (только личные сообщения), "group-all" (каждое сообщение в группе, без личных сообщений), "group-mentions" (группы, когда бот упомянут; без личных сообщений — это значение по умолчанию), "off" / "none" (отключено).

    Записи конфигурации из событий и команд Telegram

    Записи конфигурации канала включены по умолчанию (configWrites !== false).

    Записи, запускаемые Telegram, включают:

    • события миграции группы (migrate_to_chat_id) для обновления channels.telegram.groups
    • /config set и /config unset (требуется включение команд)

    Отключение:

    json5
    {channels: {telegram: {  configWrites: false,},},}
    Long polling и webhook

    По умолчанию используется long polling. Для режима webhook задайте channels.telegram.webhookUrl и channels.telegram.webhookSecret; необязательные webhookPath, webhookHost, webhookPort (по умолчанию /telegram-webhook, 127.0.0.1, 8787).

    В режиме long polling OpenClaw сохраняет свой watermark перезапуска только после успешной отправки обновления. Если обработчик завершается ошибкой, это обновление остается доступным для повтора в том же процессе и не записывается как завершенное для дедупликации при перезапуске.

    Локальный слушатель привязывается к 127.0.0.1:8787. Для публичного входящего трафика либо поместите reverse proxy перед локальным портом, либо намеренно задайте webhookHost: "0.0.0.0".

    Режим Webhook проверяет request guards, секретный токен Telegram и тело JSON перед возвратом 200 в Telegram. Затем OpenClaw обрабатывает обновление асинхронно через те же bot lanes для каждого чата/темы, которые используются long polling, поэтому медленные ходы агента не удерживают delivery ACK Telegram.

    Лимиты, повторные попытки и цели CLI
    • Значение channels.telegram.textChunkLimit по умолчанию — 4000.
    • channels.telegram.chunkMode="newline" предпочитает границы абзацев (пустые строки) перед разделением по длине.
    • channels.telegram.mediaMaxMb (по умолчанию 100) ограничивает размер входящих и исходящих медиа Telegram.
    • channels.telegram.mediaGroupFlushMs (по умолчанию 500) управляет тем, как долго альбомы/медиагруппы Telegram буферизуются перед тем, как OpenClaw отправит их как одно входящее сообщение. Увеличьте значение, если части альбома приходят с задержкой; уменьшите его, чтобы снизить задержку ответа на альбом.
    • channels.telegram.timeoutSeconds переопределяет тайм-аут клиента Telegram API (если не задано, применяется значение grammY по умолчанию). Клиенты бота ограничивают настроенные значения ниже 60-секундного ограничения исходящих запросов текста/индикатора ввода, чтобы grammY не прервал доставку видимого ответа до того, как смогут сработать транспортное ограничение и fallback OpenClaw. Long polling по-прежнему использует 45-секундное ограничение запроса getUpdates, чтобы простаивающие опросы не оставались брошенными бессрочно.
    • channels.telegram.pollingStallThresholdMs по умолчанию равно 120000; настраивайте в диапазоне от 30000 до 600000 только при ложноположительных перезапусках из-за зависания polling.
    • история контекста группы использует channels.telegram.historyLimit или messages.groupChat.historyLimit (по умолчанию 50); 0 отключает.
    • дополнительный контекст ответа/цитаты/пересылки нормализуется в одно выбранное окно контекста беседы, когда Gateway наблюдал родительские сообщения; кэш наблюдаемых сообщений хранится в состоянии Plugin в SQLite OpenClaw, а openclaw doctor --fix импортирует устаревшие sidecar-файлы. Telegram включает в обновления только один неглубокий reply_to_message, поэтому цепочки старше кэша ограничены текущей полезной нагрузкой обновления Telegram.
    • allowlist Telegram в первую очередь ограничивают, кто может запускать агента, а не являются полноценной границей редактирования дополнительного контекста.
    • элементы управления историей личных сообщений:
      • channels.telegram.dmHistoryLimit
      • channels.telegram.dms["<user_id>"].historyLimit
    • конфигурация channels.telegram.retry применяется к помощникам отправки Telegram (CLI/инструменты/действия) для восстанавливаемых исходящих ошибок API. Доставка финального входящего ответа также использует ограниченную безопасную повторную отправку при сбоях Telegram до подключения, но не повторяет неоднозначные сетевые оболочки после отправки, которые могут продублировать видимые сообщения.

    Цели отправки CLI и message-tool могут быть числовым ID чата, именем пользователя или целью темы форума:

    bash
    openclaw message send --channel telegram --target 123456789 --message "hi"openclaw message send --channel telegram --target @name --message "hi"openclaw message send --channel telegram --target -1001234567890:topic:42 --message "hi topic"

    Опросы Telegram используют openclaw message poll и поддерживают темы форума:

    bash
    openclaw message poll --channel telegram --target 123456789 \--poll-question "Ship it?" --poll-option "Yes" --poll-option "No"openclaw message poll --channel telegram --target -1001234567890:topic:42 \--poll-question "Pick a time" --poll-option "10am" --poll-option "2pm" \--poll-duration-seconds 300 --poll-public

    Флаги опросов только для Telegram:

    • --poll-duration-seconds (5-600)
    • --poll-anonymous
    • --poll-public
    • --thread-id для тем форума (или используйте цель :topic:)

    Отправка Telegram также поддерживает:

    • --presentation с блоками buttons для встроенных клавиатур, когда это разрешает channels.telegram.capabilities.inlineButtons
    • --pin или --delivery '{"pin":true}', чтобы запросить закрепленную доставку, когда бот может закреплять сообщения в этом чате
    • --force-document, чтобы отправлять исходящие изображения, GIF и видео как документы вместо сжатых фото, анимированных медиа или видео-загрузок

    Ограничение действий:

    • channels.telegram.actions.sendMessage=false отключает исходящие сообщения Telegram, включая опросы
    • channels.telegram.actions.poll=false отключает создание опросов Telegram, оставляя обычные отправки включенными
    Подтверждения exec в Telegram

    Telegram поддерживает подтверждения exec в личных сообщениях утверждающих и может дополнительно публиковать запросы в исходном чате или теме. Утверждающие должны быть числовыми ID пользователей Telegram.

    Путь конфигурации:

    • channels.telegram.execApprovals.enabled (автоматически включается, когда можно разрешить хотя бы одного утверждающего)
    • channels.telegram.execApprovals.approvers (использует числовые ID владельцев из commands.ownerAllowFrom как fallback)
    • channels.telegram.execApprovals.target: dm (по умолчанию) | channel | both
    • agentFilter, sessionFilter

    channels.telegram.allowFrom, groupAllowFrom и defaultTo управляют тем, кто может общаться с ботом и куда он отправляет обычные ответы. Они не делают кого-либо утверждающим exec. Первое одобренное сопряжение через личные сообщения начально заполняет commands.ownerAllowFrom, когда владелец команд еще не существует, поэтому настройка с одним владельцем по-прежнему работает без дублирования ID в execApprovals.approvers.

    Доставка в канал показывает текст команды в чате; включайте channel или both только в доверенных группах/темах. Когда запрос попадает в тему форума, OpenClaw сохраняет тему для запроса подтверждения и последующего сообщения. Подтверждения exec по умолчанию истекают через 30 минут.

    Кнопки встроенного подтверждения также требуют, чтобы channels.telegram.capabilities.inlineButtons разрешал целевую поверхность (dm, group или all). ID подтверждений с префиксом plugin: разрешаются через подтверждения Plugin; остальные сначала разрешаются через подтверждения exec.

    См. Подтверждения exec.

    Управление ответами об ошибках

    Когда агент сталкивается с ошибкой доставки или провайдера, политика ошибок управляет тем, отправляются ли сообщения об ошибках в чат Telegram:

    Ключ Значения По умолчанию Описание
    channels.telegram.errorPolicy always, once, silent always always — отправлять каждое сообщение об ошибке в чат. once — отправлять каждое уникальное сообщение об ошибке один раз за окно cooldown (подавлять повторяющиеся одинаковые ошибки). silent — никогда не отправлять сообщения об ошибках в чат.
    channels.telegram.errorCooldownMs number (мс) 14400000 (4ч) Окно cooldown для политики once. После отправки ошибки такое же сообщение об ошибке подавляется до истечения этого интервала. Предотвращает спам ошибками во время сбоев.

    Поддерживаются переопределения для учетной записи, группы и темы (с тем же наследованием, что и у других ключей конфигурации Telegram).

    json5
    {  channels: {    telegram: {      errorPolicy: "always",      errorCooldownMs: 120000,      groups: {        "-1001234567890": {          errorPolicy: "silent", // suppress errors in this group        },      },    },  },}

    Устранение неполадок

    Бот не отвечает на групповые сообщения без упоминания
    • Если requireMention=false, режим приватности Telegram должен разрешать полную видимость.
      • BotFather: /setprivacy -> Disable
      • затем удалите и заново добавьте бота в группу
    • openclaw channels status предупреждает, когда конфигурация ожидает групповые сообщения без упоминания.
    • openclaw channels status --probe может проверять явные числовые ID групп; wildcard "*" нельзя проверить на членство.
    • быстрый тест сессии: /activation always.
    Бот вообще не видит групповые сообщения
    • когда существует channels.telegram.groups, группа должна быть указана (или включать "*")
    • проверьте членство бота в группе
    • просмотрите логи: openclaw logs --follow для причин пропуска
    Команды работают частично или не работают вовсе
    • авторизуйте идентификатор отправителя (сопряжение и/или числовой allowFrom)
    • авторизация команд по-прежнему применяется, даже когда политика группы — open
    • setMyCommands failed с BOT_COMMANDS_TOO_MUCH означает, что в нативном меню слишком много пунктов; уменьшите число команд Plugin/skill/пользовательских команд или отключите нативные меню
    • стартовые вызовы deleteMyCommands / setMyCommands и вызовы индикатора ввода sendChatAction ограничены и повторяются один раз через транспортный fallback Telegram при тайм-ауте запроса. Постоянные сетевые ошибки/fetch обычно указывают на проблемы доступности DNS/HTTPS до api.telegram.org
    При запуске сообщается о неавторизованном токене
    • getMe returned 401 — это сбой аутентификации Telegram для настроенного токена бота.
    • Снова скопируйте или заново сгенерируйте токен бота в BotFather, затем обновите channels.telegram.botToken, channels.telegram.tokenFile, channels.telegram.accounts.<id>.botToken или TELEGRAM_BOT_TOKEN для учетной записи по умолчанию.
    • deleteWebhook 401 Unauthorized во время запуска — тоже сбой аутентификации; трактовка этого как «webhook не существует» только отложила бы тот же сбой из-за плохого токена до последующих вызовов API.
    Нестабильность polling или сети
    • Node 22+ и пользовательский fetch/proxy могут вызывать немедленное прерывание, если типы AbortSignal не совпадают.
    • Некоторые хосты сначала разрешают api.telegram.org в IPv6; неработающий исходящий IPv6 может вызывать периодические сбои Telegram API.
    • Если логи содержат TypeError: fetch failed или Network request for 'getUpdates' failed!, OpenClaw теперь повторяет их как восстанавливаемые сетевые ошибки.
    • Во время запуска polling OpenClaw повторно использует успешную стартовую проверку getMe для grammY, поэтому runner не нуждается во втором getMe перед первым getUpdates.
    • Если deleteWebhook завершается временной сетевой ошибкой во время запуска polling, OpenClaw переходит к long polling вместо выполнения еще одного управляющего вызова перед polling. Все еще активный webhook проявляется как конфликт getUpdates; затем OpenClaw пересоздает транспорт Telegram и повторяет очистку webhook.
    • Если сокеты Telegram пересоздаются по короткому фиксированному интервалу, проверьте низкое значение channels.telegram.timeoutSeconds; клиенты бота ограничивают настроенные значения ниже ограничений исходящих запросов и запросов getUpdates, но более старые выпуски могли прерывать каждый polling или ответ, когда это значение было установлено ниже этих ограничений.
    • Если логи содержат Polling stall detected, OpenClaw перезапускает polling и пересоздает транспорт Telegram после 120 секунд без завершенной проверки живости long-poll по умолчанию.
    • openclaw channels status --probe и openclaw doctor предупреждают, когда работающая учетная запись polling не завершила getUpdates после стартового grace-периода, когда работающая учетная запись webhook не завершила setWebhook после стартового grace-периода или когда последняя успешная активность транспорта polling устарела.
    • Увеличивайте channels.telegram.pollingStallThresholdMs только когда долгие вызовы getUpdates исправны, но ваш хост все еще сообщает о ложных перезапусках из-за зависания polling. Постоянные зависания обычно указывают на проблемы proxy, DNS, IPv6 или исходящего TLS между хостом и api.telegram.org.
    • Telegram также учитывает переменные окружения proxy процесса для транспорта Bot API, включая HTTP_PROXY, HTTPS_PROXY, ALL_PROXY и их варианты в нижнем регистре. NO_PROXY / no_proxy все еще могут обходить api.telegram.org.
    • Если управляемый proxy OpenClaw настроен через OPENCLAW_PROXY_URL для сервисного окружения и стандартные переменные окружения proxy отсутствуют, Telegram также использует этот URL для транспорта Bot API.
    • На VPS-хостах с нестабильным прямым исходящим соединением/TLS маршрутизируйте вызовы Telegram API через channels.telegram.proxy:
    yaml
    channels:telegram:proxy: socks5://<user>:<password>@proxy-host:1080
    • Node 22+ по умолчанию использует autoSelectFamily=true (кроме WSL2). Порядок результатов DNS для Telegram учитывает сначала OPENCLAW_TELEGRAM_DNS_RESULT_ORDER, затем channels.telegram.network.dnsResultOrder, затем значение процесса по умолчанию, например NODE_OPTIONS=--dns-result-order=ipv4first; если ничего из этого не применимо, Node 22+ возвращается к ipv4first.
    • Если ваш хост работает в WSL2 или явно лучше работает в режиме только IPv4, принудительно задайте выбор семейства:
    yaml
    channels:telegram:network:  autoSelectFamily: false
    • Ответы из диапазона RFC 2544 для бенчмарков (198.18.0.0/15) уже разрешены для загрузок медиа Telegram по умолчанию. Если доверенный fake-IP или прозрачный прокси переписывает api.telegram.org на какой-либо другой частный/внутренний/специальный адрес во время загрузок медиа, можно явно включить обход только для Telegram:
    yaml
    channels:telegram:network:  dangerouslyAllowPrivateNetwork: true
    • Такая же явная настройка доступна для каждой учетной записи по адресу channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork.
    • Если ваш прокси разрешает хосты медиа Telegram в 198.18.x.x, сначала оставьте опасный флаг выключенным. Медиа Telegram уже разрешает диапазон RFC 2544 для бенчмарков по умолчанию.
    • Переопределения через окружение (временные):
      • OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1
      • OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1
      • OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first
    • Проверьте DNS-ответы:
    bash
    dig +short api.telegram.org Adig +short api.telegram.org AAAA

    Дополнительная помощь: Устранение неполадок каналов.

    Справочник конфигурации

    Основной справочник: Справочник конфигурации - Telegram.

    High-signal Telegram fields
    • запуск/аутентификация: enabled, botToken, tokenFile, accounts.* (tokenFile должен указывать на обычный файл; символьные ссылки отклоняются)
    • контроль доступа: dmPolicy, allowFrom, groupPolicy, groupAllowFrom, groups, groups.*.topics.*, верхнеуровневый bindings[] (type: "acp")
    • значения по умолчанию для тем: groups.<chatId>.topics."*" применяется к несопоставленным темам форума; точные идентификаторы тем имеют приоритет
    • подтверждения выполнения: execApprovals, accounts.*.execApprovals
    • команды/меню: commands.native, commands.nativeSkills, customCommands
    • потоки/ответы: replyToMode
    • потоковая передача: streaming (предварительная версия), streaming.preview.toolProgress, blockStreaming
    • форматирование/доставка: textChunkLimit, chunkMode, richMessages, linkPreview, responsePrefix
    • медиа/сеть: mediaMaxMb, mediaGroupFlushMs, timeoutSeconds, pollingStallThresholdMs, retry, network.autoSelectFamily, network.dangerouslyAllowPrivateNetwork, proxy
    • пользовательский корень API: apiRoot (только корень Bot API; не включайте /bot&lt;TOKEN&gt;)
    • Webhook: webhookUrl, webhookSecret, webhookPath, webhookHost
    • действия/возможности: capabilities.inlineButtons, actions.sendMessage|editMessage|deleteMessage|reactions|sticker
    • реакции: reactionNotifications, reactionLevel
    • ошибки: errorPolicy, errorCooldownMs
    • записи/история: configWrites, historyLimit, dmHistoryLimit, dms.*.historyLimit

    Связанные материалы

    Was this useful?
    On this page

    On this page