Все системы работают Ваш IP: 216.73.217.113 info@cloudhosting.lv +371 66 66 29 69 Личный кабинет

← Все вопросы

Настройка Telegram-бота OpenClaw: токен, allowFrom и ошибки

Обновлено:

Чтобы подключить OpenClaw к Telegram, создайте бота в @BotFather, положите его токен в ~/.openclaw/.env, добавьте блок channels.telegram в ~/.openclaw/openclaw.json и привяжите бота к своему числовому Telegram user id через allowFrom. Шлюз по умолчанию использует long polling, поэтому серверу не нужны ни публичный порт, ни домен. Большинство сбоев сводится к трём вещам: опечатка в токене (401 от getMe), неверный id в allowFrom (код сопряжения или тишина вместо ответа) или режим приватности Telegram, который скрывает сообщения в группах.

Каждый ключ и каждая команда ниже сверены с официальной документацией OpenClaw (2026.9.x) и страницами Telegram Bot API; там, где документация молчит, мы говорим об этом прямо.

Что нужно до начала

  • Работающий шлюз OpenClaw: CLI openclaw на обычном хосте или Docker-образ ghcr.io/openclaw/openclaw с каталогом ~/.openclaw хоста, смонтированным в /home/node/.openclaw. Ещё не установлен? Смотрите нашу инструкцию по установке.
  • Уже настроенный ключ LLM-провайдера (OpenAI, Anthropic, OpenAI-совместимый шлюз или Ollama).
  • Аккаунт Telegram. Документация советует начинать именно с Telegram: ему "нужен только токен бота, никакой плагин устанавливать не надо".

Шаг 1: создайте бота в BotFather

Откройте Telegram, начните чат с @BotFather и отправьте /newbot. Он спросит отображаемое имя и username, оканчивающийся на bot, а затем ответит токеном вида 4839574812:AAFD39kkdpWt3ywyRZergyOLMaJhac60qc. Учебник Telegram говорит прямо: обращайтесь с ним как с паролем и никому не показывайте.

Для приватного бота с одним владельцем оставьте /setprivacy и /setjoingroups со значениями по умолчанию; к режиму приватности мы вернёмся ниже.

Шаг 2: храните токен в .env, а не в файле конфигурации

OpenClaw читает переменные окружения из родительского процесса и из ~/.openclaw/.env как глобального запасного источника, который никогда не перекрывает переменную, уже заданную в оболочке. Положите токен туда:

TELEGRAM_BOT_TOKEN=4839574812:AAFD39kkdpWt3ywyRZergyOLMaJhac60qc

Работают оба документированных способа передать его каналу:

  1. Запасной вариант из окружения. Если channels.telegram.botToken отсутствует, шлюз берёт TELEGRAM_BOT_TOKEN (только для аккаунта по умолчанию; именованным аккаунтам нужен botToken или tokenFile).
  2. Явная ссылка. Запишите "botToken": "${TELEGRAM_BOT_TOKEN}". Подстановка работает в любой строке конфигурации, раскрываются только имена в верхнем регистре, а отсутствующие переменные "остаются видимо неразрешёнными" и выдают предупреждение. Мы предпочитаем эту форму: конфигурация показывает, где хранится секрет.

Приоритет, цитата со страницы настройки: "tokenFile сильнее botToken, а botToken сильнее окружения." Поэтому, если новый токен не применяется, ищите устаревший botToken или tokenFile. tokenFile должен быть обычным файлом; символические ссылки отклоняются.

Шаг 3: блок channels.telegram в openclaw.json

Документация описывает ~/.openclaw/openclaw.json как JSON5 (комментарии и завершающие запятые допустимы); мы держим свой файл в строгом JSON. Минимальный первый блок:

{
  "channels": {
    "telegram": {
      "enabled": true,
      "botToken": "${TELEGRAM_BOT_TOKEN}",
      "dmPolicy": "pairing"
    }
  }
}

Сокращение CLI openclaw channels add --channel telegram --token <bot-token> записывает токен прямо в файл конфигурации; на серверах мы предпочитаем ссылку на окружение, описанную выше.

dmPolicy решает, кто может писать боту в личном чате. Четыре документированных значения:

  • pairing (по умолчанию): незнакомый отправитель вместо ответа получает 8-символьный код, и ничего не обрабатывается, пока вы не одобрите его из CLI. Коды истекают через час, не больше трёх ожидающих на аккаунт канала.
  • allowlist: обслуживаются только id из allowFrom, без сопряжения. Нужен хотя бы один id.
  • open: требует, чтобы allowFrom содержал "*". Документация: использовать "только для намеренно публичных ботов с жёстко ограниченными инструментами".
  • disabled: личные сообщения отключены.

Шлюз следит за файлом конфигурации и применяет большинство изменений автоматически (страница горячей перезагрузки в документации перечисляет, что по-прежнему требует перезапуска); в Docker docker compose up -d openclaw-gateway пересоздаёт контейнер.

Шаг 4: узнайте свой Telegram user id и задайте allowFrom

Именно здесь чаще всего что-то идёт не так. allowFrom принимает числовые Telegram user id в кавычках, как строки: "не номер телефона, не username, не ID чата или группы и не ID бота". Префиксы telegram: и tg: принимаются и нормализуются.

