برنامه نویسی ربات تلگرام
درس پنجم: تفکیک نوع آپدیت ها در ربات تلگرام
بر اساس به روز رسانی 3.6 رباتهای تلگرام
هم اکنون وقت آن رسیده تا بعد از گذشت چهار درسی که قبول دارم خسته کننده بودند، وارد مباحث اصلی ساخت ربات تلگرام شویم. پایهایترینِ این مباحث، تفکیک انواع آپدیتهای دریافت شده از طرف تلگرام میباشد.
مقدمه
وقتی وب هوکِ ربات خود را به یک url خاصی تنظیم میکنیم تا سرور تلگرام، محتوا را به آن ارسال کند؛ حتما از خود میپرسید که این محتوای ارسال شده چیست و چگونه باید آن را پردازش کنیم؟!
برای شروع، همنطور که باید از درس قبل بدایند:
- یک پوشه، در پوشهی fk-tb ایجاد کرده و نامی برای آن انتخاب کنید. برای مثال: test-update
- فایلی با نام test-update.php در داخل پوشهی test-update ایجاد کنید.
- کد پیشفرضی که در پست “فایل TBS” گفته شد را در آن قرار داده و مطابق ربات خود، مقدارها را تغییر دهید.
- نسخهی آخر فایل TBS را هم در جای خود قرار دهید.
توجه: این موارد در درس قبل توضیح داده شدند و در دروس بعدی به آنها اشاره نخواهم کرد.
دریافت آپدیت و تفکیک آن
نکتهی خیلی مهم: فایل TBS، خود محتوای دریافت شده از سمت تلگرام را خوانده و آن را پردازش میکند و نتیجه را داخل یک آرایه میریزد. نام متغیر این آرایه، $update بوده و همچنین، به صورت global تعریف شده است تا در هرجایی قابل استفاده باشد. این آرایه، براساس چیزی که در Telegram Bot API برای نوع update آمده است، مقداردهی میشود.
متغیر update، دربرگیرندهی تمامی چیزی است که سرور تلگرام برایمان ارسال کرده؛ به عبارتی، کاربر، محتوایی به سرور تلگرام ارسال میکند و سرور تلگرام آن را به آدرس ما و ما بعد از بررسی، در صورتی که بخواهیم میتوانیم به سرور تلگرم بگوییم چه چیزی را به چه جایی ارسال کند. (که البته باید به آنجا هم دسترسی داشته باشد؛ چرا که برای مثال، اگر پی وی باشد، شخص باید قبلا ربات را استارت کرده و بلاک یا استاپ نکرده باشد)
بنابراین، طبق API تلگرام، متغیر update براساس آخرین ورژن پلت فرم رباتها، میتواند شامل یکی از نوعهای زیر باشد:
- message
- edited_message
- channel_post
- edited_channel_post
- inline_query
- chosen_inline_result
- callback_query
- shipping_query
- pre_checkout_query
طبیعتا، این واضح است که چهار مورد اول، برای چه منظوری میباشند؛ ولی همه را در ادامه به صورت مختصر توضیح خواهیم داد.
حالا برای بررسی اینکه آپدیت دریافتی از چه نوعی میباشد، باید به صورت زیر عمل کنیم:
ابتدا متغیر update را از global دریافت کرده و سپس یک به یک، با استفاده از متد isset بررسی کردهایم که آیا این متغیر update (که از نوع آرایه است)، شامل کلید فلان میباشد یا خیر!
- نکته 1: آپدیت در هر لحظه، تنها میتواند شامل یکی از این کلیدها باشد؛ به عبارتی، یک آپدیت نمیتواند دو نوع باشد؛ برای مثال نمیتواند هم پیام جدید و هم پیام ویرایش شده باشد!
- نکته 2: تمامی موارد را باید یکی به یکی بررسی کنیم و درصورتی که هیچ کدام نباشد، به احتمال خیلی زیاد برای پلت فرم رباتها به روزرسانی آمده و نوع جدیدی اضافه شده است که ما در کدمان آن را بررسی نکردهایم.
هرکدام از این نوع ها، شامل چه چیزی هستند؟!
دوباره اگر به Telegram Bot API مراجعه کنید، مشاهده میکنید که جنس هرکدام از این موارد نیز مشخص شده است. برای مثال، هر چهار مورد اول از جنس Message میباشند؛ اما اینکه چه Message ای، باید توضیح دهیم.
- نوع message
این نوع، یک پیام حدید میباشد که میتواند از طرف پی وی و گروه دریافت شود و شامل یک پیام متنی، عکس، ورود و خروج کاربر و … میشود. - نوع edited_message
این نوع، دقیقا همان چیزهایی که در نوع قبلی هستند (به جز مواردی) را شامل میشود، با این تفاوت که اینجا دیگر یک پیام جدید نیست.؛ بلکه ویرایش شده است.
منظور از “به جز مواردی”، این است که برای مثال، لفت دادن و جوین شدن دیگر نمیتوانند ویرایش شوند بنابراین در اینجا قرار نمیگیرند. - نوع channel_post
مربوط به پیام جدید از طرف کانال میباشد. چرا که نوع message تنها شامل چتهای پی وی و گروه میشود و کانالها در اینجا دریافت میشوند؛ البته باید قبلا مشخص شده باشد که میخواهیم از کانال چیزی دریافت کنیم یا نه که فعلا مورد بحث ما نیست. - نوع edited_channel_post
مثل edited_message، ولی برای کانال! - نوع inline_query
احتمالا رباتهایی مثل like و vote خود تلگرام را دیدهاید که با نوشتن نام کاربریشان و بدون رفتن به پیوی، قابل استفاده هستند.
در این حالت، ورودیای که در جلوی نام کاربری دریافت میشود؛ در این نوع از آپدیت برای ربات ارسال میشود. - نوع chosen_inline_result
وقتی چیزی در جواب inline_query برای کاربر نمایش داده شده و یکی از آنها از طرف کاربر انتخاب شود، در این نوع برای ربات ارسال میشود. - نوع callback_query
نتایجی که از سمت دکمههای شیشهای ارسال میشوند. - نوع shipping_query
برای پرداخت که فعلا با آن کاری نداریم. - نوع pre_checkout_query
سبد خرید و این چیزها که فعلا با آن کاری نداریم.
بررسی انواع Message
علاوهبر اینکه نوع آپدیت بررسی میشود؛ برخی از این نوعها، از جمله نوع Message، شامل نوعهای خود میباشند.
نوع Message، شامل یک یا چند نوع زیر میتواند به صورت همزمان باشد.
- text
- entities
- caption_entities
- audio
- document
- game
- photo
- sticker
- video
- voice
- video_note
- caption
- contact
- location
- venue
- new_chat_members
- left_chat_member
- new_chat_title
- new_chat_photo
- delete_chat_photo
- group_chat_created
- supergroup_chat_created
- channel_chat_created
- migrate_to_chat_id
- migrate_from_chat_id
- pinned_message
- invoice
- successful_payment
- connected_website
جنس و توضیح اینها را نیز میتوانید در Telegram Bot API مشاهده کنید و البته در دروس بعدی، هرکدام را توضیح خواهیم داد.
یک مثال برای نوع text
همانطور که شاید حدس بزنید، مربوط به یک پیام متنی میباشد که حتما باید از جنس String باشد.
حالا فرض کنید میخواهیم رباتی بنویسیم که با دریافت دستور /start، به کاربری که وارد پیوی شده است، خوش آمدگویی کند و سپس با دریافت هر پیام دیگری، تعداد کل حروف، تعداد فاصله و تعداد حروف بدون فاصله را به کاربر اعلام کند. بنابراین، کد فایل اصلی ما به صورت زیر خواهد بود که البته نوعهای دیگر آپدیت را چون نیازی نداشتیم، بررسی نکردیم
(من دیگر کدهای ابتدای فایل را نمینویسم و تنها بخش اصلی را مینویسم.)
نکته: نوع Message، شامل یک ویژگی به نام chat میباشد و این ویژگی، همیشه وجود دارد و نیازی به بررسی اینکه آیا وجود دارد یا خیر نیست. همچین ویژگی chat، برای گرفتن اطلاعات چت، از قبیل، نوع چت (پیوی، گروه و …)، نام و نام خانوادگی یا عنوان و نام کاربری چت و سایر ویژگیهای چت، استفاده میشود.
در کد بالا، پس از بررسی اینکه آیا پیام message می باشد یا خیر، message و chat را در یک متغیر جدید قرار دادهایم. یک متغیر هم با نام method تعریف کردهایم تا نام متدی که میخواهیم اجرایش کنیم را درون آن قرار دهیم.
در ادامه، بررسی کردهایم که آیا پیام از نوع متن است یا خیر؛ زمانی که متن باشد، متن آن را درون متغیر text قرار دادهایم تا به سادگی از آن استفاده کنیم. سپس پارامترهای ورودی متدی که قرار است از آن برای ارسال جواب استفاده کنیم را ایجاد کردهایم که از نوع یک آرایه میباشد و به صورت پیشفرض، chat_id را در آن قرار دادهایم؛ اگر به متد sendMessage در توضیحات تلگرام مراجعه کنید، ورودی chat_id را مشاهده خواهید کرد که یک ورودی اجباری میباشد؛ ورودی text نیز اجبار میباشد که در ادامه آن را وارد خواهیم کرد.
بررسی میکنیم که اگر پیام برابر start بود، نام چت را گرفته و سپس آن را به همراه متن Welcome to FuLLKade Bot در پارامتر text تنظیم کند. بنابراین اگر نام شخصی که وارد پی وی شده، Hadi باشد؛ ربات پیام Hadi, Welcome to FuLLKade Bot را به اون نمایش میدهد.
حالا اگر پیام برابر start نباشد، عملیات شمارش را انجام میدهد که در ابتدا با متد strlen کل حروف را میشمارد؛ سپس با متد substr_coun، یک رشتهی خاصی که در اینجا فقط یک فاصله هست را شمرده و در نهایت با تفریق این دو، تعداد کاراکترهای قابل نمایش را به دست میآورد. در آخر هم که جواب را در پارامتر text تنظیم میکند.
حالا خارج از بررسی نوع آپدیت، بررسی کردهایم که اگر نام متد و پارامتر ورودی تنظیم شده بود، آن را با استفاده از متد fktbs_request_json ای که قبلا گفتیم، اجرا کند. البته حتما نیازی نیست شما اینگونه متد و پارامتر را تعریف و مورد استفاده قرار دهید، بلکه من به سلیقهی خودم اینگونه نوشتم تا کمی ذهنتان درگیر شود.
نکتهی خیلی مهم: ویژگی chat، همواره شامل first_name و last_name نمیباشد و اگر از طرف گروه باشد، به جای این دو، شامل title خواهد بود. بنابراین اینها را باید مدیریت کنیم.
سوال: حالا اگر در گروه start ارسال شود، دوباره این کد کار خواهد کرد! ولی گروه که جای این نیست! پس چه باید کرد؟!
خیلی ساده است، میتوانید از ویژگی type مربوط به chat، برای بررسی اینکه چت مورد نظر، پیوی است یا نه، استفاده کنید؛ به صورت زیر:
1 2 3 |
if ($chat['type'] === 'private') { } |
حالا از این در کد بالا استفاده کنید؛ تلاش کنید.
سوال: آیا میتوان کاری کرد که اگر start دوباره ارسال شد، به کاربر پیام متفاوتی ارسال شود؟! یعنی ربات بداند که این از قبل Start کرده است!
باز هم خیلی ساده است؛ میتوانید زمانی که پیامی میآید؛ اطلاعات چت را در جایی ذخیره کنید؛ برای مثال، دیتابیس بهترین گزینه است و در آینده به تمامی این موارد اشاره خواهیم کرد و فعلا زمانش نیست. البته اگر ماهر باشید که بی شک میتوانید این کار را انجام دهید و نیازی به توضیحات اضافی نیست!
به امید خدا، تا درس های آینده… موفق باشید.
سلام
ممنون از سایت خوبتون
برای مشاهده این بخش باید عضو سایت بشم ولی هرکاری میکنم و بادهر مرورگری وارد میشم نمیتونم ثبتنام کنم .یوزرنیم و ایمیل و پسورد میزنم ولی متاسفانه چن هفتس که امتحان میکنم نمیتونم عضو سایت بشم.لینک فعال سازی حسابم برای ایمیلم فرستاده نمیشه .با دو ایمیل هم امتحان کردم
لطفا رسیدگی کنید
باتشکر از سایت خوبتون
سلام دوست عزیز
اسپم ایمیلتون رو چک کردین؟
بله چک کردم ولی هیچ پیغامی چک نکردم
تورو خدا یکاری کنین
لینک مجدد به ایمیلتون ارسال شد چک کنید و در صورت نبود خبر بدین تا مشکل رو بررسی کنیم و براتون رمز ورود ارسال کنیم
هیچی نمیاد برادر.هیچ لینکی به ایمیلم نیومده.منم مشتاقم عضو سایتتون شم و آموزشارو دنبال کنم???
ایمیلتون تایید شد وارد شین!
اگه میشه آموزشارو برای ایمیلم بفرستین
خیلی نیاز دارم.ممنون میشم
سلام
متغیر parametersچرا از نوع آرایه س؟
سلام؛ این متغیر داخل تابعی که نوشتیم به جیسون تبدیل شده و به سرور تلگرام ارسال میشه
ما که نمیتونیم دستی رشته جیسون بسازیم چون برامون خیلی خسته بنابراین با استفاده از آرایه میسازیم و اونو به جیسون انکد میکنیم
درسایه بعدی رو کی میزارید؟
سلام دوستان
من یه ربات رباتساز دارم فقط بلد نیستم رباتو آپدیت کنم و چند بخش دیگ براش بزارم
مثلا ربات من ربات هایی همچون ربات پیام رسان یا ممبرگیر یا بازید گیر و چند چند ربات دیگه رو میسازع ولی من بلد نیستم بخش های زیادی اضافه کنم ینی این قابلیت رو بزارم که ربات های دیگر رو هم بسازع مثلن ربات کلیکرساز یا ربات تبچی و سلف از این جور چیزا هم بسازع
خواهشن هرکی بلده جواب بده یا تو تلگرام به ایدی زیر پیام بدع👇🙏🙏
@y_tip
ایدیم خیلی راحته خواهشن اگر بلدی کمکم کن