ویجت‌ها در پیام‌های تلگرام اکنون یک کانال ارتباطی برگشتی با ربات دارند. در بیلد‌های بتای تلگرام برای macOS 13.1.0 مورخ ۲۶ اکتبر، فراخوانی request() به اسکریپت ویجت اضافه شده است: با هر ضربه (کلیک/لمس)، این فراخوانی می‌تواند تا ۶۴ بایت داده به ربات ارسال کند و تا ۱٬۰۲۴ بایت پاسخ دریافت کند. بدون ضربه، درخواست فقط در چت خصوصی با ربات ارسال می‌شود، به شرطی که ربات چنین درخواست‌هایی را مجاز کرده باشد، ویجت روی صفحه باشد و ارسال درخواست‌ها هر پنج ثانیه یک بار بیشتر نباشد. در همان‌جا، ویجت اکنون می‌داند چه کسی آن را باز کرده است — شناسه (ID)، نام، نام کاربری و وضعیت Premium — و در چه نوع چتی قرار دارد. خود ویجت‌ها در نسخه‌های بتای iOS، macOS و Android مشاهده شده‌اند، اما این مکانیسم فعلاً فقط در بیلد macOS قابل مشاهده است؛ در طرح عمومی API و در Bot API، ویجت‌ها وجود ندارند.

The post on Telegram — @gramnews
پیام‌های ویجتی چگونه خواهند بود

چه تغییراتی بین ۲۵ و ۲۶ اکتبر رخ داد

بتای macOS از طریق فید به‌روزرسانی‌ها توزیع می‌شود و هر بیلد یک فایل zip حاوی برنامه است. برای مقایسه، نسخه‌های 13.1.0.283381 مورخ ۲۵ اکتبر و 13.1.0.283391 مورخ ۲۶ اکتبر مورد بررسی قرار گرفته‌اند.

اسکریپت ویجت از طریق شیء سراسری TelegramWidget با کلاینت ارتباط برقرار می‌کند. کد آن در بسته WidgetSandbox داخل برنامه، در فایل sandbox-bundle.js قرار دارد. در نسخه 283381، این شیء قابلیت‌های محدودی داشت: ارائه تم، اشتراک در رویدادها، باز کردن لینک و فعال کردن لرزش. در نسخه 283391، موارد زیر به آن اضافه شد:

چه چیزیچه کاری انجام می‌دهد
request(data)یک رشته از ۱ تا ۶۴ بایت به ربات ارسال می‌کند و پاسخ آن را برمی‌گرداند
viewerشناسه (ID)، نام، نام خانوادگی، نام کاربری و وضعیت Premium کاربر مشاهده‌کننده
chatTypeنوع چت: خصوصی، گروه، سوپرگروه یا کانال
chatDataداده‌های مرتبط با پیام در این چت، تا ۱٬۰۲۴ بایت
publicDataداده‌های خود پیام، تا ۱٬۰۲۴ بایت
watchPublicData()اشتراک در تغییرات publicData
isForward و isPreviewآیا این یک کپی فوروارد شده است و آیا پیش‌نمایش یک نتیجه اینلاین هنوز ارسال نشده است
copyText(text)تا ۲۵۶ کاراکتر را در کلیپ‌بورد قرار می‌دهد
setResizeAnchorلبه‌ای که ویجت هنگام تغییر ارتفاع از آن رشد می‌کند — بالا یا پایین

به سه رویداد قبلی — تغییر تم، فعال‌سازی و غیرفعال‌سازی — رویدادهای chatDataChanged و publicDataChanged نیز اضافه شدند.

همزمان، از بسته HTMLBubbles تمام محتوای نمایشی حذف شد: سیزده چت نمایشی که در مطلب ۱۳ اکتبر به آن‌ها اشاره شده بود، پوشه ported با کارت‌های منتقل‌شده، بازی چندنفره voxel-clash و پوشه widget-sandbox با مثال‌ها. تنها کتابخانه three.js در بسته باقی ماند.

چه زمانی ویجت می‌تواند به ربات پیام دهد

