Mainstream messaging
Telegram
Siap produksi untuk DM dan grup bot melalui grammY. Long polling adalah mode default; mode webhook bersifat opsional.
Kebijakan DM default untuk Telegram adalah pairing.
Diagnostik lintas kanal dan playbook perbaikan.
Pola dan contoh konfigurasi kanal lengkap.
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
/setjoingroupsuntuk mengizinkan/menolak penambahan ke grup/setprivacyuntuk perilaku visibilitas grup
Kontrol akses dan aktivasi
DM policy
channels.telegram.dmPolicy mengontrol akses pesan langsung:
pairing(default)allowlist(memerlukan setidaknya satu ID pengirim diallowFrom)open(memerlukanallowFrommenyertakan"*")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):
- DM bot Anda.
- Jalankan
openclaw logs --follow. - 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:
-
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 entrigroups(atau"*")
- dengan
groupsdikonfigurasi: bertindak sebagai allowlist (ID eksplisit atau"*")
- tanpa config
-
Pengirim mana yang diizinkan di grup (
channels.telegram.groupPolicy)openallowlist(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.mentionPatternsmessages.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.iddariopenclaw 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. Konfigurasikanchannels.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
getUpdates409, gateway OpenClaw lain, script, atau poller eksternal kemungkinan menggunakan token yang sama. - Mulai ulang watchdog long-polling dipicu setelah 120 detik tanpa liveness
getUpdatesyang selesai secara default. Tingkatkanchannels.telegram.pollingStallThresholdMshanya jika deployment Anda masih melihat mulai ulang polling-stall palsu selama pekerjaan berjalan lama. Nilainya dalam milidetik dan diizinkan dari30000hingga600000; override per akun didukung. - Telegram Bot API tidak memiliki dukungan tanda dibaca (
sendReadReceiptstidak 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.streamingadalahoff | partial | block | progress(default:partial)progressmempertahankan satu draft status yang dapat diedit untuk progres tool, menghapusnya saat selesai, dan mengirim jawaban final sebagai pesan normalstreaming.preview.toolProgressmengontrol apakah pembaruan tool/progres menggunakan ulang pesan pratinjau yang sama yang diedit (default:truesaat streaming pratinjau aktif)streaming.preview.commandTextmengontrol detail perintah/exec di dalam baris progres tool tersebut:raw(default, mempertahankan perilaku yang dirilis) ataustatus(hanya label tool)channels.telegram.streamModelegacy dan nilai booleanstreamingterdeteksi; jalankanopenclaw doctor --fixuntuk memigrasikannya kechannels.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 streammengirim penalaran ke pratinjau langsung saat membuat- pratinjau penalaran dihapus setelah pengiriman akhir; gunakan
/reasoning onsaat 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,_, panjang1..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 faileddenganBOT_COMMANDS_TOO_MUCHberarti menu Telegram masih melampaui batas setelah dipangkas; kurangi perintah plugin/skill/khusus atau nonaktifkanchannels.telegram.commands.native.deleteWebhook,deleteMyCommands, atausetMyCommandsgagal dengan404: Not Foundsementara perintah curl Bot API langsung berfungsi dapat berartichannels.telegram.apiRootdisetel ke endpoint/bot<TOKEN>lengkap.apiRootharus hanya berupa root Bot API, danopenclaw doctor --fixmenghapus/bot<TOKEN>yang tidak sengaja berada di akhir.getMe returned 401berarti Telegram menolak token bot yang dikonfigurasi. PerbaruibotToken,tokenFile, atauTELEGRAM_BOT_TOKENdengan token BotFather saat ini; OpenClaw berhenti sebelum polling sehingga ini tidak dilaporkan sebagai kegagalan pembersihan webhook.setMyCommands faileddengan kesalahan jaringan/fetch biasanya berarti DNS/HTTPS keluar keapi.telegram.orgdiblokir.
Perintah pemasangan perangkat (plugin device-pair)
Saat plugin device-pair diinstal:
/pairmenghasilkan kode penyiapan- tempel kode di aplikasi iOS
/pair pendingmencantumkan permintaan tertunda (termasuk peran/cakupan)- setujui permintaan:
/pair approve <requestId>untuk persetujuan eksplisit/pair approvesaat hanya ada satu permintaan tertunda/pair approve latestuntuk 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:
offdmgroupallallowlist(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, opsionalmediaUrl,replyToMessageId,messageThreadId)react(chatId,messageId,emoji)deleteMessage(chatId,messageId)editMessage(chatId,messageId,content)createForumTopic(chatId,name, opsionaliconColor,iconCustomEmojiId)
Tindakan pesan channel mengekspos alias ergonomis (send, react, delete, edit, sticker, sticker-search, topic-create).
Kontrol gating:
channels.telegram.actions.sendMessagechannels.telegram.actions.deleteMessagechannels.telegram.actions.reactionschannels.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)firstall
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 menolaksendMessage(...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.emojiSticker.setNameSticker.fileIdSticker.fileUniqueIdSticker.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:
ownberarti 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>.ackReactionchannels.telegram.ackReactionmessages.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 memperbaruichannels.telegram.groups /config setdan/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.textChunkLimitadalah 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.timeoutSecondsmenimpa 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 permintaangetUpdates45 detik agar polling menganggur tidak ditinggalkan tanpa batas.channels.telegram.pollingStallThresholdMsbawaan ke120000; sesuaikan antara30000dan600000hanya untuk mulai ulang polling-stall positif palsu.- riwayat konteks grup menggunakan
channels.telegram.historyLimitataumessages.groupChat.historyLimit(bawaan 50);0menonaktifkan. - 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.dmHistoryLimitchannels.telegram.dms["<user_id>"].historyLimit
- Konfigurasi
channels.telegram.retryberlaku 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-iduntuk topik forum (atau gunakan target:topic:)
Kirim Telegram juga mendukung:
--presentationdengan blokbuttonsuntuk keyboard inline saatchannels.telegram.capabilities.inlineButtonsmengizinkannya--pinatau--delivery '{"pin":true}'untuk meminta pengiriman yang disematkan saat bot dapat menyematkan di obrolan tersebut--force-documentuntuk mengirim gambar keluar dan GIF sebagai dokumen, bukan sebagai foto terkompresi atau unggahan media animasi
Gating tindakan:
channels.telegram.actions.sendMessage=falsemenonaktifkan pesan Telegram keluar, termasuk pollchannels.telegram.actions.poll=falsemenonaktifkan 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 daricommands.ownerAllowFrom)channels.telegram.execApprovals.target:dm(bawaan) |channel|bothagentFilter,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
- BotFather:
openclaw channels statusmemperingatkan ketika konfigurasi mengharapkan pesan grup tanpa mention.openclaw channels status --probedapat 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.groupsada, grup harus tercantum (atau menyertakan"*") - verifikasi keanggotaan bot di grup
- tinjau log:
openclaw logs --followuntuk alasan dilewati
Perintah berfungsi sebagian atau tidak sama sekali
- otorisasi identitas pengirim Anda (pairing dan/atau
allowFromnumerik) - otorisasi perintah tetap berlaku bahkan ketika kebijakan grup adalah
open setMyCommands faileddenganBOT_COMMANDS_TOO_MUCHberarti menu native memiliki terlalu banyak entri; kurangi perintah Plugin/Skills/kustom atau nonaktifkan menu native- panggilan startup
deleteMyCommands/setMyCommandsdan panggilan pengetikansendChatActiondibatasi dan dicoba ulang sekali melalui fallback transport Telegram saat waktu tunggu permintaan habis. Error jaringan/fetch yang persisten biasanya menunjukkan masalah keterjangkauan DNS/HTTPS keapi.telegram.org
Startup melaporkan token tidak sah
getMe returned 401adalah 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, atauTELEGRAM_BOT_TOKENuntuk akun default. deleteWebhook 401 Unauthorizedsaat 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.orgke IPv6 terlebih dahulu; egress IPv6 yang rusak dapat menyebabkan kegagalan Telegram API secara intermiten. - Jika log menyertakan
TypeError: fetch failedatauNetwork request for 'getUpdates' failed!, OpenClaw sekarang mencoba ulang ini sebagai error jaringan yang dapat dipulihkan. - Selama startup polling, OpenClaw menggunakan ulang probe startup
getMeyang berhasil untuk grammY sehingga runner tidak memerlukangetMekedua sebelumgetUpdatespertama. - Jika
deleteWebhookgagal 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 konflikgetUpdates; OpenClaw lalu membangun ulang transport Telegram dan mencoba ulang pembersihan Webhook. - Jika soket Telegram didaur ulang pada cadence tetap yang pendek, periksa
channels.telegram.timeoutSecondsyang rendah; klien bot menjepit nilai yang dikonfigurasi di bawah guard permintaan outbound dangetUpdates, 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 --probedanopenclaw doctormemperingatkan ketika akun polling yang berjalan belum menyelesaikangetUpdatessetelah masa tenggang startup, ketika akun Webhook yang berjalan belum menyelesaikansetWebhooksetelah masa tenggang startup, atau ketika aktivitas transport polling terakhir yang berhasil sudah basi.- Tingkatkan
channels.telegram.pollingStallThresholdMshanya ketika panggilangetUpdatesyang 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 danapi.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_proxymasih dapat melewatiapi.telegram.org. - Jika proxy terkelola OpenClaw dikonfigurasi melalui
OPENCLAW_PROXY_URLuntuk 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 menghormatiOPENCLAW_TELEGRAM_DNS_RESULT_ORDER, laluchannels.telegram.network.dnsResultOrder, lalu default proses sepertiNODE_OPTIONS=--dns-result-order=ipv4first; jika tidak ada yang berlaku, Node 22+ fallback keipv4first. - 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 ulangapi.telegram.orgke 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=1OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1OPENCLAW_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.*(tokenFileharus 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<TOKEN>) - 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