Три документированных способа узнать свой id:

  1. Запустите шлюз с политикой pairing по умолчанию, напишите боту и прочитайте Your Telegram user id в его ответе о сопряжении.
  2. Запустите openclaw logs --follow и прочитайте senderUserId в записи telegram pairing request.
  3. Когда бот уже отвечает вам, отправьте /whoami@<bot_username>; он подтвердит ваш user id, а в разрешённой группе ещё и id группы.

Теперь привяжите бота к себе. Пример из документации для одного владельца сохраняет pairing и добавляет allowFrom: вы одобрены заранее, посторонние видят лишь код, который можно игнорировать.

{
  "channels": {
    "telegram": {
      "enabled": true,
      "botToken": "${TELEGRAM_BOT_TOKEN}",
      "dmPolicy": "pairing",
      "allowFrom": ["123456789"]
    }
  }
}

Если запросы сопряжения не нужны вовсе, поставьте dmPolicy в allowlist с тем же allowFrom.

Шаг 5: запустите, проверьте и отправьте первое сообщение

openclaw gateway start
openclaw channels status --probe
openclaw logs --follow

channels status --probe подтверждает у Telegram, что канал готов, поэтому неверный токен проявится здесь первым. В Docker используйте обёртку со страницы установки docker compose exec openclaw-gateway sh -lc 'node dist/index.js gateway health', заменив подкоманду на channels status --probe.

Напишите боту. Если вы оставили pairing без allowFrom, получите код; одобрите его так:

openclaw pairing list telegram
openclaw pairing approve telegram <CODE>

Одобренные отправители хранятся в ~/.openclaw/state/openclaw.sqlite и переживают перезапуски. Одобрение "даёт доступ только к личным сообщениям", но не к группам. Чтобы проверить токен без OpenClaw, вызовите getMe: curl -s "https://api.telegram.org/bot<TOKEN>/getMe" на сервере, а не в браузере, чтобы токен не остался в истории.

Личный чат против групп и режим приватности

Документация считает группы поддерживаемыми при условии срабатывания по упоминанию, но для ассистента с одним владельцем личный чат безопаснее: сообщение любого другого участника является недоверенным содержимым, которое читает модель, тот самый случай prompt injection из документации. Если группа всё же нужна, должны сойтись три вещи.

1. Группа должна быть в списке разрешённых. groupPolicy по умолчанию равен allowlist, поэтому id чата должен присутствовать в channels.telegram.groups (или должен стоять подстановочный знак "*"). Id супергрупп отрицательные и начинаются с -100; прочитайте его в openclaw logs --follow, через бота, показывающего id пересланных сообщений, или через getUpdates.

2. Решите, кто может его запускать. groupAllowFrom принимает числовые user id по тем же правилам, что и allowFrom; если он не задан, используется allowFrom. Укажите там только свой id.

3. Упоминания и режим приватности. При requireMention: true бот отвечает только на упоминание, и именно этот режим страница настройки сочетает с режимом приватности Telegram (включён по умолчанию), в котором бот получает только адресованные ему команды, ответы на свои сообщения и служебные сообщения. Для requireMention: false, или если упоминания до бота не доходят, отключите режим приватности через /setprivacy в BotFather, затем удалите бота из группы и добавьте заново; Telegram применяет изменение только при повторном входе. Администраторы группы получают все сообщения в любом случае.

{
  "channels": {
    "telegram": {
      "enabled": true,
      "botToken": "${TELEGRAM_BOT_TOKEN}",
      "dmPolicy": "allowlist",
      "allowFrom": ["123456789"],
      "groupPolicy": "allowlist",
      "groupAllowFrom": ["123456789"],
      "groups": {
        "-1001234567890": { "requireMention": true }
      }
    }
  }
}

Polling или webhook

"Long polling используется по умолчанию." Шлюз в цикле вызывает getUpdates Telegram, и ему нужен только исходящий HTTPS: ни открытого порта, ни домена, ни сертификата. Так работаем и мы.

Режиму webhook нужны channels.telegram.webhookUrl и channels.telegram.webhookSecret; слушатель по умолчанию использует webhookHost 127.0.0.1, webhookPort 8787 и webhookPath /telegram-webhook (/healthz зарезервирован). Он привязан к loopback, поэтому перед ним ставят обратный прокси с настоящим сертификатом (или задают webhookCertPath для самоподписанного сертификата на голом IP); Telegram доставляет только на HTTPS-порты 443, 80, 88 или 8443.

Одно правило Bot API кусает тех, кто переключается туда и обратно: getUpdates и webhook взаимоисключающие. OpenClaw вызывает deleteWebhook при старте polling; если вызов не удался из-за кратковременной сетевой ошибки, оставшийся webhook проявляется как конфликт getUpdates, и шлюз пересобирает транспорт и повторяет попытку. Только если это повторяется снова и снова, вызывайте deleteWebhook сами.

Типичные ошибки и что они значат