قوانین در همان سندباکس، در متن خطاهایی که اسکریپت دریافت می‌کند و در رشته‌های برنامه ثبت شده‌اند:

  • درخواست از کنترل‌کننده ضربه روی ویجت ارسال می‌شود، یک فراخوانی برای هر ضربه؛
  • بدون ضربه — فقط در چت خصوصی با ربات، فقط در صورتی که پیام اجازه درخواست‌های پس‌زمینه را داشته باشد (پرچم background_query)، فقط تا زمانی که ویجت روی صفحه است و نه بیشتر از یک بار در هر پنج ثانیه؛
  • تا زمانی که درخواست قبلی در انتظار پاسخ است، درخواست جدیدی ارسال نمی‌شود؛
  • پیش‌نمایش نتیجه اینلاین که هنوز به چت ارسال نشده است، از ربات سوالی نمی‌کند؛
  • درخواست‌ها غیرفعال هستند اگر ربات آن‌ها را برای این پیام مجاز نکرده باشد — کپی فوروارد شده اجازه جداگانه دارد؛
  • پاسخ ربات — فقط متن و نه طولانی‌تر از ۱٬۰۲۴ بایت، در غیر این صورت اسکریپت خطای INVALID_ANSWER را دریافت می‌کند؛ اگر به موقع پاسخ ندهد — TIMEOUT.

در کپی فوروارد شده، chatData خالی است، اما publicData باقی می‌ماند.

در رشته‌های برنامه در کنار کد حباب HTML، عبارت «A tap may send data to the bot» — «یک ضربه ممکن است داده‌ها را به ربات ارسال کند» — ظاهر شد. اینکه کلاینت دقیقاً کجا آن را نمایش می‌دهد، از بیلد مشخص نیست.

چه باید کرد

  • ویجت‌ها فعلاً فقط در نسخه‌های بتا وجود دارند و نمی‌توان آن‌ها را از طریق ربات‌ها ارسال کرد: در Bot API متدی برای ارسال ویجت وجود ندارد.
  • هنگام ضربه زدن روی ویجت، در نظر داشته باشید که هر ضربه می‌تواند به یک درخواست به ربات تبدیل شود. اسکریپت شناسه (ID)، نام، نام کاربری و وضعیت Premium شما را می‌بیند و شناسه تا ۱۶ رقم را اشغال می‌کند — در یک درخواست ۶۴ بایتی جا می‌شود.
  • ویجت به خودی خود، بدون ضربه، فقط در چت خصوصی با همان ربات به ربات پیام می‌دهد. برای گروه‌ها و کانال‌ها، سندباکس درخواست‌های پس‌زمینه را پیش‌بینی نمی‌کند.
  • ویجت به شبکه دسترسی ندارد: fetch، XMLHttpRequest، WebSocket و workerها در سندباکس با جایگزین‌هایی که خطا برمی‌گردانند، جایگزین شده‌اند. داده‌ها از طریق ربات یا از طریق لینکی که ویجت باز می‌کند (openLink فقط https را می‌پذیرد و طول آن نباید بیشتر از ۲۵۶ کاراکتر باشد) به بیرون ارسال می‌شوند — این وضعیت در بیلد ۲۵ اکتبر نیز وجود داشت.

چگونه سرور ویجت را تحویل می‌دهد

در باینری 283391، نام‌های انواع طرح (schema types) ظاهر شدند که در 283381 وجود نداشتند. در طرح عمومی لایه 232 — نه در Telegram Desktop و نه در Telegram Web A — آن‌ها وجود ندارند، و ویجت‌ها در مستندات Bot API نیز نیستند. ساختار از روی نام‌ها قابل درک است، بنابراین در ادامه — تفسیری است، نه توضیحی:

  • botInlineMessageWidget، inputBotInlineMessageWidget و inputBotInlineMessageWidgetId — ربات، ظاهراً، ویجت را به عنوان یک نتیجه اینلاین، به طور کامل یا با شناسه (ID) برمی‌گرداند؛
  • inputMediaWidgetId — ویجت به عنوان پیوست پیام با شناسه (ID)؛
  • updateBotWidgetQuery، updateInlineBotWidgetQuery و updateBotWidgetCopyQuery — درخواست‌ها به ربات از ویجت در یک پیام عادی، در پیامی که از طریق حالت اینلاین ارسال شده است و، با توجه به نام، در یک کپی فوروارد شده؛ پاسخ — botWidgetQueryAnswer؛
  • updateMessageWidgetData و widgetPublicData — سرور داده‌های جدید ویجت از قبل ارسال شده را می‌فرستد، و در سندباکس برای این کار رویداد publicDataChanged وجود دارد؛
  • خطاهای سرور WIDGET_QUERY_NOT_ALLOWED و WIDGET_RESPONSE_TIMEOUT به نظر می‌رسد جفت خطاهای اسکریپت NOT_ALLOWED و TIMEOUT باشند.

