Mainstream messaging

Telegram

Siap produksi untuk DM dan grup bot melalui grammY. Long polling adalah mode default; mode webhook bersifat opsional.

Penyiapan cepat

  • Create the bot token in BotFather

    Buka Telegram dan chat dengan @BotFather (pastikan handle persis @BotFather).

    Jalankan /newbot, ikuti prompt, dan simpan token.

  • Configure token and DM policy

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

    Fallback env: TELEGRAM_BOT_TOKEN=... (hanya akun default). Telegram tidak menggunakan openclaw channels login telegram; konfigurasikan token di config/env, lalu mulai gateway.

  • Start gateway and approve first DM

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

    Kode pairing kedaluwarsa setelah 1 jam.

  • Add the bot to a group

    Tambahkan bot ke grup Anda, lalu atur channels.telegram.groups dan groupPolicy agar cocok dengan model akses Anda.

  • Pengaturan sisi Telegram

    Privacy mode and group visibility

    Bot Telegram secara default menggunakan Privacy Mode, yang membatasi pesan grup yang mereka terima.

    Jika bot harus melihat semua pesan grup, lakukan salah satu:

    • nonaktifkan mode privasi melalui /setprivacy, atau
    • jadikan bot admin grup.

    Saat mengubah mode privasi, hapus + tambahkan ulang bot di setiap grup agar Telegram menerapkan perubahan.

    Group permissions

    Status admin dikendalikan di pengaturan grup Telegram.

    Bot admin menerima semua pesan grup, yang berguna untuk perilaku grup yang selalu aktif.

    Helpful BotFather toggles
    • /setjoingroups untuk mengizinkan/menolak penambahan ke grup
    • /setprivacy untuk perilaku visibilitas grup

    Kontrol akses dan aktivasi

    DM policy

    channels.telegram.dmPolicy mengontrol akses pesan langsung:

    • pairing (default)
    • allowlist (memerlukan setidaknya satu ID pengirim di allowFrom)
    • open (memerlukan allowFrom menyertakan "*")
    • disabled

    dmPolicy: "open" dengan allowFrom: ["*"] memungkinkan akun Telegram mana pun yang menemukan atau menebak nama pengguna bot untuk memerintah bot. Gunakan hanya untuk bot yang sengaja dibuat publik dengan tool yang sangat dibatasi; bot satu pemilik sebaiknya menggunakan allowlist dengan ID pengguna numerik.

    channels.telegram.allowFrom menerima ID pengguna Telegram numerik. Prefiks telegram: / tg: diterima dan dinormalisasi. Dalam config multi-akun, channels.telegram.allowFrom tingkat atas yang restriktif diperlakukan sebagai batas keamanan: entri tingkat akun allowFrom: ["*"] tidak membuat akun tersebut publik kecuali allowlist akun efektif masih berisi wildcard eksplisit setelah penggabungan. dmPolicy: "allowlist" dengan allowFrom kosong memblokir semua DM dan ditolak oleh validasi config. Penyiapan hanya meminta ID pengguna numerik. Jika Anda meningkatkan versi dan config Anda berisi entri allowlist @username, jalankan openclaw doctor --fix untuk menyelesaikannya (upaya terbaik; memerlukan token bot Telegram). Jika sebelumnya Anda mengandalkan file allowlist pairing-store, openclaw doctor --fix dapat memulihkan entri ke channels.telegram.allowFrom dalam alur allowlist (misalnya saat dmPolicy: "allowlist" belum memiliki ID eksplisit).

    Untuk bot satu pemilik, pilih dmPolicy: "allowlist" dengan ID allowFrom numerik eksplisit agar kebijakan akses tahan lama di config (bukan bergantung pada persetujuan pairing sebelumnya).

    Kebingungan umum: persetujuan pairing DM tidak berarti "pengirim ini diotorisasi di mana saja". Pairing memberikan akses DM. Jika belum ada pemilik perintah, pairing pertama yang disetujui juga menetapkan commands.ownerAllowFrom sehingga perintah khusus pemilik dan persetujuan exec memiliki akun operator eksplisit. Otorisasi pengirim grup tetap berasal dari allowlist config eksplisit. Jika Anda ingin "Saya diotorisasi sekali dan DM maupun perintah grup berfungsi", masukkan ID pengguna Telegram numerik Anda di channels.telegram.allowFrom; untuk perintah khusus pemilik, pastikan commands.ownerAllowFrom berisi telegram:<your user id>.

    Menemukan ID pengguna Telegram Anda

    Lebih aman (tanpa bot pihak ketiga):

    1. DM bot Anda.
    2. Jalankan openclaw logs --follow.
    3. Baca from.id.

    Metode Bot API resmi:

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

    Metode pihak ketiga (kurang privat): @userinfobot atau @getidsbot.

    Group policy and allowlists

    Dua kontrol berlaku bersama:

    1. Grup mana yang diizinkan (channels.telegram.groups)

      • tanpa config groups:
        • dengan groupPolicy: "open": grup mana pun dapat lolos pemeriksaan ID grup
        • dengan groupPolicy: "allowlist" (default): grup diblokir sampai Anda menambahkan entri groups (atau "*")
      • groups dikonfigurasi: bertindak sebagai allowlist (ID eksplisit atau "*")
    2. Pengirim mana yang diizinkan di grup (channels.telegram.groupPolicy)

      • open
      • allowlist (default)
      • disabled

    groupAllowFrom digunakan untuk pemfilteran pengirim grup. Jika tidak diatur, Telegram fallback ke allowFrom. Entri groupAllowFrom harus berupa ID pengguna Telegram numerik (prefiks telegram: / tg: dinormalisasi). Jangan masukkan ID chat grup atau supergroup Telegram di groupAllowFrom. ID chat negatif berada di bawah channels.telegram.groups. Entri non-numerik diabaikan untuk otorisasi pengirim. Batas keamanan (2026.2.25+): auth pengirim grup tidak mewarisi persetujuan pairing-store DM. Pairing tetap hanya DM. Untuk grup, atur groupAllowFrom atau allowFrom per grup/per topik. Jika groupAllowFrom tidak diatur, Telegram fallback ke config allowFrom, bukan pairing store. Pola praktis untuk bot satu pemilik: atur ID pengguna Anda di channels.telegram.allowFrom, biarkan groupAllowFrom tidak diatur, dan izinkan grup target di bawah channels.telegram.groups. Catatan runtime: jika channels.telegram sepenuhnya tidak ada, runtime default ke groupPolicy="allowlist" yang fail-closed kecuali channels.defaults.groupPolicy diatur secara eksplisit.

    Contoh: izinkan anggota mana pun di satu grup tertentu:

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

    Contoh: izinkan hanya pengguna tertentu di dalam satu grup tertentu:

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

    Mention behavior

    Balasan grup memerlukan mention secara default.

    Mention dapat berasal dari:

    • mention native @botusername, atau
    • pola mention di:
      • agents.list[].groupChat.mentionPatterns
      • messages.groupChat.mentionPatterns

    Toggle perintah tingkat sesi:

    • /activation always
    • /activation mention

    Ini hanya memperbarui status sesi. Gunakan config untuk persistensi.

    Contoh config persisten:

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

    Mendapatkan ID chat grup:

    • teruskan pesan grup ke @userinfobot / @getidsbot
    • atau baca chat.id dari openclaw logs --follow
    • atau periksa Bot API getUpdates

    Perilaku runtime

    • Telegram dimiliki oleh proses gateway.
    • Routing deterministik: inbound Telegram membalas kembali ke Telegram (model tidak memilih kanal).
    • Pesan inbound dinormalisasi ke envelope kanal bersama dengan metadata balasan dan placeholder media.
    • Sesi grup diisolasi berdasarkan ID grup. Topik forum menambahkan :topic:<threadId> agar topik tetap terisolasi.
    • Pesan DM dapat membawa message_thread_id; OpenClaw mempertahankan ID thread untuk balasan tetapi mempertahankan DM pada sesi datar secara default. Konfigurasikan channels.telegram.dm.threadReplies: "inbound", channels.telegram.direct.<chatId>.threadReplies: "inbound", requireTopic: true, atau config topik yang cocok saat Anda sengaja menginginkan isolasi sesi topik DM.
    • Long polling menggunakan runner grammY dengan pengurutan per chat/per thread. Konkurensi sink runner keseluruhan menggunakan agents.defaults.maxConcurrent.
    • Long polling dijaga di dalam setiap proses gateway sehingga hanya satu poller aktif yang dapat menggunakan token bot pada satu waktu. Jika Anda masih melihat konflik getUpdates 409, gateway OpenClaw lain, script, atau poller eksternal kemungkinan menggunakan token yang sama.
    • Mulai ulang watchdog long-polling dipicu setelah 120 detik tanpa liveness getUpdates yang selesai secara default. Tingkatkan channels.telegram.pollingStallThresholdMs hanya jika deployment Anda masih melihat mulai ulang polling-stall palsu selama pekerjaan berjalan lama. Nilainya dalam milidetik dan diizinkan dari 30000 hingga 600000; override per akun didukung.
    • Telegram Bot API tidak memiliki dukungan tanda dibaca (sendReadReceipts tidak berlaku).

    Referensi fitur

    Live stream preview (message edits)

    OpenClaw dapat melakukan streaming balasan parsial secara real time:

    • chat langsung: pesan pratinjau + editMessageText
    • grup/topik: pesan pratinjau + editMessageText

    Persyaratan:

    • channels.telegram.streaming adalah off | partial | block | progress (default: partial)
    • progress mempertahankan satu draft status yang dapat diedit untuk progres tool, menghapusnya saat selesai, dan mengirim jawaban final sebagai pesan normal
    • streaming.preview.toolProgress mengontrol apakah pembaruan tool/progres menggunakan ulang pesan pratinjau yang sama yang diedit (default: true saat streaming pratinjau aktif)
    • streaming.preview.commandText mengontrol detail perintah/exec di dalam baris progres tool tersebut: raw (default, mempertahankan perilaku yang dirilis) atau status (hanya label tool)
    • channels.telegram.streamMode legacy dan nilai boolean streaming terdeteksi; jalankan openclaw doctor --fix untuk memigrasikannya ke channels.telegram.streaming.mode

    Pembaruan pratinjau progres tool adalah baris status singkat yang ditampilkan saat tool berjalan, misalnya eksekusi perintah, pembacaan file, pembaruan perencanaan, atau ringkasan patch. Telegram mengaktifkannya secara default agar cocok dengan perilaku OpenClaw yang dirilis dari v2026.4.22 dan setelahnya. Untuk mempertahankan pratinjau yang diedit untuk teks jawaban tetapi menyembunyikan baris progres tool, atur:

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

    Untuk mempertahankan progres tool terlihat tetapi menyembunyikan teks perintah/exec, atur:

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

    Gunakan mode progress saat Anda menginginkan progres alat yang terlihat tanpa mengedit jawaban akhir ke dalam pesan yang sama. Letakkan kebijakan teks perintah di bawah streaming.progress:

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

    Gunakan streaming.mode: "off" hanya saat Anda menginginkan pengiriman khusus akhir: edit pratinjau Telegram dinonaktifkan dan obrolan alat/progres generik ditekan alih-alih dikirim sebagai pesan status mandiri. Prompt persetujuan, payload media, dan kesalahan tetap dirutekan melalui pengiriman akhir normal. Gunakan streaming.preview.toolProgress: false saat Anda hanya ingin mempertahankan edit pratinjau jawaban sambil menyembunyikan baris status progres alat.

    Untuk balasan teks saja:

    • pratinjau DM/grup/topik pendek: OpenClaw mempertahankan pesan pratinjau yang sama dan melakukan edit akhir di tempat
    • akhir teks panjang yang dipecah menjadi beberapa pesan Telegram menggunakan kembali pratinjau yang ada sebagai potongan akhir pertama jika memungkinkan, lalu hanya mengirim potongan yang tersisa
    • akhir mode progres menghapus draf status dan menggunakan pengiriman akhir normal alih-alih mengedit draf menjadi jawaban
    • jika edit akhir gagal sebelum teks lengkap dikonfirmasi, OpenClaw menggunakan pengiriman akhir normal dan membersihkan pratinjau yang usang

    Untuk balasan kompleks (misalnya payload media), OpenClaw kembali ke pengiriman akhir normal lalu membersihkan pesan pratinjau.

    Streaming pratinjau terpisah dari streaming blok. Saat streaming blok diaktifkan secara eksplisit untuk Telegram, OpenClaw melewati stream pratinjau untuk menghindari streaming ganda.

    Stream penalaran khusus Telegram:

    • /reasoning stream mengirim penalaran ke pratinjau langsung saat membuat
    • pratinjau penalaran dihapus setelah pengiriman akhir; gunakan /reasoning on saat penalaran harus tetap terlihat
    • jawaban akhir dikirim tanpa teks penalaran
    Pemformatan dan fallback HTML

    Teks keluar menggunakan Telegram parse_mode: "HTML".

    • Teks mirip Markdown dirender menjadi HTML yang aman untuk Telegram.
    • HTML model mentah di-escape untuk mengurangi kegagalan parse Telegram.
    • Jika Telegram menolak HTML yang di-parse, OpenClaw mencoba ulang sebagai teks biasa.

    Pratinjau tautan diaktifkan secara default dan dapat dinonaktifkan dengan channels.telegram.linkPreview: false.

    Perintah native dan perintah khusus

    Pendaftaran menu perintah Telegram ditangani saat startup dengan setMyCommands.

    Default perintah native:

    • commands.native: "auto" mengaktifkan perintah native untuk Telegram

    Tambahkan entri menu perintah khusus:

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

    Aturan:

    • nama dinormalisasi (menghapus / di awal, huruf kecil)
    • pola valid: a-z, 0-9, _, panjang 1..32
    • perintah khusus tidak dapat menimpa perintah native
    • konflik/duplikat dilewati dan dicatat

    Catatan:

    • perintah khusus hanya entri menu; perintah tersebut tidak mengimplementasikan perilaku secara otomatis
    • perintah plugin/skill tetap dapat berfungsi saat diketik meskipun tidak ditampilkan di menu Telegram

    Jika perintah native dinonaktifkan, bawaan dihapus. Perintah khusus/plugin tetap dapat mendaftar jika dikonfigurasi.

    Kegagalan penyiapan umum:

    • setMyCommands failed dengan BOT_COMMANDS_TOO_MUCH berarti menu Telegram masih melampaui batas setelah dipangkas; kurangi perintah plugin/skill/khusus atau nonaktifkan channels.telegram.commands.native.
    • deleteWebhook, deleteMyCommands, atau setMyCommands gagal dengan 404: Not Found sementara perintah curl Bot API langsung berfungsi dapat berarti channels.telegram.apiRoot disetel ke endpoint /bot&lt;TOKEN&gt; lengkap. apiRoot harus hanya berupa root Bot API, dan openclaw doctor --fix menghapus /bot&lt;TOKEN&gt; yang tidak sengaja berada di akhir.
    • getMe returned 401 berarti Telegram menolak token bot yang dikonfigurasi. Perbarui botToken, tokenFile, atau TELEGRAM_BOT_TOKEN dengan token BotFather saat ini; OpenClaw berhenti sebelum polling sehingga ini tidak dilaporkan sebagai kegagalan pembersihan webhook.
    • setMyCommands failed dengan kesalahan jaringan/fetch biasanya berarti DNS/HTTPS keluar ke api.telegram.org diblokir.

    Perintah pemasangan perangkat (plugin device-pair)

    Saat plugin device-pair diinstal:

    1. /pair menghasilkan kode penyiapan
    2. tempel kode di aplikasi iOS
    3. /pair pending mencantumkan permintaan tertunda (termasuk peran/cakupan)
    4. setujui permintaan:
      • /pair approve <requestId> untuk persetujuan eksplisit
      • /pair approve saat hanya ada satu permintaan tertunda
      • /pair approve latest untuk yang terbaru

    Kode penyiapan membawa token bootstrap berumur pendek. Serah terima bootstrap bawaan mempertahankan token node utama di scopes: []; token operator apa pun yang diserahterimakan tetap dibatasi pada operator.approvals, operator.read, operator.talk.secrets, dan operator.write. Pemeriksaan cakupan bootstrap menggunakan prefiks peran, sehingga allowlist operator tersebut hanya memenuhi permintaan operator; peran non-operator tetap memerlukan cakupan di bawah prefiks perannya sendiri.

    Jika perangkat mencoba ulang dengan detail autentikasi yang berubah (misalnya peran/cakupan/kunci publik), permintaan tertunda sebelumnya digantikan dan permintaan baru menggunakan requestId yang berbeda. Jalankan ulang /pair pending sebelum menyetujui.

    Detail selengkapnya: Pemasangan.

    Tombol inline

    Konfigurasikan cakupan keyboard inline:

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

    Override per akun:

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

    Cakupan:

    • off
    • dm
    • group
    • all
    • allowlist (default)

    capabilities: ["inlineButtons"] lama dipetakan ke inlineButtons: "all".

    Contoh tindakan pesan:

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

    Klik callback diteruskan ke agen sebagai teks: callback_data: <value>

    Tindakan pesan Telegram untuk agen dan otomatisasi

    Tindakan alat Telegram mencakup:

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

    Tindakan pesan channel mengekspos alias ergonomis (send, react, delete, edit, sticker, sticker-search, topic-create).

    Kontrol gating:

    • channels.telegram.actions.sendMessage
    • channels.telegram.actions.deleteMessage
    • channels.telegram.actions.reactions
    • channels.telegram.actions.sticker (default: dinonaktifkan)

    Catatan: edit dan topic-create saat ini diaktifkan secara default dan tidak memiliki toggle channels.telegram.actions.* terpisah. Pengiriman runtime menggunakan snapshot konfigurasi/rahasia aktif (startup/reload), sehingga jalur tindakan tidak melakukan resolusi ulang SecretRef ad hoc per pengiriman.

    Semantik penghapusan reaksi: /tools/reactions

    Tag threading balasan

    Telegram mendukung tag threading balasan eksplisit dalam output yang dihasilkan:

    • [[reply_to_current]] membalas pesan pemicu
    • [[reply_to:<id>]] membalas ID pesan Telegram tertentu

    channels.telegram.replyToMode mengontrol penanganan:

    • off (default)
    • first
    • all

    Saat threading balasan diaktifkan dan teks atau caption Telegram asli tersedia, OpenClaw menyertakan kutipan native Telegram secara otomatis. Telegram membatasi teks kutipan native pada 1024 unit kode UTF-16, sehingga pesan yang lebih panjang dikutip dari awal dan kembali ke balasan biasa jika Telegram menolak kutipan.

    Catatan: off menonaktifkan threading balasan implisit. Tag [[reply_to_*]] eksplisit tetap dihormati.

    Topik forum dan perilaku thread

    Supergrup forum:

    • kunci sesi topik menambahkan :topic:<threadId>
    • balasan dan pengetikan menargetkan thread topik
    • jalur konfigurasi topik: channels.telegram.groups.<chatId>.topics.<threadId>

    Kasus khusus topik umum (threadId=1):

    • pengiriman pesan menghilangkan message_thread_id (Telegram menolak sendMessage(...thread_id=1))
    • tindakan pengetikan tetap menyertakan message_thread_id

    Pewarisan topik: entri topik mewarisi pengaturan grup kecuali dioverride (requireMention, allowFrom, skills, systemPrompt, enabled, groupPolicy). agentId hanya untuk topik dan tidak mewarisi dari default grup.

    Perutean agen per topik: Setiap topik dapat dirutekan ke agen berbeda dengan mengatur agentId dalam konfigurasi topik. Ini memberi setiap topik workspace, memori, dan sesi terisolasi miliknya sendiri. Contoh:

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

    Setiap topik kemudian memiliki kunci sesinya sendiri: agent:zu:telegram:group:-1001234567890:topic:3

    Pengikatan topik ACP persisten: Topik forum dapat menyematkan sesi harness ACP melalui pengikatan ACP bertipe tingkat atas (bindings[] dengan type: "acp" dan match.channel: "telegram", peer.kind: "group", serta id yang memenuhi syarat topik seperti -1001234567890:topic:42). Saat ini dicakupkan ke topik forum dalam grup/supergrup. Lihat Agen ACP.

    Spawn ACP terikat thread dari chat: /acp spawn <agent> --thread here|auto mengikat topik saat ini ke sesi ACP baru; tindak lanjut dirutekan langsung ke sana. OpenClaw menyematkan konfirmasi spawn dalam topik. Memerlukan channels.telegram.threadBindings.spawnSessions tetap diaktifkan (default: true).

    Konteks templat mengekspos MessageThreadId dan IsForum. Obrolan DM dengan message_thread_id mempertahankan metadata perutean DM dan balasan pada sesi datar secara bawaan; obrolan tersebut hanya menggunakan kunci sesi yang sadar thread saat dikonfigurasi dengan threadReplies: "inbound", threadReplies: "always", requireTopic: true, atau konfigurasi topik yang cocok. Gunakan channels.telegram.dm.threadReplies tingkat atas untuk bawaan akun, atau direct.<chatId>.threadReplies untuk satu DM.

    Audio, video, dan stiker

    Pesan audio

    Telegram membedakan catatan suara dan file audio.

    • bawaan: perilaku file audio
    • tag [[audio_as_voice]] dalam balasan agen untuk memaksa pengiriman catatan suara
    • transkrip catatan suara masuk dibingkai sebagai teks buatan mesin yang tidak tepercaya dalam konteks agen; deteksi mention tetap menggunakan transkrip mentah sehingga pesan suara yang dibatasi mention tetap berfungsi.

    Contoh tindakan pesan:

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

    Pesan video

    Telegram membedakan file video dan catatan video.

    Contoh tindakan pesan:

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

    Catatan video tidak mendukung caption; teks pesan yang diberikan dikirim secara terpisah.

    Stiker

    Penanganan stiker masuk:

    • WEBP statis: diunduh dan diproses (placeholder <media:sticker>)
    • TGS animasi: dilewati
    • WEBM video: dilewati

    Bidang konteks stiker:

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

    File cache stiker:

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

    Stiker dideskripsikan sekali (jika memungkinkan) dan di-cache untuk mengurangi panggilan vision berulang.

    Aktifkan tindakan stiker:

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

    Tindakan kirim stiker:

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

    Cari stiker yang di-cache:

    {
    action: "sticker-search",
    channel: "telegram",
    query: "cat waving",
    limit: 5,
    }
    
    Notifikasi reaksi

    Reaksi Telegram tiba sebagai pembaruan message_reaction (terpisah dari payload pesan).

    Saat diaktifkan, OpenClaw mengantrekan peristiwa sistem seperti:

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

    Konfigurasi:

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

    Catatan:

    • own berarti hanya reaksi pengguna terhadap pesan yang dikirim bot (upaya terbaik melalui cache pesan terkirim).
    • Peristiwa reaksi tetap mematuhi kontrol akses Telegram (dmPolicy, allowFrom, groupPolicy, groupAllowFrom); pengirim yang tidak sah dibuang.
    • Telegram tidak menyediakan ID thread dalam pembaruan reaksi.
      • grup non-forum dirutekan ke sesi obrolan grup
      • grup forum dirutekan ke sesi topik umum grup (:topic:1), bukan ke topik asal yang persis

    allowed_updates untuk polling/Webhook menyertakan message_reaction secara otomatis.

    Reaksi ack

    ackReaction mengirim emoji pengakuan saat OpenClaw memproses pesan masuk.

    Urutan resolusi:

    • channels.telegram.accounts.<accountId>.ackReaction
    • channels.telegram.ackReaction
    • messages.ackReaction
    • fallback emoji identitas agen (agents.list[].identity.emoji, jika tidak ada "👀")

    Catatan:

    • Telegram mengharapkan emoji unicode (misalnya "👀").
    • Gunakan "" untuk menonaktifkan reaksi bagi channel atau akun.
    Penulisan konfigurasi dari peristiwa dan perintah Telegram

    Penulisan konfigurasi channel diaktifkan secara bawaan (configWrites !== false).

    Penulisan yang dipicu Telegram mencakup:

    • peristiwa migrasi grup (migrate_to_chat_id) untuk memperbarui channels.telegram.groups
    • /config set dan /config unset (memerlukan pengaktifan perintah)

    Nonaktifkan:

    {
    channels: {
    telegram: {
      configWrites: false,
    },
    },
    }
    
    Long polling vs Webhook

    Bawaannya adalah long polling. Untuk mode Webhook, tetapkan channels.telegram.webhookUrl dan channels.telegram.webhookSecret; opsional webhookPath, webhookHost, webhookPort (bawaan /telegram-webhook, 127.0.0.1, 8787).

    Dalam mode long polling, OpenClaw mempertahankan watermark mulai ulangnya hanya setelah sebuah pembaruan berhasil dikirimkan. Jika handler gagal, pembaruan tersebut tetap dapat dicoba ulang dalam proses yang sama dan tidak ditulis sebagai selesai untuk dedupe saat mulai ulang.

    Listener lokal mengikat ke 127.0.0.1:8787. Untuk ingress publik, letakkan reverse proxy di depan port lokal atau tetapkan webhookHost: "0.0.0.0" secara sengaja.

    Mode Webhook memvalidasi guard permintaan, token rahasia Telegram, dan isi JSON sebelum mengembalikan 200 ke Telegram. OpenClaw kemudian memproses pembaruan secara asinkron melalui lane bot per-obrolan/per-topik yang sama seperti yang digunakan long polling, sehingga giliran agen yang lambat tidak menahan ACK pengiriman Telegram.

    Batas, coba ulang, dan target CLI
    • Bawaan channels.telegram.textChunkLimit adalah 4000.
    • channels.telegram.chunkMode="newline" lebih memilih batas paragraf (baris kosong) sebelum pemisahan berdasarkan panjang.
    • channels.telegram.mediaMaxMb (bawaan 100) membatasi ukuran media Telegram masuk dan keluar.
    • channels.telegram.mediaGroupFlushMs (bawaan 500) mengontrol berapa lama album/grup media Telegram di-buffer sebelum OpenClaw mengirimkannya sebagai satu pesan masuk. Naikkan jika bagian album datang terlambat; turunkan untuk mengurangi latensi balasan album.
    • channels.telegram.timeoutSeconds menimpa batas waktu klien API Telegram (jika tidak ditetapkan, bawaan grammY berlaku). Klien bot membatasi nilai terkonfigurasi di bawah guard permintaan teks/typing keluar 60 detik agar grammY tidak membatalkan pengiriman balasan yang terlihat sebelum guard transport dan fallback OpenClaw dapat berjalan. Long polling tetap menggunakan guard permintaan getUpdates 45 detik agar polling menganggur tidak ditinggalkan tanpa batas.
    • channels.telegram.pollingStallThresholdMs bawaan ke 120000; sesuaikan antara 30000 dan 600000 hanya untuk mulai ulang polling-stall positif palsu.
    • riwayat konteks grup menggunakan channels.telegram.historyLimit atau messages.groupChat.historyLimit (bawaan 50); 0 menonaktifkan.
    • konteks tambahan balasan/kutipan/terusan saat ini diteruskan sebagaimana diterima.
    • allowlist Telegram terutama membatasi siapa yang dapat memicu agen, bukan batas redaksi konteks tambahan penuh.
    • Kontrol riwayat DM:
      • channels.telegram.dmHistoryLimit
      • channels.telegram.dms["<user_id>"].historyLimit
    • Konfigurasi channels.telegram.retry berlaku untuk helper kirim Telegram (CLI/tools/actions) untuk error API keluar yang dapat dipulihkan. Pengiriman balasan akhir masuk juga menggunakan coba ulang safe-send terbatas untuk kegagalan pra-koneksi Telegram, tetapi tidak mencoba ulang amplop jaringan pasca-kirim yang ambigu yang dapat menggandakan pesan yang terlihat.

    Target kirim CLI dan message-tool dapat berupa ID obrolan numerik, nama pengguna, atau target topik 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"
    

    Poll Telegram menggunakan openclaw message poll dan mendukung topik 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
    

    Flag poll khusus Telegram:

    • --poll-duration-seconds (5-600)
    • --poll-anonymous
    • --poll-public
    • --thread-id untuk topik forum (atau gunakan target :topic:)

    Kirim Telegram juga mendukung:

    • --presentation dengan blok buttons untuk keyboard inline saat channels.telegram.capabilities.inlineButtons mengizinkannya
    • --pin atau --delivery '{"pin":true}' untuk meminta pengiriman yang disematkan saat bot dapat menyematkan di obrolan tersebut
    • --force-document untuk mengirim gambar keluar dan GIF sebagai dokumen, bukan sebagai foto terkompresi atau unggahan media animasi

    Gating tindakan:

    • channels.telegram.actions.sendMessage=false menonaktifkan pesan Telegram keluar, termasuk poll
    • channels.telegram.actions.poll=false menonaktifkan pembuatan poll Telegram sambil tetap mengaktifkan pengiriman biasa
    Persetujuan exec di Telegram

    Telegram mendukung persetujuan exec dalam DM pemberi persetujuan dan secara opsional dapat memposting prompt di obrolan atau topik asal. Pemberi persetujuan harus berupa ID pengguna Telegram numerik.

    Jalur konfigurasi:

    • channels.telegram.execApprovals.enabled (aktif otomatis saat setidaknya satu pemberi persetujuan dapat diresolusikan)
    • channels.telegram.execApprovals.approvers (fallback ke ID pemilik numerik dari commands.ownerAllowFrom)
    • channels.telegram.execApprovals.target: dm (bawaan) | channel | both
    • agentFilter, sessionFilter

    channels.telegram.allowFrom, groupAllowFrom, dan defaultTo mengontrol siapa yang dapat berbicara dengan bot dan ke mana bot mengirim balasan normal. Ketiganya tidak menjadikan seseorang pemberi persetujuan exec. Pemasangan DM pertama yang disetujui melakukan bootstrap commands.ownerAllowFrom saat belum ada pemilik perintah, sehingga penyiapan satu pemilik tetap berfungsi tanpa menduplikasi ID di bawah execApprovals.approvers.

    Pengiriman channel menampilkan teks perintah dalam obrolan; hanya aktifkan channel atau both di grup/topik tepercaya. Saat prompt mendarat di topik forum, OpenClaw mempertahankan topik untuk prompt persetujuan dan tindak lanjutnya. Persetujuan exec kedaluwarsa setelah 30 menit secara bawaan.

    Tombol persetujuan inline juga memerlukan channels.telegram.capabilities.inlineButtons untuk mengizinkan permukaan target (dm, group, atau all). ID persetujuan yang diawali plugin: diresolusikan melalui persetujuan Plugin; yang lain diresolusikan melalui persetujuan exec terlebih dahulu.

    Lihat Persetujuan exec.

    Kontrol balasan error

    Saat agen menemukan error pengiriman atau provider, Telegram dapat membalas dengan teks error atau menyembunyikannya. Dua kunci konfigurasi mengontrol perilaku ini:

    Kunci Nilai Bawaan Deskripsi
    channels.telegram.errorPolicy reply, silent reply reply mengirim pesan error yang ramah ke obrolan. silent menyembunyikan balasan error sepenuhnya.
    channels.telegram.errorCooldownMs number (ms) 60000 Waktu minimum antara balasan error ke obrolan yang sama. Mencegah spam error saat gangguan.

    Override per-akun, per-grup, dan per-topik didukung (pewarisan yang sama seperti kunci konfigurasi Telegram lainnya).

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

    Pemecahan masalah

    Bot tidak merespons pesan grup non-mention
    • Jika requireMention=false, mode privasi Telegram harus mengizinkan visibilitas penuh.
      • BotFather: /setprivacy -> Nonaktifkan
      • lalu hapus + tambahkan ulang bot ke grup
    • openclaw channels status memperingatkan ketika konfigurasi mengharapkan pesan grup tanpa mention.
    • openclaw channels status --probe dapat memeriksa ID grup numerik eksplisit; wildcard "*" tidak dapat diperiksa keanggotaannya.
    • uji sesi cepat: /activation always.
    Bot sama sekali tidak melihat pesan grup
    • ketika channels.telegram.groups ada, grup harus tercantum (atau menyertakan "*")
    • verifikasi keanggotaan bot di grup
    • tinjau log: openclaw logs --follow untuk alasan dilewati
    Perintah berfungsi sebagian atau tidak sama sekali
    • otorisasi identitas pengirim Anda (pairing dan/atau allowFrom numerik)
    • otorisasi perintah tetap berlaku bahkan ketika kebijakan grup adalah open
    • setMyCommands failed dengan BOT_COMMANDS_TOO_MUCH berarti menu native memiliki terlalu banyak entri; kurangi perintah Plugin/Skills/kustom atau nonaktifkan menu native
    • panggilan startup deleteMyCommands / setMyCommands dan panggilan pengetikan sendChatAction dibatasi dan dicoba ulang sekali melalui fallback transport Telegram saat waktu tunggu permintaan habis. Error jaringan/fetch yang persisten biasanya menunjukkan masalah keterjangkauan DNS/HTTPS ke api.telegram.org
    Startup melaporkan token tidak sah
    • getMe returned 401 adalah kegagalan autentikasi Telegram untuk token bot yang dikonfigurasi.
    • Salin ulang atau buat ulang token bot di BotFather, lalu perbarui channels.telegram.botToken, channels.telegram.tokenFile, channels.telegram.accounts.<id>.botToken, atau TELEGRAM_BOT_TOKEN untuk akun default.
    • deleteWebhook 401 Unauthorized saat startup juga merupakan kegagalan autentikasi; memperlakukannya sebagai "tidak ada Webhook" hanya akan menunda kegagalan token buruk yang sama ke panggilan API berikutnya.
    Ketidakstabilan polling atau jaringan
    • Node 22+ + fetch/proxy kustom dapat memicu perilaku abort langsung jika tipe AbortSignal tidak cocok.
    • Beberapa host me-resolve api.telegram.org ke IPv6 terlebih dahulu; egress IPv6 yang rusak dapat menyebabkan kegagalan Telegram API secara intermiten.
    • Jika log menyertakan TypeError: fetch failed atau Network request for 'getUpdates' failed!, OpenClaw sekarang mencoba ulang ini sebagai error jaringan yang dapat dipulihkan.
    • Selama startup polling, OpenClaw menggunakan ulang probe startup getMe yang berhasil untuk grammY sehingga runner tidak memerlukan getMe kedua sebelum getUpdates pertama.
    • Jika deleteWebhook gagal dengan error jaringan sementara selama startup polling, OpenClaw melanjutkan ke long polling alih-alih membuat panggilan control-plane pra-poll lainnya. Webhook yang masih aktif muncul sebagai konflik getUpdates; OpenClaw lalu membangun ulang transport Telegram dan mencoba ulang pembersihan Webhook.
    • Jika soket Telegram didaur ulang pada cadence tetap yang pendek, periksa channels.telegram.timeoutSeconds yang rendah; klien bot menjepit nilai yang dikonfigurasi di bawah guard permintaan outbound dan getUpdates, tetapi rilis lama dapat meng-abort setiap poll atau balasan ketika ini diatur di bawah guard tersebut.
    • Jika log menyertakan Polling stall detected, OpenClaw memulai ulang polling dan membangun ulang transport Telegram setelah 120 detik tanpa liveness long-poll yang selesai secara default.
    • openclaw channels status --probe dan openclaw doctor memperingatkan ketika akun polling yang berjalan belum menyelesaikan getUpdates setelah masa tenggang startup, ketika akun Webhook yang berjalan belum menyelesaikan setWebhook setelah masa tenggang startup, atau ketika aktivitas transport polling terakhir yang berhasil sudah basi.
    • Tingkatkan channels.telegram.pollingStallThresholdMs hanya ketika panggilan getUpdates yang berjalan lama sehat tetapi host Anda masih melaporkan restart polling-stall palsu. Stall yang persisten biasanya mengarah ke masalah proxy, DNS, IPv6, atau egress TLS antara host dan api.telegram.org.
    • Telegram juga menghormati env proxy proses untuk transport Bot API, termasuk HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, dan varian huruf kecilnya. NO_PROXY / no_proxy masih dapat melewati api.telegram.org.
    • Jika proxy terkelola OpenClaw dikonfigurasi melalui OPENCLAW_PROXY_URL untuk lingkungan layanan dan tidak ada env proxy standar, Telegram juga menggunakan URL tersebut untuk transport Bot API.
    • Pada host VPS dengan egress/TLS langsung yang tidak stabil, rute panggilan Telegram API melalui channels.telegram.proxy:
    channels:
    telegram:
    proxy: socks5://<user>:<password>@proxy-host:1080
    
    • Node 22+ secara default menggunakan autoSelectFamily=true (kecuali WSL2). Urutan hasil DNS Telegram menghormati OPENCLAW_TELEGRAM_DNS_RESULT_ORDER, lalu channels.telegram.network.dnsResultOrder, lalu default proses seperti NODE_OPTIONS=--dns-result-order=ipv4first; jika tidak ada yang berlaku, Node 22+ fallback ke ipv4first.
    • Jika host Anda adalah WSL2 atau secara eksplisit bekerja lebih baik dengan perilaku hanya IPv4, paksa pemilihan family:
    channels:
    telegram:
    network:
      autoSelectFamily: false
    
    • Jawaban rentang benchmark RFC 2544 (198.18.0.0/15) sudah diizinkan untuk unduhan media Telegram secara default. Jika fake-IP tepercaya atau proxy transparan menulis ulang api.telegram.org ke alamat private/internal/special-use lain selama unduhan media, Anda dapat ikut serta dalam bypass khusus Telegram:
    channels:
    telegram:
    network:
      dangerouslyAllowPrivateNetwork: true
    
    • Opt-in yang sama tersedia per akun di channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork.
    • Jika proxy Anda me-resolve host media Telegram menjadi 198.18.x.x, biarkan flag berbahaya tetap nonaktif terlebih dahulu. Media Telegram sudah mengizinkan rentang benchmark RFC 2544 secara default.
    • Override lingkungan (sementara):
      • OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1
      • OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1
      • OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first
    • Validasi jawaban DNS:
    dig +short api.telegram.org A
    dig +short api.telegram.org AAAA
    

    Bantuan lainnya: Pemecahan masalah channel.

    Referensi konfigurasi

    Referensi utama: Referensi konfigurasi - Telegram.

    Field Telegram sinyal tinggi
    • startup/auth: enabled, botToken, tokenFile, accounts.* (tokenFile harus menunjuk ke file reguler; symlink ditolak)
    • kontrol akses: dmPolicy, allowFrom, groupPolicy, groupAllowFrom, groups, groups.*.topics.*, bindings[] tingkat atas (type: "acp")
    • persetujuan exec: execApprovals, accounts.*.execApprovals
    • perintah/menu: commands.native, commands.nativeSkills, customCommands
    • threading/balasan: replyToMode, dm.threadReplies, direct.*.threadReplies
    • streaming: streaming (pratinjau), streaming.preview.toolProgress, blockStreaming
    • pemformatan/pengiriman: textChunkLimit, chunkMode, linkPreview, responsePrefix
    • media/jaringan: mediaMaxMb, mediaGroupFlushMs, timeoutSeconds, pollingStallThresholdMs, retry, network.autoSelectFamily, network.dangerouslyAllowPrivateNetwork, proxy
    • root API kustom: apiRoot (hanya root Bot API; jangan sertakan /bot&lt;TOKEN&gt;)
    • Webhook: webhookUrl, webhookSecret, webhookPath, webhookHost
    • tindakan/kapabilitas: capabilities.inlineButtons, actions.sendMessage|editMessage|deleteMessage|reactions|sticker
    • reaksi: reactionNotifications, reactionLevel
    • error: errorPolicy, errorCooldownMs
    • penulisan/riwayat: configWrites, historyLimit, dmHistoryLimit, dms.*.historyLimit

    Terkait