Mainstream messaging

Telegram

Gotowy do produkcji dla wiadomości prywatnych bota i grup przez grammY. Domyślnym trybem jest długie odpytywanie; tryb Webhook jest opcjonalny.

Szybka konfiguracja

  • Utwórz token bota w BotFather

    Otwórz Telegram i porozmawiaj z @BotFather (potwierdź, że identyfikator to dokładnie @BotFather).

    Uruchom /newbot, wykonaj instrukcje i zapisz token.

  • Skonfiguruj token i politykę wiadomości prywatnych

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

    Rezerwowe źródło z env: TELEGRAM_BOT_TOKEN=... (tylko konto domyślne). Telegram nie używa openclaw channels login telegram; skonfiguruj token w konfiguracji/env, a następnie uruchom gateway.

  • Uruchom gateway i zatwierdź pierwszą wiadomość prywatną

    openclaw gateway
    openclaw pairing list telegram
    openclaw pairing approve telegram <CODE>
    

    Kody parowania wygasają po 1 godzinie.

  • Dodaj bota do grupy

    Dodaj bota do swojej grupy, a następnie ustaw channels.telegram.groups i groupPolicy tak, aby pasowały do Twojego modelu dostępu.

  • Ustawienia po stronie Telegram

    Tryb prywatności i widoczność grup

    Boty Telegram domyślnie używają trybu prywatności, który ogranicza wiadomości grupowe, jakie otrzymują.

    Jeśli bot musi widzieć wszystkie wiadomości grupowe, wykonaj jedną z czynności:

    • wyłącz tryb prywatności przez /setprivacy, lub
    • ustaw bota jako administratora grupy.

    Po przełączeniu trybu prywatności usuń i ponownie dodaj bota w każdej grupie, aby Telegram zastosował zmianę.

    Uprawnienia grupy

    Status administratora jest kontrolowany w ustawieniach grupy Telegram.

    Boty administracyjne otrzymują wszystkie wiadomości grupowe, co jest przydatne dla zawsze aktywnego zachowania w grupach.

    Przydatne przełączniki BotFather
    • /setjoingroups, aby zezwolić/zabronić dodawania do grup
    • /setprivacy dla zachowania widoczności w grupach

    Kontrola dostępu i aktywacja

    Polityka wiadomości prywatnych

    channels.telegram.dmPolicy kontroluje dostęp przez wiadomości bezpośrednie:

    • pairing (domyślnie)
    • allowlist (wymaga co najmniej jednego ID nadawcy w allowFrom)
    • open (wymaga, aby allowFrom zawierało "*")
    • disabled

    dmPolicy: "open" z allowFrom: ["*"] pozwala dowolnemu kontu Telegram, które znajdzie lub odgadnie nazwę użytkownika bota, wydawać mu polecenia. Używaj tego tylko dla celowo publicznych botów z mocno ograniczonymi narzędziami; boty z jednym właścicielem powinny używać allowlist z liczbowymi ID użytkowników.

    channels.telegram.allowFrom przyjmuje liczbowe ID użytkowników Telegram. Prefiksy telegram: / tg: są akceptowane i normalizowane. W konfiguracjach wielokontowych restrykcyjne channels.telegram.allowFrom na najwyższym poziomie jest traktowane jako granica bezpieczeństwa: wpisy allowFrom: ["*"] na poziomie konta nie czynią tego konta publicznym, chyba że efektywna lista dozwolonych konta po scaleniu nadal zawiera jawny symbol wieloznaczny. dmPolicy: "allowlist" z pustym allowFrom blokuje wszystkie wiadomości prywatne i jest odrzucane przez walidację konfiguracji. Konfigurator pyta tylko o liczbowe ID użytkowników. Jeśli wykonano aktualizację i konfiguracja zawiera wpisy listy dozwolonych @username, uruchom openclaw doctor --fix, aby je rozwiązać (najlepszy możliwy wynik; wymaga tokena bota Telegram). Jeśli wcześniej używano plików listy dozwolonych z magazynu parowania, openclaw doctor --fix może odzyskać wpisy do channels.telegram.allowFrom w przepływach listy dozwolonych (na przykład gdy dmPolicy: "allowlist" nie ma jeszcze jawnych ID).

    Dla botów z jednym właścicielem preferuj dmPolicy: "allowlist" z jawnymi liczbowymi ID allowFrom, aby polityka dostępu była trwała w konfiguracji (zamiast zależeć od wcześniejszych zatwierdzeń parowania).

    Częste nieporozumienie: zatwierdzenie parowania wiadomości prywatnych nie oznacza „ten nadawca jest autoryzowany wszędzie”. Parowanie przyznaje dostęp do wiadomości prywatnych. Jeśli właściciel poleceń jeszcze nie istnieje, pierwsze zatwierdzone parowanie ustawia też commands.ownerAllowFrom, dzięki czemu polecenia tylko dla właściciela i zatwierdzenia exec mają jawne konto operatora. Autoryzacja nadawcy w grupach nadal pochodzi z jawnych list dozwolonych w konfiguracji. Jeśli chcesz „jestem autoryzowany raz i działają zarówno wiadomości prywatne, jak i polecenia grupowe”, umieść swoje liczbowe ID użytkownika Telegram w channels.telegram.allowFrom; dla poleceń tylko dla właściciela upewnij się, że commands.ownerAllowFrom zawiera telegram:<your user id>.

    Znajdowanie ID użytkownika Telegram

    Bezpieczniej (bez bota zewnętrznego):

    1. Wyślij wiadomość prywatną do swojego bota.
    2. Uruchom openclaw logs --follow.
    3. Odczytaj from.id.

    Oficjalna metoda Bot API:

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

    Metoda zewnętrzna (mniej prywatna): @userinfobot lub @getidsbot.

    Polityka grup i listy dozwolonych

    Dwie kontrolki działają razem:

    1. Które grupy są dozwolone (channels.telegram.groups)

      • brak konfiguracji groups:
        • z groupPolicy: "open": dowolna grupa może przejść kontrole ID grupy
        • z groupPolicy: "allowlist" (domyślnie): grupy są blokowane do czasu dodania wpisów groups (lub "*")
      • skonfigurowane groups: działa jako lista dozwolonych (jawne ID lub "*")
    2. Którzy nadawcy są dozwoleni w grupach (channels.telegram.groupPolicy)

      • open
      • allowlist (domyślnie)
      • disabled

    groupAllowFrom służy do filtrowania nadawców w grupach. Jeśli nie jest ustawione, Telegram wraca do allowFrom. Wpisy groupAllowFrom powinny być liczbowymi ID użytkowników Telegram (prefiksy telegram: / tg: są normalizowane). Nie umieszczaj ID czatu grupy ani supergrupy Telegram w groupAllowFrom. Ujemne ID czatu należą do channels.telegram.groups. Wpisy nieliczbowe są ignorowane przy autoryzacji nadawcy. Granica bezpieczeństwa (2026.2.25+): autoryzacja nadawcy w grupie nie dziedziczy zatwierdzeń z magazynu parowania wiadomości prywatnych. Parowanie pozostaje tylko dla wiadomości prywatnych. Dla grup ustaw groupAllowFrom albo allowFrom dla danej grupy/tematu. Jeśli groupAllowFrom nie jest ustawione, Telegram wraca do konfiguracji allowFrom, a nie do magazynu parowania. Praktyczny wzorzec dla botów z jednym właścicielem: ustaw swoje ID użytkownika w channels.telegram.allowFrom, pozostaw groupAllowFrom nieustawione i zezwól na grupy docelowe w channels.telegram.groups. Uwaga dotycząca działania: jeśli channels.telegram całkowicie brakuje, środowisko uruchomieniowe domyślnie działa w trybie fail-closed groupPolicy="allowlist", chyba że channels.defaults.groupPolicy jest jawnie ustawione.

    Przykład: zezwól dowolnemu członkowi w jednej konkretnej grupie:

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

    Przykład: zezwól tylko konkretnym użytkownikom w jednej konkretnej grupie:

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

    Zachowanie wzmianek

    Odpowiedzi w grupach domyślnie wymagają wzmianki.

    Wzmianka może pochodzić z:

    • natywnej wzmianki @botusername, lub
    • wzorców wzmianek w:
      • agents.list[].groupChat.mentionPatterns
      • messages.groupChat.mentionPatterns

    Przełączniki poleceń na poziomie sesji:

    • /activation always
    • /activation mention

    Aktualizują one tylko stan sesji. Użyj konfiguracji dla trwałości.

    Przykład trwałej konfiguracji:

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

    Pobieranie ID czatu grupowego:

    • przekaż wiadomość grupową do @userinfobot / @getidsbot
    • albo odczytaj chat.id z openclaw logs --follow
    • albo sprawdź Bot API getUpdates

    Zachowanie w środowisku uruchomieniowym

    • Telegram jest obsługiwany przez proces gateway.
    • Routing jest deterministyczny: odpowiedzi przychodzące z Telegram wracają do Telegram (model nie wybiera kanałów).
    • Wiadomości przychodzące są normalizowane do współdzielonej koperty kanału z metadanymi odpowiedzi i placeholderami mediów.
    • Sesje grupowe są izolowane według ID grupy. Tematy forum dopisują :topic:<threadId>, aby utrzymać izolację tematów.
    • Wiadomości prywatne mogą przenosić message_thread_id; OpenClaw zachowuje ID wątku dla odpowiedzi, ale domyślnie utrzymuje wiadomości prywatne w płaskiej sesji. Skonfiguruj channels.telegram.dm.threadReplies: "inbound", channels.telegram.direct.<chatId>.threadReplies: "inbound", requireTopic: true albo pasującą konfigurację tematu, gdy celowo chcesz izolować sesje tematów w wiadomościach prywatnych.
    • Długie odpytywanie używa runnera grammY z sekwencjonowaniem per czat/per wątek. Ogólna współbieżność sink runnera używa agents.defaults.maxConcurrent.
    • Długie odpytywanie jest chronione wewnątrz każdego procesu gateway, aby tylko jeden aktywny odpytywacz mógł używać tokena bota w danym czasie. Jeśli nadal widzisz konflikty getUpdates 409, prawdopodobnie inny OpenClaw gateway, skrypt lub zewnętrzny odpytywacz używa tego samego tokena.
    • Ponowne uruchomienia watchdog dla długiego odpytywania są domyślnie wyzwalane po 120 sekundach bez zakończonej żywotności getUpdates. Zwiększ channels.telegram.pollingStallThresholdMs tylko wtedy, gdy Twoje wdrożenie nadal widzi fałszywe restarty zatrzymanego odpytywania podczas długotrwałej pracy. Wartość jest podawana w milisekundach i dozwolona w zakresie od 30000 do 600000; obsługiwane są nadpisania per konto.
    • Telegram Bot API nie obsługuje potwierdzeń odczytu (sendReadReceipts nie ma zastosowania).

    Odniesienie do funkcji

    Podgląd strumienia na żywo (edycje wiadomości)

    OpenClaw może strumieniować częściowe odpowiedzi w czasie rzeczywistym:

    • czaty bezpośrednie: wiadomość podglądu + editMessageText
    • grupy/tematy: wiadomość podglądu + editMessageText

    Wymaganie:

    • channels.telegram.streaming ma wartość off | partial | block | progress (domyślnie: partial)
    • progress utrzymuje jedną edytowalną wersję roboczą statusu dla postępu narzędzi, czyści ją po zakończeniu i wysyła finalną odpowiedź jako zwykłą wiadomość
    • streaming.preview.toolProgress kontroluje, czy aktualizacje narzędzi/postępu ponownie używają tej samej edytowanej wiadomości podglądu (domyślnie: true, gdy strumieniowanie podglądu jest aktywne)
    • streaming.preview.commandText kontroluje szczegóły poleceń/exec w tych liniach postępu narzędzi: raw (domyślnie, zachowuje wydane zachowanie) lub status (tylko etykieta narzędzia)
    • starsze channels.telegram.streamMode i logiczne wartości streaming są wykrywane; uruchom openclaw doctor --fix, aby zmigrować je do channels.telegram.streaming.mode

    Aktualizacje podglądu postępu narzędzi to krótkie linie statusu pokazywane podczas działania narzędzi, na przykład wykonywania poleceń, odczytów plików, aktualizacji planowania lub podsumowań poprawek. Telegram domyślnie utrzymuje je włączone, aby pasowały do wydanego zachowania OpenClaw od v2026.4.22 i nowszych. Aby zachować edytowany podgląd tekstu odpowiedzi, ale ukryć linie postępu narzędzi, ustaw:

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

    Aby pozostawić widoczny postęp narzędzi, ale ukryć tekst polecenia/exec, ustaw:

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

    Użyj trybu progress, gdy chcesz widzieć postęp narzędzi bez edytowania końcowej odpowiedzi w tej samej wiadomości. Umieść zasadę tekstu polecenia pod streaming.progress:

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

    Używaj streaming.mode: "off" tylko wtedy, gdy chcesz dostarczać wyłącznie odpowiedzi końcowe: edycje podglądu Telegram są wyłączone, a ogólne komunikaty narzędzi/postępu są wyciszane zamiast wysyłania ich jako samodzielnych komunikatów statusu. Monity o zatwierdzenie, ładunki multimedialne i błędy nadal przechodzą przez zwykłe dostarczanie końcowe. Użyj streaming.preview.toolProgress: false, gdy chcesz zachować tylko edycje podglądu odpowiedzi, ukrywając wiersze statusu postępu narzędzi.

    Dla odpowiedzi wyłącznie tekstowych:

    • krótkie podglądy w DM/grupie/temacie: OpenClaw zachowuje tę samą wiadomość podglądu i wykonuje końcową edycję w miejscu
    • długie końcowe teksty dzielone na wiele wiadomości Telegram ponownie używają istniejącego podglądu jako pierwszego końcowego fragmentu, gdy to możliwe, a następnie wysyłają tylko pozostałe fragmenty
    • końcowe odpowiedzi w trybie postępu czyszczą szkic statusu i używają zwykłego dostarczania końcowego zamiast edytować szkic w odpowiedź
    • jeśli końcowa edycja nie powiedzie się, zanim ukończony tekst zostanie potwierdzony, OpenClaw używa zwykłego dostarczania końcowego i usuwa nieaktualny podgląd

    Dla złożonych odpowiedzi (na przykład ładunków multimedialnych) OpenClaw przełącza się na zwykłe dostarczanie końcowe, a następnie usuwa wiadomość podglądu.

    Strumieniowanie podglądu jest oddzielne od strumieniowania bloków. Gdy strumieniowanie bloków jest jawnie włączone dla Telegram, OpenClaw pomija strumień podglądu, aby uniknąć podwójnego strumieniowania.

    Strumień rozumowania tylko dla Telegram:

    • /reasoning stream wysyła rozumowanie do podglądu na żywo podczas generowania
    • podgląd rozumowania jest usuwany po końcowym dostarczeniu; użyj /reasoning on, gdy rozumowanie ma pozostać widoczne
    • końcowa odpowiedź jest wysyłana bez tekstu rozumowania
    Formatowanie i awaryjny HTML

    Tekst wychodzący używa Telegram parse_mode: "HTML".

    • Tekst podobny do Markdown jest renderowany do HTML bezpiecznego dla Telegram.
    • Surowy HTML modelu jest escapowany, aby ograniczyć błędy parsowania Telegram.
    • Jeśli Telegram odrzuci sparsowany HTML, OpenClaw ponawia próbę jako zwykły tekst.

    Podglądy linków są domyślnie włączone i można je wyłączyć za pomocą channels.telegram.linkPreview: false.

    Polecenia natywne i polecenia niestandardowe

    Rejestracja menu poleceń Telegram jest obsługiwana przy uruchomieniu za pomocą setMyCommands.

    Domyślne ustawienia poleceń natywnych:

    • commands.native: "auto" włącza polecenia natywne dla Telegram

    Dodaj niestandardowe wpisy menu poleceń:

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

    Reguły:

    • nazwy są normalizowane (usunięcie początkowego /, małe litery)
    • prawidłowy wzorzec: a-z, 0-9, _, długość 1..32
    • polecenia niestandardowe nie mogą zastępować poleceń natywnych
    • konflikty/duplikaty są pomijane i logowane

    Uwagi:

    • polecenia niestandardowe są tylko wpisami menu; nie implementują automatycznie zachowania
    • polecenia plugin/skill mogą nadal działać po wpisaniu, nawet jeśli nie są widoczne w menu Telegram

    Jeśli polecenia natywne są wyłączone, wbudowane polecenia są usuwane. Polecenia niestandardowe/plugin mogą nadal zostać zarejestrowane, jeśli są skonfigurowane.

    Typowe błędy konfiguracji:

    • setMyCommands failed z BOT_COMMANDS_TOO_MUCH oznacza, że menu Telegram nadal przepełniło się po przycięciu; zmniejsz liczbę poleceń plugin/skill/niestandardowych albo wyłącz channels.telegram.commands.native.
    • niepowodzenie deleteWebhook, deleteMyCommands lub setMyCommands z 404: Not Found, gdy bezpośrednie polecenia curl Bot API działają, może oznaczać, że channels.telegram.apiRoot ustawiono na pełny punkt końcowy /bot&lt;TOKEN&gt;. apiRoot musi być tylko korzeniem Bot API, a openclaw doctor --fix usuwa przypadkowy końcowy /bot&lt;TOKEN&gt;.
    • getMe returned 401 oznacza, że Telegram odrzucił skonfigurowany token bota. Zaktualizuj botToken, tokenFile lub TELEGRAM_BOT_TOKEN bieżącym tokenem BotFather; OpenClaw zatrzymuje się przed odpytywaniem, więc nie jest to zgłaszane jako błąd czyszczenia Webhook.
    • setMyCommands failed z błędami sieci/fetch zwykle oznacza, że wychodzące DNS/HTTPS do api.telegram.org jest zablokowane.

    Polecenia parowania urządzeń (plugin device-pair)

    Gdy plugin device-pair jest zainstalowany:

    1. /pair generuje kod konfiguracji
    2. wklej kod w aplikacji iOS
    3. /pair pending wyświetla oczekujące żądania (w tym rolę/zakresy)
    4. zatwierdź żądanie:
      • /pair approve <requestId> dla jawnego zatwierdzenia
      • /pair approve, gdy istnieje tylko jedno oczekujące żądanie
      • /pair approve latest dla najnowszego

    Kod konfiguracji przenosi krótkotrwały token bootstrap. Wbudowane przekazanie bootstrap utrzymuje token głównego węzła przy scopes: []; każdy przekazany token operatora pozostaje ograniczony do operator.approvals, operator.read, operator.talk.secrets i operator.write. Sprawdzenia zakresu bootstrap są prefiksowane rolą, więc ta lista dozwolonych operatora spełnia tylko żądania operatora; role niebędące operatorami nadal potrzebują zakresów pod własnym prefiksem roli.

    Jeśli urządzenie ponowi próbę ze zmienionymi szczegółami uwierzytelniania (na przykład rola/zakresy/klucz publiczny), poprzednie oczekujące żądanie zostanie zastąpione, a nowe żądanie użyje innego requestId. Uruchom ponownie /pair pending przed zatwierdzeniem.

    Więcej szczegółów: Parowanie.

    Przyciski wbudowane

    Skonfiguruj zakres klawiatury wbudowanej:

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

    Nadpisanie dla konta:

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

    Zakresy:

    • off
    • dm
    • group
    • all
    • allowlist (domyślnie)

    Starsze capabilities: ["inlineButtons"] mapuje się na inlineButtons: "all".

    Przykład akcji wiadomości:

    {
    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" }],
    ],
    }
    

    Kliknięcia callback są przekazywane agentowi jako tekst: callback_data: <value>

    Akcje wiadomości Telegram dla agentów i automatyzacji

    Akcje narzędzi Telegram obejmują:

    • sendMessage (to, content, opcjonalnie mediaUrl, replyToMessageId, messageThreadId)
    • react (chatId, messageId, emoji)
    • deleteMessage (chatId, messageId)
    • editMessage (chatId, messageId, content)
    • createForumTopic (chatId, name, opcjonalnie iconColor, iconCustomEmojiId)

    Akcje wiadomości kanału udostępniają ergonomiczne aliasy (send, react, delete, edit, sticker, sticker-search, topic-create).

    Kontrole bramkowania:

    • channels.telegram.actions.sendMessage
    • channels.telegram.actions.deleteMessage
    • channels.telegram.actions.reactions
    • channels.telegram.actions.sticker (domyślnie: wyłączone)

    Uwaga: edit i topic-create są obecnie domyślnie włączone i nie mają osobnych przełączników channels.telegram.actions.*. Wysyłki w czasie działania używają aktywnej migawki konfiguracji/sekretów (uruchomienie/przeładowanie), więc ścieżki akcji nie wykonują doraźnego ponownego rozwiązywania SecretRef dla każdej wysyłki.

    Semantyka usuwania reakcji: /tools/reactions

    Tagi wątkowania odpowiedzi

    Telegram obsługuje jawne tagi wątkowania odpowiedzi w wygenerowanym wyjściu:

    • [[reply_to_current]] odpowiada na wiadomość wyzwalającą
    • [[reply_to:<id>]] odpowiada na konkretny identyfikator wiadomości Telegram

    channels.telegram.replyToMode steruje obsługą:

    • off (domyślnie)
    • first
    • all

    Gdy wątkowanie odpowiedzi jest włączone, a oryginalny tekst lub podpis Telegram jest dostępny, OpenClaw automatycznie dołącza natywny fragment cytatu Telegram. Telegram ogranicza natywny tekst cytatu do 1024 jednostek kodu UTF-16, więc dłuższe wiadomości są cytowane od początku i wracają do zwykłej odpowiedzi, jeśli Telegram odrzuci cytat.

    Uwaga: off wyłącza niejawne wątkowanie odpowiedzi. Jawne tagi [[reply_to_*]] nadal są respektowane.

    Tematy forum i zachowanie wątków

    Supergrupy forum:

    • klucze sesji tematu dołączają :topic:<threadId>
    • odpowiedzi i pisanie są kierowane do wątku tematu
    • ścieżka konfiguracji tematu: channels.telegram.groups.<chatId>.topics.<threadId>

    Specjalny przypadek tematu ogólnego (threadId=1):

    • wysyłki wiadomości pomijają message_thread_id (Telegram odrzuca sendMessage(...thread_id=1))
    • akcje pisania nadal zawierają message_thread_id

    Dziedziczenie tematów: wpisy tematów dziedziczą ustawienia grupy, chyba że zostaną nadpisane (requireMention, allowFrom, skills, systemPrompt, enabled, groupPolicy). agentId jest tylko dla tematu i nie dziedziczy z domyślnych ustawień grupy.

    Routing agenta dla tematu: Każdy temat może kierować do innego agenta przez ustawienie agentId w konfiguracji tematu. Daje to każdemu tematowi własną izolowaną przestrzeń roboczą, pamięć i sesję. Przykład:

    {
      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
              }
            }
          }
        }
      }
    }
    

    Każdy temat ma wtedy własny klucz sesji: agent:zu:telegram:group:-1001234567890:topic:3

    Trwałe powiązanie tematu ACP: Tematy forum mogą przypinać sesje uprzęży ACP przez typowane powiązania ACP najwyższego poziomu (bindings[] z type: "acp" i match.channel: "telegram", peer.kind: "group" oraz identyfikatorem kwalifikowanym tematem, takim jak -1001234567890:topic:42). Obecnie ograniczone do tematów forum w grupach/supergrupach. Zobacz Agenci ACP.

    Uruchamianie ACP powiązane z wątkiem z czatu: /acp spawn <agent> --thread here|auto wiąże bieżący temat z nową sesją ACP; dalsze wiadomości są kierowane bezpośrednio tam. OpenClaw przypina potwierdzenie uruchomienia w temacie. Wymaga, aby channels.telegram.threadBindings.spawnSessions pozostało włączone (domyślnie: true).

    Kontekst szablonu udostępnia MessageThreadId i IsForum. Czaty DM z message_thread_id domyślnie zachowują trasowanie DM i metadane odpowiedzi w płaskich sesjach; używają kluczy sesji uwzględniających wątki tylko wtedy, gdy skonfigurowano threadReplies: "inbound", threadReplies: "always", requireTopic: true albo pasującą konfigurację tematu. Użyj najwyższego poziomu channels.telegram.dm.threadReplies jako domyślnego ustawienia konta albo direct.<chatId>.threadReplies dla jednego DM.

    Dźwięk, wideo i naklejki

    Wiadomości dźwiękowe

    Telegram rozróżnia notatki głosowe i pliki audio.

    • domyślnie: zachowanie pliku audio
    • tag [[audio_as_voice]] w odpowiedzi agenta wymusza wysłanie notatki głosowej
    • transkrypcje przychodzących notatek głosowych są ujmowane w kontekście agenta jako wygenerowany maszynowo, niezaufany tekst; wykrywanie wzmianek nadal używa surowej transkrypcji, więc wiadomości głosowe bramkowane wzmiankami nadal działają.

    Przykład akcji wiadomości:

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

    Wiadomości wideo

    Telegram rozróżnia pliki wideo i notatki wideo.

    Przykład akcji wiadomości:

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

    Notatki wideo nie obsługują podpisów; podany tekst wiadomości jest wysyłany osobno.

    Naklejki

    Obsługa przychodzących naklejek:

    • statyczne WEBP: pobierane i przetwarzane (placeholder <media:sticker>)
    • animowane TGS: pomijane
    • wideo WEBM: pomijane

    Pola kontekstu naklejki:

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

    Plik pamięci podręcznej naklejek:

    • ~/.openclaw/telegram/sticker-cache.json

    Naklejki są opisywane raz (gdy to możliwe) i buforowane, aby ograniczyć powtarzane wywołania wizji.

    Włącz akcje naklejek:

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

    Akcja wysłania naklejki:

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

    Wyszukaj naklejki w pamięci podręcznej:

    {
    action: "sticker-search",
    channel: "telegram",
    query: "cat waving",
    limit: 5,
    }
    
    Powiadomienia o reakcjach

    Reakcje Telegram przychodzą jako aktualizacje message_reaction (oddzielnie od ładunków wiadomości).

    Gdy są włączone, OpenClaw umieszcza w kolejce zdarzenia systemowe takie jak:

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

    Konfiguracja:

    • channels.telegram.reactionNotifications: off | own | all (domyślnie: own)
    • channels.telegram.reactionLevel: off | ack | minimal | extensive (domyślnie: minimal)

    Uwagi:

    • own oznacza tylko reakcje użytkowników na wiadomości wysłane przez bota (best-effort przez pamięć podręczną wysłanych wiadomości).
    • Zdarzenia reakcji nadal respektują kontrolę dostępu Telegram (dmPolicy, allowFrom, groupPolicy, groupAllowFrom); nieautoryzowani nadawcy są odrzucani.
    • Telegram nie podaje identyfikatorów wątków w aktualizacjach reakcji.
      • grupy bez forum są trasowane do sesji czatu grupowego
      • grupy forum są trasowane do sesji ogólnego tematu grupy (:topic:1), a nie do dokładnego tematu źródłowego

    allowed_updates dla odpytywania/Webhook automatycznie obejmuje message_reaction.

    Reakcje potwierdzenia

    ackReaction wysyła emoji potwierdzenia, gdy OpenClaw przetwarza przychodzącą wiadomość.

    Kolejność rozstrzygania:

    • channels.telegram.accounts.<accountId>.ackReaction
    • channels.telegram.ackReaction
    • messages.ackReaction
    • awaryjna emoji tożsamości agenta (agents.list[].identity.emoji, w przeciwnym razie "👀")

    Uwagi:

    • Telegram oczekuje emoji Unicode (na przykład "👀").
    • Użyj "", aby wyłączyć reakcję dla kanału lub konta.
    Zapisy konfiguracji ze zdarzeń i poleceń Telegram

    Zapisy konfiguracji kanału są domyślnie włączone (configWrites !== false).

    Zapisy wyzwalane przez Telegram obejmują:

    • zdarzenia migracji grup (migrate_to_chat_id) aktualizujące channels.telegram.groups
    • /config set i /config unset (wymaga włączenia poleceń)

    Wyłącz:

    {
    channels: {
    telegram: {
      configWrites: false,
    },
    },
    }
    
    Długie odpytywanie kontra Webhook

    Domyślnie używane jest długie odpytywanie. Dla trybu Webhook ustaw channels.telegram.webhookUrl i channels.telegram.webhookSecret; opcjonalnie webhookPath, webhookHost, webhookPort (domyślnie /telegram-webhook, 127.0.0.1, 8787).

    W trybie długiego odpytywania OpenClaw zapisuje swój znacznik wodny restartu dopiero po pomyślnym wysłaniu aktualizacji. Jeśli obsługa nie powiedzie się, ta aktualizacja pozostaje możliwa do ponowienia w tym samym procesie i nie jest zapisywana jako ukończona na potrzeby deduplikacji po restarcie.

    Lokalny listener wiąże się z 127.0.0.1:8787. Dla publicznego wejścia umieść odwrotne proxy przed lokalnym portem albo celowo ustaw webhookHost: "0.0.0.0".

    Tryb Webhook sprawdza zabezpieczenia żądania, tajny token Telegram i treść JSON przed zwróceniem 200 do Telegram. Następnie OpenClaw przetwarza aktualizację asynchronicznie przez te same pasy bota per czat/per temat, których używa długie odpytywanie, więc wolne tury agenta nie wstrzymują ACK dostarczenia Telegram.

    Limity, ponawianie i cele CLI
    • Domyślną wartością channels.telegram.textChunkLimit jest 4000.
    • channels.telegram.chunkMode="newline" preferuje granice akapitów (puste wiersze) przed dzieleniem według długości.
    • channels.telegram.mediaMaxMb (domyślnie 100) ogranicza rozmiar przychodzących i wychodzących mediów Telegram.
    • channels.telegram.mediaGroupFlushMs (domyślnie 500) kontroluje, jak długo albumy/grupy mediów Telegram są buforowane, zanim OpenClaw wyśle je jako jedną wiadomość przychodzącą. Zwiększ tę wartość, jeśli części albumu przychodzą późno; zmniejsz ją, aby ograniczyć opóźnienie odpowiedzi na album.
    • channels.telegram.timeoutSeconds nadpisuje limit czasu klienta API Telegram (jeśli nie ustawiono, obowiązuje domyślna wartość grammY). Klienci bota ograniczają skonfigurowane wartości poniżej 60-sekundowego zabezpieczenia żądań wychodzącego tekstu/pisania, aby grammY nie przerwało dostarczania widocznej odpowiedzi, zanim zabezpieczenie transportu OpenClaw i mechanizm awaryjny będą mogły się uruchomić. Długie odpytywanie nadal używa 45-sekundowego zabezpieczenia żądania getUpdates, aby bezczynne odpytywania nie były porzucane bezterminowo.
    • channels.telegram.pollingStallThresholdMs domyślnie wynosi 120000; dostrajaj w zakresie od 30000 do 600000 tylko w przypadku fałszywie dodatnich restartów z powodu zastoju odpytywania.
    • historia kontekstu grupy używa channels.telegram.historyLimit albo messages.groupChat.historyLimit (domyślnie 50); 0 wyłącza.
    • dodatkowy kontekst odpowiedzi/cytatu/przekazania jest obecnie przekazywany tak, jak został odebrany.
    • listy dozwolonych Telegram głównie ograniczają to, kto może wyzwolić agenta, a nie stanowią pełnej granicy redakcji dodatkowego kontekstu.
    • Kontrole historii DM:
      • channels.telegram.dmHistoryLimit
      • channels.telegram.dms["<user_id>"].historyLimit
    • Konfiguracja channels.telegram.retry dotyczy helperów wysyłania Telegram (CLI/narzędzia/akcje) dla możliwych do odzyskania błędów wychodzącego API. Dostarczanie końcowej odpowiedzi przychodzącej również używa ograniczonego ponowienia bezpiecznego wysyłania dla awarii Telegram przed połączeniem, ale nie ponawia niejednoznacznych kopert sieciowych po wysłaniu, które mogłyby zduplikować widoczne wiadomości.

    Cele wysyłania CLI i narzędzia wiadomości mogą być numerycznym ID czatu, nazwą użytkownika albo celem tematu forum:

    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"
    

    Ankiety Telegram używają openclaw message poll i obsługują tematy forum:

    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
    

    Flagi ankiet tylko dla Telegram:

    • --poll-duration-seconds (5-600)
    • --poll-anonymous
    • --poll-public
    • --thread-id dla tematów forum (albo użyj celu :topic:)

    Wysyłanie Telegram obsługuje też:

    • --presentation z blokami buttons dla klawiatur inline, gdy channels.telegram.capabilities.inlineButtons na to pozwala
    • --pin albo --delivery '{"pin":true}', aby zażądać przypiętego dostarczenia, gdy bot może przypinać w tym czacie
    • --force-document, aby wysyłać wychodzące obrazy i GIF-y jako dokumenty zamiast skompresowanych zdjęć lub przesyłanych animowanych mediów

    Bramkowanie akcji:

    • channels.telegram.actions.sendMessage=false wyłącza wychodzące wiadomości Telegram, w tym ankiety
    • channels.telegram.actions.poll=false wyłącza tworzenie ankiet Telegram, pozostawiając zwykłe wysyłki włączone
    Zatwierdzenia exec w Telegram

    Telegram obsługuje zatwierdzenia exec w DM osób zatwierdzających i może opcjonalnie publikować prompty w czacie lub temacie źródłowym. Osoby zatwierdzające muszą być numerycznymi identyfikatorami użytkowników Telegram.

    Ścieżka konfiguracji:

    • channels.telegram.execApprovals.enabled (włącza się automatycznie, gdy co najmniej jedna osoba zatwierdzająca jest możliwa do rozstrzygnięcia)
    • channels.telegram.execApprovals.approvers (awaryjnie używa numerycznych ID właścicieli z commands.ownerAllowFrom)
    • channels.telegram.execApprovals.target: dm (domyślnie) | channel | both
    • agentFilter, sessionFilter

    channels.telegram.allowFrom, groupAllowFrom i defaultTo kontrolują, kto może rozmawiać z botem i dokąd wysyła on zwykłe odpowiedzi. Nie czynią one nikogo osobą zatwierdzającą exec. Pierwsze zatwierdzone parowanie DM inicjuje commands.ownerAllowFrom, gdy nie istnieje jeszcze właściciel poleceń, więc konfiguracja z jednym właścicielem nadal działa bez duplikowania ID w execApprovals.approvers.

    Dostarczenie do kanału pokazuje tekst polecenia na czacie; włączaj channel albo both tylko w zaufanych grupach/tematach. Gdy prompt trafia do tematu forum, OpenClaw zachowuje temat dla promptu zatwierdzenia i dalszej odpowiedzi. Zatwierdzenia exec domyślnie wygasają po 30 minutach.

    Przyciski zatwierdzania inline również wymagają, aby channels.telegram.capabilities.inlineButtons dopuszczało docelową powierzchnię (dm, group lub all). ID zatwierdzeń z prefiksem plugin: są rozstrzygane przez zatwierdzenia Plugin; pozostałe są najpierw rozstrzygane przez zatwierdzenia exec.

    Zobacz Zatwierdzenia exec.

    Kontrole odpowiedzi o błędach

    Gdy agent napotka błąd dostarczenia lub dostawcy, Telegram może odpowiedzieć tekstem błędu albo go ukryć. To zachowanie kontrolują dwa klucze konfiguracji:

    Klucz Wartości Domyślnie Opis
    channels.telegram.errorPolicy reply, silent reply reply wysyła przyjazną wiadomość o błędzie do czatu. silent całkowicie ukrywa odpowiedzi o błędach.
    channels.telegram.errorCooldownMs liczba (ms) 60000 Minimalny czas między odpowiedziami o błędach do tego samego czatu. Zapobiega spamowi błędów podczas awarii.

    Obsługiwane są nadpisania per konto, per grupa i per temat (takie samo dziedziczenie jak dla innych kluczy konfiguracji Telegram).

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

    Rozwiązywanie problemów

    Bot nie odpowiada na wiadomości grupowe bez wzmianki
    • Jeśli requireMention=false, tryb prywatności Telegram musi umożliwiać pełną widoczność.
      • BotFather: /setprivacy -> Disable
      • następnie usuń bota z grupy i dodaj go ponownie
    • openclaw channels status ostrzega, gdy konfiguracja oczekuje niewzmiankowanych wiadomości grupowych.
    • openclaw channels status --probe może sprawdzać jawne numeryczne identyfikatory grup; wildcard "*" nie może być sprawdzony pod kątem członkostwa.
    • szybki test sesji: /activation always.
    Bot not seeing group messages at all
    • gdy istnieje channels.telegram.groups, grupa musi być wymieniona (lub zawierać "*")
    • zweryfikuj członkostwo bota w grupie
    • przejrzyj logi: openclaw logs --follow, aby znaleźć powody pominięcia
    Commands work partially or not at all
    • autoryzuj tożsamość nadawcy (parowanie i/lub numeryczne allowFrom)
    • autoryzacja poleceń nadal obowiązuje, nawet gdy polityka grupy to open
    • setMyCommands failed z BOT_COMMANDS_TOO_MUCH oznacza, że menu natywne ma zbyt wiele pozycji; ogranicz polecenia pluginów/Skills/niestandardowe albo wyłącz menu natywne
    • wywołania startowe deleteMyCommands / setMyCommands oraz wywołania wpisywania sendChatAction są ograniczone czasowo i ponawiane raz przez transport awaryjny Telegram w przypadku przekroczenia limitu czasu żądania. Utrzymujące się błędy sieciowe/fetch zwykle wskazują problemy z osiągalnością DNS/HTTPS do api.telegram.org
    Startup reports unauthorized token
    • getMe returned 401 to błąd uwierzytelniania Telegram dla skonfigurowanego tokenu bota.
    • Skopiuj ponownie albo wygeneruj ponownie token bota w BotFather, a następnie zaktualizuj channels.telegram.botToken, channels.telegram.tokenFile, channels.telegram.accounts.<id>.botToken albo TELEGRAM_BOT_TOKEN dla domyślnego konta.
    • deleteWebhook 401 Unauthorized podczas uruchamiania również jest błędem uwierzytelniania; traktowanie tego jako „brak Webhooka” tylko odroczyłoby ten sam błąd nieprawidłowego tokenu do późniejszych wywołań API.
    Polling or network instability
    • Node 22+ + niestandardowy fetch/proxy może wywoływać natychmiastowe anulowanie, jeśli typy AbortSignal są niezgodne.
    • Niektóre hosty najpierw rozwiązują api.telegram.org na IPv6; niedziałający wychodzący IPv6 może powodować sporadyczne błędy API Telegram.
    • Jeśli logi zawierają TypeError: fetch failed albo Network request for 'getUpdates' failed!, OpenClaw ponawia je teraz jako możliwe do odzyskania błędy sieciowe.
    • Podczas uruchamiania odpytywania OpenClaw ponownie używa udanego startowego sprawdzenia getMe dla grammY, aby runner nie potrzebował drugiego getMe przed pierwszym getUpdates.
    • Jeśli deleteWebhook zakończy się przejściowym błędem sieciowym podczas uruchamiania odpytywania, OpenClaw przechodzi do long pollingu zamiast wykonywać kolejne przedodpytywaniowe wywołanie płaszczyzny sterowania. Nadal aktywny Webhook ujawnia się jako konflikt getUpdates; OpenClaw przebudowuje wtedy transport Telegram i ponawia czyszczenie Webhooka.
    • Jeśli gniazda Telegram są odnawiane w krótkim, stałym rytmie, sprawdź, czy channels.telegram.timeoutSeconds nie ma niskiej wartości; klienci botów ograniczają skonfigurowane wartości poniżej zabezpieczeń żądań wychodzących i getUpdates, ale starsze wydania mogły przerywać każde odpytywanie lub odpowiedź, gdy ta wartość była ustawiona poniżej tych zabezpieczeń.
    • Jeśli logi zawierają Polling stall detected, OpenClaw domyślnie uruchamia ponownie odpytywanie i przebudowuje transport Telegram po 120 sekundach bez ukończonego sprawdzenia żywotności long pollingu.
    • openclaw channels status --probe i openclaw doctor ostrzegają, gdy działające konto odpytywania nie ukończyło getUpdates po okresie rozruchowym, gdy działające konto Webhooka nie ukończyło setWebhook po okresie rozruchowym albo gdy ostatnia udana aktywność transportu odpytywania jest nieaktualna.
    • Zwiększ channels.telegram.pollingStallThresholdMs tylko wtedy, gdy długo działające wywołania getUpdates są zdrowe, ale host nadal zgłasza fałszywe ponowne uruchomienia z powodu zastoju odpytywania. Utrzymujące się zastoje zwykle wskazują problemy z proxy, DNS, IPv6 albo wychodzącym TLS między hostem a api.telegram.org.
    • Telegram honoruje również zmienne środowiskowe proxy procesu dla transportu Bot API, w tym HTTP_PROXY, HTTPS_PROXY, ALL_PROXY oraz ich warianty pisane małymi literami. NO_PROXY / no_proxy nadal może omijać api.telegram.org.
    • Jeśli zarządzane proxy OpenClaw jest skonfigurowane przez OPENCLAW_PROXY_URL dla środowiska usługi i nie ma standardowej zmiennej środowiskowej proxy, Telegram używa tego URL-a również dla transportu Bot API.
    • Na hostach VPS z niestabilnym bezpośrednim ruchem wychodzącym/TLS kieruj wywołania API Telegram przez channels.telegram.proxy:
    channels:
    telegram:
    proxy: socks5://<user>:<password>@proxy-host:1080
    
    • Node 22+ domyślnie używa autoSelectFamily=true (z wyjątkiem WSL2). Kolejność wyników DNS Telegram respektuje OPENCLAW_TELEGRAM_DNS_RESULT_ORDER, następnie channels.telegram.network.dnsResultOrder, następnie domyślne ustawienie procesu, takie jak NODE_OPTIONS=--dns-result-order=ipv4first; jeśli żadne nie ma zastosowania, Node 22+ wraca do ipv4first.
    • Jeśli Twój host to WSL2 albo jawnie działa lepiej przy zachowaniu tylko IPv4, wymuś wybór rodziny:
    channels:
    telegram:
    network:
      autoSelectFamily: false
    
    • Odpowiedzi z zakresu benchmarkowego RFC 2544 (198.18.0.0/15) są już domyślnie dozwolone dla pobierania multimediów Telegram. Jeśli zaufane fake-IP albo przezroczyste proxy przepisuje api.telegram.org na inny prywatny/wewnętrzny/specjalnego użycia adres podczas pobierania multimediów, możesz włączyć obejście tylko dla Telegram:
    channels:
    telegram:
    network:
      dangerouslyAllowPrivateNetwork: true
    
    • To samo ustawienie dobrowolne jest dostępne dla konta pod channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork.
    • Jeśli Twoje proxy rozwiązuje hosty multimediów Telegram na 198.18.x.x, najpierw pozostaw niebezpieczną flagę wyłączoną. Multimedia Telegram już domyślnie dopuszczają zakres benchmarkowy RFC 2544.
    • Nadpisania środowiskowe (tymczasowe):
      • OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1
      • OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1
      • OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first
    • Zweryfikuj odpowiedzi DNS:
    dig +short api.telegram.org A
    dig +short api.telegram.org AAAA
    

    Więcej pomocy: Rozwiązywanie problemów z kanałami.

    Dokumentacja konfiguracji

    Główna dokumentacja: Dokumentacja konfiguracji - Telegram.

    High-signal Telegram fields
    • uruchamianie/uwierzytelnianie: enabled, botToken, tokenFile, accounts.* (tokenFile musi wskazywać zwykły plik; dowiązania symboliczne są odrzucane)
    • kontrola dostępu: dmPolicy, allowFrom, groupPolicy, groupAllowFrom, groups, groups.*.topics.*, najwyższego poziomu bindings[] (type: "acp")
    • zatwierdzenia wykonywania: execApprovals, accounts.*.execApprovals
    • polecenie/menu: commands.native, commands.nativeSkills, customCommands
    • wątki/odpowiedzi: replyToMode, dm.threadReplies, direct.*.threadReplies
    • strumieniowanie: streaming (podgląd), streaming.preview.toolProgress, blockStreaming
    • formatowanie/dostarczanie: textChunkLimit, chunkMode, linkPreview, responsePrefix
    • multimedia/sieć: mediaMaxMb, mediaGroupFlushMs, timeoutSeconds, pollingStallThresholdMs, retry, network.autoSelectFamily, network.dangerouslyAllowPrivateNetwork, proxy
    • niestandardowy korzeń API: apiRoot (tylko korzeń Bot API; nie dołączaj /bot&lt;TOKEN&gt;)
    • Webhook: webhookUrl, webhookSecret, webhookPath, webhookHost
    • akcje/możliwości: capabilities.inlineButtons, actions.sendMessage|editMessage|deleteMessage|reactions|sticker
    • reakcje: reactionNotifications, reactionLevel
    • błędy: errorPolicy, errorCooldownMs
    • zapisy/historia: configWrites, historyLimit, dmHistoryLimit, dms.*.historyLimit

    Powiązane