رشته‌های کلاینت همچنین به پرچم‌های مجوز اشاره می‌کنند: allow_queries برای پیام، fwd_allow_queries برای کپی‌های فوروارد شده آن و background_query برای درخواست‌های بدون ضربه. اینکه ربات دقیقاً چه چیزی را همراه با درخواست دریافت می‌کند — شناسه (ID) کاربر ضربه‌زننده، مانند دکمه‌های زیر پیام، یا خیر — از بیلد مشخص نیست.

چه چیزی در آزمایشگاه‌های اندازه‌گیری در کد باز بررسی می‌شود

در مخزن کد باز کلاینت، موتور ویجت‌ها به عنوان زیرماژول twidget متصل شده است؛ با کلیک بر روی لینک زیرماژول، GitHub خطای 404 را برمی‌گرداند — مخزن بسته یا حذف شده است. در کنار آن، آزمایشگاه‌های اندازه‌گیری قرار دارند، و در پوشه tools/perflab/TwidgetLab/widgets/attack — ۲۸ ویجت وجود دارد که سعی می‌کنند بدون ضربه واقعی عمل کنند. شانزده مورد از آن‌ها داده‌ها را به ربات ارسال می‌کنند: با تایمر هر ۵۰ میلی‌ثانیه، با کلیک مصنوعی، با فراخوانی تأخیری پس از کلیک، از طریق برچسب فیلد فرم (label)، با کشیدن و رها کردن. دوازده مورد سعی می‌کنند بدون ضربه لینکی را باز کنند یا از صفحه خارج شوند — با لینکی روی دکمه، ارسال فرم، به‌روزرسانی خودکار صفحه. این پوشه با کامیتی در ۲۳ اکتبر، سه روز قبل از بیلد حاوی request()، در مخزن ظاهر شد.

در این آزمایشگاه‌ها، ارسال هنوز TelegramWidget.sendMessage نامیده می‌شود. در بیلد 283391 چنین فراخوانی وجود ندارد — request() وجود دارد، و فراخوانی خارج از ضربه توسط اسکریپت به عنوان خطا با دلیل no-activation دریافت می‌شود.

چه چیزهای دیگری در مثال‌های حذف شده وجود داشت

در پوشه widget-sandbox بیلد 283381، دو مجموعه ۲۰ ویجتی — with-profile و without-profile — قرار داشتند. نام فایل‌ها درخواست‌هایی بودند: «show me a mortgage calculator»، «make a bar chart of the top 6 programming…»، «create a pomodoro timer»، «create a flashcard widget for 8 Spanish…». شیء TelegramWidget در ۱۲ فایل از مجموعه اول و هیچ‌کدام از مجموعه دوم ذکر شده است. این به نظر می‌رسد ویجت‌هایی باشند که توسط یک مدل با درخواست‌های یکسان، با و بدون توضیحات قابلیت‌های سندباکس، جمع‌آوری شده‌اند — این یک نتیجه‌گیری بر اساس محتوا است، خود بیلد این را نمی‌گوید. کلمه profile در شیء TelegramWidget نیز وجود دارد: ویژگی profile برابر با ۱ است، و isProfileAtLeast() سطح را بررسی می‌کند.

بقیه محتوای پوشه — بررسی‌های سازگاری (Chart.js، D3، three.js، WebGL، فرم‌ها، کشیدن و رها کردن، localStorage)، کارت‌های ویترین با موضوعات «خرید»، «کار»، «زندگی»، «سفر» و تست‌های استرس بود.

ویجت‌ها در کجا دیگر هستند

ویجت‌ها در پیام‌ها به عنوان فرمت به‌روزرسانی بعدی 13.2 در ۲۵ اکتبر توصیف شده بودند. اینکه ویجت چگونه با ربات ارتباط برقرار می‌کند، چه چیزی را درباره بیننده می‌بیند و مرزهای درخواست‌ها کجا هستند، در آن توضیحات نبود.