СимптомВероятная причинаРешение
В логах запуска getMe returned 401Опечатка в токене или он отозван, либо устаревший botToken/tokenFile перекрывает .envСгенерируйте токен заново в BotFather, обновите botToken или TELEGRAM_BOT_TOKEN, снова запустите channels status --probe
Бот онлайн, но никогда не отвечает на ваше личное сообщениеОжидает запрос сопряжения, или в allowFrom записан username, номер телефона, id группы или id самого ботаopenclaw pairing list telegram; прочитайте senderUserId в логах; исправьте allowFrom; openclaw doctor --fix для устаревших записей
Команды работают частичноОтправитель не авторизован, или setMyCommands failed с BOT_COMMANDS_TOO_MUCHАвторизуйте отправителя; сократите число пользовательских команд или отключите нативные меню
Бот игнорирует сообщения в группе без упоминанияРежим приватности Telegram включён, а requireMention равен false/setprivacy Disable в BotFather, затем удалите и заново добавьте бота
Бот ничего не видит в группеГруппа не указана в channels.telegram.groups, нет записи "*", или бот не участникДобавьте id вида -100...; channels status --probe проверяет членство; логи показывают причину пропуска
Polling stall detected120 секунд нет ни одного завершённого цикла long polling; часто IPv6 DNS или нестабильный исходящий каналПерезапускается сам; если повторяется, проверьте dig +short api.telegram.org AAAA, принудительно включите IPv4 (channels.telegram.network.autoSelectFamily: false или NODE_OPTIONS=--dns-result-order=ipv4first) или задайте channels.telegram.proxy
Текст работает, вложения падают с getaddrinfo EAI_AGAIN или ENOTFOUNDЗагрузка медиа по-прежнему использует локальный DNS даже при заданных переменных окружения проксиЗадайте channels.telegram.proxy (HTTP(S) или SOCKS5), чтобы он разрешал имена хостов медиа

Безопасность: один владелец, один токен, замена при утечке

OpenClaw по своей природе является удалённым выполнением кода: кто может написать боту, тот может управлять его инструментами. Страница безопасности требует "одну границу доверия на шлюз: один оператор или команда, участники которой доверяют друг другу", а страница о prompt injection ограничивает инструменты высокого риска (exec, browser, web_fetch, web_search) доверенными агентами или явными списками разрешённых. На практике:

  • Ровно один id в allowFrom, ваш. Никаких "*", никакого общего бота с включённым exec.
  • Ограничьте инструменты для всех, кроме себя. Пример из документации запрещает write и edit для подстановочного отправителя и оставляет владельца без ограничений:
    "direct": {
      "*": { "tools": { "deny": ["write", "edit"] } },
      "123456789": { "tools": {} }
    }
  • Никогда не вставляйте токен в чат, тикет или скриншот. Если он утёк, /token в BotFather выдаёт замену; обновите .env и снова запустите channels status --probe.
  • Держите шлюз на loopback. Панель управления по умолчанию слушает http://127.0.0.1:18789/; заходите на неё через SSH-туннель или Tailscale, но никогда через опубликованный порт. Telegram она не нужна, а CVE-2026-25253 (RCE в один клик через кражу токена) объясняет, почему мы на этом настаиваем.
  • Запускайте openclaw security audit после каждого изменения конфигурации; документация называет это единственной командой, которая скажет, отклонились ли вы от безопасной настройки.

Запуск на сервере

Telegram-ассистент должен быть онлайн в момент, когда вы ему пишете, поэтому ноутбук не подходит; хватит любой небольшой Linux VM с исходящим HTTPS. Наш каталог VPS покрывает этот диапазон; если хотите пропустить установку, готовый сервер OpenClaw от 9.35 EUR в месяц поставляется с Ubuntu 24.04 и шлюзом, уже работающим в Docker: добавьте свой ключ LLM, подключите бота, как описано выше, и агент будет отвечать только вам. Выбираете между облачной моделью и собственной? Смотрите это сравнение.

Вопросы

Нужен ли домен или открытый порт для Telegram-бота?

Нет. Long polling используется по умолчанию и работает только через исходящий HTTPS. Домен, сертификат и входящий порт нужны лишь при переходе в режим webhook.

Почему бот отвечает кодом вместо ответа?

Так работает политика pairing по умолчанию: ваш id ещё не одобрен. Выполните openclaw pairing approve telegram <CODE> или добавьте свой числовой user id в allowFrom. Коды истекают через час.

Можно ли указать в allowFrom мой @username?

Нет. allowFrom и groupAllowFrom принимают только числовые Telegram user id. Старые конфигурации с записями @username преобразует openclaw doctor --fix.

Бот в моей группе, но ничего не читает. Почему?

Действуют два фильтра: id группы должен быть указан в channels.telegram.groups (или должна быть запись "*"), а режим приватности Telegram должен позволять боту видеть сообщения. Оставьте requireMention: true, либо отключите режим приватности через /setprivacy и добавьте бота заново, либо сделайте бота администратором группы.

Хотите, чтобы это работало приватно?
AI-ассистент на своём сервере в ЕС, и данные остаются там, куда вы их положили.
Посмотреть цены

Готовы начать?

Запустите за минуты или обсудите с инженером, что подходит вашему проекту.