Widget dalam pesan — blok interaktif dari HTML, CSS, dan JavaScript langsung di dalam obrolan — telah hadir di versi beta Telegram untuk Android dan iOS. Pada 25 Oktober, mereka muncul di Android 13.2.0 (7254) dan iOS 13.2 (35726), dan di Android, widget buatan sendiri sudah dapat menjalankan JavaScript. Build Android 13.2.0 (7260) dari 27 Oktober menunjukkan cara kerjanya: tanpa mesin peramban, menggunakan interpreter-nya sendiri dengan kuota CPU, dan dengan arbiter terpisah yang memutuskan apakah sebuah ketukan itu asli. Bot yang menerima permintaan dari widget akan mengetahui ID pengguna yang mengetuk. Di Telegram Desktop dan Bot API publik, widget masih belum tersedia.
Mekanisme permintaan ke bot melalui beta macOS telah dibahas dalam artikel 27 Oktober; di sini kami akan membahas apa yang ditambahkan oleh build untuk Android.
Di mana widget tersedia
| Klien | Build | Apa yang terlihat |
|---|---|---|
| macOS, beta | 13.1.0 | sandbox, permintaan ke bot, halaman uji — sejak pertengahan Oktober |
| Android, beta | 13.2.0 (7254, 7260) | skema, sandbox, teks antarmuka; widget berfungsi |
| iOS, beta | 13.2 (35726) | widget dalam pesan dan alat untuk pengujiannya |
| Telegram Desktop | 7.3.3 | tidak ada: baik dalam kode maupun skema layer 232 |
| Bot API | 10.3 | tidak ada |
Beta Android didistribusikan melalui kanal resmi dan tautan langsung dari situs web Telegram. Protokol klien di dalamnya adalah layer 233, satu tingkat lebih baru dari yang publik.
Bagaimana widget disimpan dalam pesan
Widget adalah jenis media baru, messageMediaWidget. Selain kode itu sendiri (payload) dan ukurannya, ada dua set data di dalamnya: chat_data — data pesan ini, dan public_data dengan hash — data umum widget yang dapat diubah oleh bot setelah pengiriman (messages.editMessageWidgetData, updateMessageWidgetData). Flag can_query dan background_query menunjukkan apakah widget dapat menulis ke bot saat diketuk dan tanpa diketuk, is_copy menandai salinan yang diteruskan. Widget juga dapat datang sebagai respons inline dari bot — botInlineMessageWidget.
Izin diatur oleh pengirim. Dalam pesan kesalahan dari bagian native klien, disebutkan flag server allow_queries dan fwd_allow_queries: tanpa yang pertama, widget tidak akan menulis ke bot sama sekali, tanpa yang kedua, salinan yang diteruskan akan diam. Permintaan latar belakang memerlukan background_query tambahan dan hanya akan dikirim selama widget terlihat di layar.
Apa yang diterima bot
Ketukan berubah menjadi messages.getBotWidgetQueryAnswer dengan bidang obrolan, pesan, dan data — hingga 64 byte. Bot menerima pembaruan updateBotWidgetQuery dan merespons dengan metode messages.setBotWidgetQueryAnswer dengan satu string result.
Dalam pembaruan untuk bot, bidang user_id adalah wajib, tanpa flag: bot selalu tahu siapa yang mengetuk. Bersamaan dengan itu, datang chat_type, chat_instance — pengidentifikasi obrolan anonim yang sama dengan tombol inline biasa — nomor pesan, dan widget_id. Untuk salinan yang diteruskan dan pesan inline, ada pembaruan tersendiri — updateBotWidgetCopyQuery dan updateInlineBotWidgetQuery.
Ini mirip dengan mengetuk tombol inline dengan callback, hanya saja tombolnya digambar oleh skrip, dan datanya dikumpulkan oleh skrip itu juga.
Bagaimana kode widget dieksekusi
Di Android, tidak ada WebView maupun Chromium di bawah widget. Kode dieksekusi oleh pustaka native twidget di dalam pustaka utama klien — nama yang sama digunakan oleh tipe Twidget* di beta untuk macOS dan repositori tertutup yang terhubung ke sumbernya. Skrip sandbox disimpan dua kali di klien: sebagai sumber dan bytecode .qbc, yang dijalankan oleh interpreter JavaScript bawaan. Gambar digambar oleh renderer-nya sendiri langsung ke jendela Android — tidak ada tata letak peramban, melainkan ada penguraiannya: paket validator terpisah memeriksa HTML dan CSS.
Batasan-batasan ditulis dalam kode, bukan dalam aturan untuk pengembang:
- CPU — widget memiliki kuota waktu (
cpuQuotaMs), melebihi ini akan berakhir dengan kesalahan «CPU limit exceeded»; - Timer — jumlah timer simultan terbatas, mesin akan menolak yang berlebihan;
- Jaringan —
fetch,XMLHttpRequest,WebSocket, dannavigator.sendBeacondiblokir,navigator.onLineselalu salah,userAgent—TelegramWidget/1.0; - Penyimpanan — setiap widget dimulai dengan kosong;
- Keluar ke luar —
openLinkhanya mengambil alamat https hingga 256 karakter dan bertanya: «This widget wants to open:»,copyText— hingga 256 karakter; - Jembatan ke klien — setelah diluncurkan, fungsi layanan
__host,__hostOps, dan yang terkait dihapus dari objek global, dan kode widget tidak dapat mencapainya.
File sandbox diverifikasi oleh klien dengan checksum dari manifest.txt, perbedaan akan menghasilkan kesalahan terpisah «Bundle checksum mismatch».
Bagaimana klien membedakan ketukan dari imitasi
Permintaan ke bot tanpa izin latar belakang hanya dikirim dari penangan ketukan — "satu panggilan per satu ketukan pada widget yang terlihat," seperti yang disebutkan dalam pesan kesalahan. Yang memutuskan apakah itu ketukan adalah arbiter sentuhan native, bukan skrip: fungsi arbiterDown, arbiterMove, arbiterUp, dan arbiterHoldDeadline menerima koordinat jari dan waktu penahanan. Menurut desain, klik sintetis dari JavaScript, timer, atau seret tidak akan mengirim permintaan.
Di versi beta juga terdapat alat untuk memeriksa batasan ini: layar kesesuaian (WidgetConformanceActivity) dan menjalankan serangkaian serangan (attackScan, WidgetAttacks). Kumpulan halaman uji serangan untuk macOS — 28 halaman yang mencoba mengirim pesan tanpa ketukan atau mengarahkan ke tautan — tersedia dalam kode terbuka klien.
Apa yang dilihat pengguna
Teks antarmuka sudah ada dalam kamus string klien berbahasa Inggris: «Loading widget…», «Widget failed to load», «Widget stopped», «Preview of the widget», dan peringatan «This widget can send data to its bot's server when you tap it.»
Tidak ada tombol terpisah di pengaturan beta yang akan menonaktifkan widget — hal ini diperhatikan oleh para penguji. Mengirim widget belum bisa dilakukan oleh semua orang, dan di Bot API belum ada metode untuk itu.




