در قسمتهای قبلی آموزش اتصال ربات تلگرام به آردوینو، در خصوص نحوهی ساخت ربات بهکمک Botfather و همچنین برقراری ارتباط با سرورهای تلگرام برای جانبخشیدن به ربات توضیحدادیم و سورس آن را نیز منتشرکردیم. در این آموزش، نگاهی کاربردیتر به مقوله ربات تلگرام خواهیمداشت.
سرایدار تلگرامی!
همانطورکه قبلا اشارهکردیم ، طیف کارهایی که میتوان با استفادهاز یک ربات تلگرامی انجامداد محدودیت ندارد و محدودیت موجود به قوه تخیل ما برمیگردد. دراین آموزش، ما رباتی را خواهیمساخت که با استفادهاز آن بتوانیم از راهدور وسایلمنزل را کنترلکنیم، چنین رباتی میتواند کاربردهای فراوانی داشتهباشد، مثلا بعداز یک مسافرت درونشهری یا برونشهری در راه برگشت به خانه با استفادهاز ربات تلگرام کولر خانه را روشنکنید یا وقتی که سفر شما طولانی شد بتوانید از راه دور لامپهای خانه را روشن یا خاموش کنید حتی میتوان ربات را به دوربین متصل کرد و از فضای درون خانه عکس گرفت. همهچیز امکانپذیر است و محدودیتی وجود ندارد. در این آموزش به کنترل وسایل منزل اکتفا میکنیم و شاید اگر دوستان مشتاق بودند قسمت دوربین را هم اضافهکنیم.
ربات چگونه کار می کند؟
سایتها و سورسهای زیادی وجوددارند که چنین رباتی را ایجادکردهاند، ولی نگاهما متفاوت است، معمولا رباتهای ساختهشده همه از یک الگوی متنی برای کنترل وسایل استفاده کردهاند و اینکه از کتابخوانههای آماده برای کد بهره بردهاند که البته بد نیست ولی فاقد توضیحات لازم در خصوص نحوه عملکرد ربات و جزئیات آن است، ما همهچیز را از ابتدا و از صفر بنا کردهایم ، بهاینمعنیکه ابتدا درخصوص نحوهی عملکرد یک ربات توضیحدادیم، پروتکلهای آن را موشکافی کردیم ، و اولین ارتباط را با یک کد بسیار ساده پیادهسازی کردیم، درادامه باتوجهبه آموزشهای ارائهشده کتابخانهای متناسب با آنرا پیادهسازی کردیم.
رباتی هم که قصد پیادهسازی آنرا داریم در همین الگو قرار میگیرد، همانطورکه قبلا اشارهکردیم الگوی رفتاری ربات ما کاملا متفاوتاز آن چیزیاست که تاکنون در اینترنت وجودداشتهاست.
رباتی که قصد پیادهسازی آنرا داریم از دستورات متنی برای کنترل لوازم و وسایل استفاده نمیکند بلکه با استفادهاز inline keyboard برای کنترل و دریافت دستورات کاربر استفاده میکند. در روش دریافت دستورات بهصورت متنی احتمال اینکه کاربر دستور موردنظر را درست وارد نکند بالاست و یا اینکه ممکناست کارکرد دستورات را و یا شکل نوشتاری آنرا فراموش کند ولی در روش مورداستفاده ما دستورات بهصورت لیستی در اختیار کاربر قرار میگیرد که عملکرد هر دستور بهصورت متن فارسی روی آن درجشدهاست همین مساله باعث میشود که استفادهاز ربات بسیار دلپذیرتر و سادهتر باشد.
قضیه inline keyboard چیست ؟
تاقبلاز وجود inline keyboard رباتهای تلگرامی در بهترین حالت کیبوردهایی داشتند که کاربر میتوانست بااستفادهاز آنها دستورات موردنظر خود را به ربات بدهد، مشکلات موجود درخصوص آپدیتنشدن کیبورد، لودنشدن آن باعث ایجاد حس ناخوشایندی در کاربران و تنفر آنها از رباتهای تلگرام شدهبود، با ایجاد قابلیت inline keyboard میتوان گفت علاوهبر ظاهر زیبا عملکرد مطلوبی هم در برقراری ارتباط با کاربر ایجادشدهاست.
inline keyboard ها قابلیت اضافه و ویرایش شدن در هر پست ارسالی را دارا میباشند، یعنی میتوان در انتهای هر پست لیستیاز کلیدها را ایجاد کرد، هر کلید دارای دو محتواست، محتوای اول که به کاربر نمایش داده میشود و محتوای دوم بافشردن کلید توسط کاربر به سرور ارسال میشود و سرورتلگرام آنرا ازطریق CallBack آنرا برای پردازش در اختیارما قرار میدهد.
چطور inline keyboard بسازیم ؟
اصولا تلگرام تمام تبادلات را در قالب JSON انجام میدهد، JSON یک استاندارد باز است که باساختار خوانا برای انسان و ماشین، میتواند اطلاعات و دادههای مختلف را بااستفادهاز آن بین عوامل مختلف ردوبدل کرد. برای ایجاد inline keyboard باید دادههای مربوط به کیبورد را در قالب JSON به پیام خود اضافهکنیم. برای نمونه، کد JSON زیر دو کلید به متن ما اضافه میکنید.
{ "inline_keyboard": [ [ {"text": "Sisoog", "url": "https://www.sisoog.com/"}, {"text": "Google", "url": "http://www.google.com/"} ] ] };
با اضافهکردن ساختارفوق به فیلد reply_markup در تابع ارسال پیام، هنگام نمایش پیام موردنظر به کاربر، دو کلید یکی با نام Sisoog و دیگری با نام Google به انتهای پیام اضافه میشود. نوع کلیدها را ما با پارامتر url تنظیم کردهایم که به تلگرام میگوید با کلیک برروی این کلید به آدرس مقابل مراجعهکند و سایت موردنظر را باز کند، این نوع کلید بافشردهشدن مقادیری به سرور برنمیگرداند چرا که عملکرد آنکه بازکردن صفحهوب است سمت کاربر انجام میشود. اما اگر نوع کلید را با مقدار callback_data مشخصکنیم، بهمحض کلیک کاربر برروی دکمه مقدار تعیینشده به سرور برای پردازش ارسال میشود.
چگونه پیام های ربات را مدیریت کنیم ؟
برخلاف چیزی که بیشتر دوستان فکر میکنند (بازخورد از صحبتهای دوستان) کتابخانه نوشتهشده برای ربات تلگرام (Zeus_TgBot) بهصورت 100درصد برنامهنویسی شده و مقصود از اینکار پیشرفتن با آموزشها و درک بهتر کدهای نوشتهشدهاست، اگرنه کتابخانههای فراوانی برای برقراری ارتباط با تلگرام وجوددارد، ما سعیکردهایم کتابخانه را در سادهترین حالتممکن کدنویسی کنیم تا درک کدهای نوشتهشده سادهتر باشد.
برای اضافهکردن قابلیت inline keyboard به ربات تلگرام، مجبورشدیم که مقداری تغییرات دربرخی توابع ایجادکنیم، از آنجایی که ارسال کدهای JSON ازطریق GET امکانپذیر نبود و با روشهای معمول سرور تلگرام خطا اعلام میکرد، مجبور به پیادهسازی متد POST برای ارسال دادههای به سرور شدیم، قبلا متد GET را توضیح دادیم که دادهها از طریق URL به سرور انتقال مییابد، در متد POST دادهها باید از طریق Socket به سرور ارسال شوند.
client.println("POST /Method HTTP/1.1"); client.println("Host: api.telegram.org"); client.println("Cache-Control: no-cache"); client.println("Content-Type: application/json"); client.print("Content-Length: "); client.println(PostData.length()); client.println(); client.println(PostData);
درواقع برای ارسالدادهها بهعنوان POST میتوان از کدهای زیر استفادهکنید.
تغییر بعدی که اجتنابناپذیر بود، تغییر در تابع Message_Event بود، در ورژنهای قبلی چون قابلیت inline keyboard وجود نداشت، تابع مذکور فقط شامل آیدی فرستنده، آیدی پیام و متنپیام بود، باتوجهبه اضافهشده قابلیت inline keyboard به کتابخانه “تلگرام آردوینو” باید بتوان CallBack های مربوط به فشردهشدن کلیدها را نیز مدیریت کرد پس تابع فوق به شکلزیر اصلاح شد.
typedef void (*Message_Event) (String Message_id,String Message_From,String Message_Text,bool is_callback,String Call_ID);
همانطورکه قبلا توضیحدادیم، شما میتوانید بااستفادهاز تابع Set_Message_Event ؛ تابعی را به کتابخانه Zeus_TgBot معرفی کنید تا درهنگام دریافت پیام جدید بهصورت خودکار تابع موردنظر فراخوانی شود. تابع مذکور باید 5 پارامتر ورودی باشد.
پارامتر اول شناسه پیام است، هنگامی که کاربر برروی یکیاز کلیدها، کلیک کند، شناسه پیامی که دکمهها به آن اتچ شدهاند را برمیگرداند، پارامتر دوم درواقع شناسه فردی است که پیام را برای ما ارسال کردهاست، برای ارسال پاسخ میتوانیم پیام را به این شناسه ارسالکنیم.
پارامتر سوم متن پیام است و پارامتر چهارم مشخصمیکند که این فراخونی بهدلیل دریافت پیام جدید بودهاست یا فشردهشدن کلید ها ، آخرین پارامتر هم حاوی داده ذخیره شده درون کلید است این پارامتر وقتی حاوی مقدار است که کاربر برروی کلید کلیک کردهباشد. درغیراین صورت مقداری نخواهد داشت.
راهاندازی برنامه
#include "Arduino.h" #include <ESP8266WiFi.h> #include <ESP8266WiFiMulti.h> #include "ZeusTgBot.h" #include <EEPROM.h> ESP8266WiFiMulti WiFiMulti; #define Ssid "Your_WIFI_SSID" #define Password "Your_WIFI_PASS" #define Bot_Key "Your_BOT_Key" Zeus_TgBot Bot(Bot_Key); // Witty Cloud Board specifc pins const int LDR = A0; const int BUTTON = 4; const int RED = 15; const int GREEN = 12; const int BLUE = 13; void Tg_Message_Prossess(String mgs_id,String sender_id,String msg,bool is_callback,String Call_ID); uint32_t Command_Run = 0; void setup() { // Add your initialization code here Serial.begin(115200); Serial.print("\n"); //Serial.setDebugOutput(true); // We start by connecting to a WiFi network WiFiMulti.addAP(Ssid, Password); Serial.println(); Serial.println(); Serial.print("Wait for WiFi... "); /*Wait For Connect to Server*/ while(WiFiMulti.run() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.println(); Serial.println("Connect to NetWork .... OK"); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); // Initialize LDR, Button and RGB LED pinMode(LDR, INPUT); pinMode(BUTTON, INPUT); pinMode(RED, OUTPUT); pinMode(GREEN, OUTPUT); pinMode(BLUE, OUTPUT); Bot.Set_Message_Event(&Tg_Message_Prossess); Zeus_TgBot::User_t User; if(Bot.GetMe(&User)) { Serial.println(); Serial.println("Bot Information"); Serial.println("first name: " + User.first_name); Serial.println("last_name: " + User.last_name); Serial.println("username: " + User.username); Serial.println(); } else { Serial.println("Can Not Get Bot Info"); } } void Tg_Message_Prossess(String mgs_id,String sender_id,String msg,bool is_callback,String Call_ID) { String Intor = "ربات تلگرام \n\ \n\با استفاده از این ربات قادر خواهید بود لوازم منزل را از راه دور و با استفاده از تلگرام کنترل کنید.\n\ از منوی زیر یکی از کلید ها را انتخاب کنید."; String keyboardJson = "[[\{ \"text\" : \"مشاهده سایت \", \"url\" : \"https://belec.ir\" \} ]," "[\{ \"text\" : \"عضویت در تلگرام \", \"url\" : \"https://t.me/joinchat/AAAAAEBAGr-XNdPMm3bTIg\" \} ]," "[\{ \"text\" : \"تغییر وضعیت لامپ سبز\", \"callback_data\" : \"Gtg\" \} ]," "[\{ \"text\" : \"تغییر وضعیت لامپ قرمز\", \"callback_data\" : \"Rtg\" \} ]," "[\{ \"text\" : \"تغییر وضعیت لامپ آبی\", \"callback_data\" : \"Btg\" \} ]]"; if(is_callback==true) { /*it's Call Back Data*/ Serial.println("Get CallBack - " + msg); if(msg=="Gtg") /*Command For Green LED*/ { if(digitalRead(GREEN)) { digitalWrite(GREEN, false); Bot.answerCallbackQuery(Call_ID,"لامپ سبز خاموش شد"); } else { digitalWrite(GREEN, true); Bot.answerCallbackQuery(Call_ID,"لامپ سبز روشن شد"); } } if(msg=="Rtg") /*Command For Green LED*/ { if(digitalRead(RED)) { digitalWrite(RED, false); Bot.answerCallbackQuery(Call_ID,"لامپ قرمز خاموش شد"); } else { digitalWrite(RED, true); Bot.answerCallbackQuery(Call_ID,"لامپ قرمز روشن شد"); } } if(msg=="Btg") /*Command For Green LED*/ { if(digitalRead(BLUE)) { digitalWrite(BLUE, false); Bot.answerCallbackQuery(Call_ID,"لامپ آبی خاموش شد"); } else { digitalWrite(BLUE, true); Bot.answerCallbackQuery(Call_ID,"لامپ آبی روشن شد"); } } Intor += "\n\n وضعیت لامپ ها\n"; Intor += "\n سبز: "; Intor += (digitalRead(GREEN)) ? "روشن":"خاموش"; Intor += "\n قرمز: "; Intor += (digitalRead(RED)) ? "روشن":"خاموش"; Intor += "\n آبی: "; Intor += (digitalRead(BLUE)) ? "روشن":"خاموش"; Intor += "\n\nتعداد درخواست های پردازش شده: " + String(Command_Run); Intor += "\n\nسیسوگ"; Command_Run++; Bot.EditMessage(mgs_id, sender_id, Intor, keyboardJson); } else { Serial.println("Get Message - " + msg); Bot.sendMessage(sender_id, Intor, keyboardJson); } } // The loop function is called in an endless loop void loop() { //Add your repeated code here Bot.GetUpdates(); delay(100); }
باتوجهبه توابع موجود، عملکرد و پیادهسازی برنامهکار بسیار سادهای است. ابتدا کافیاست SSID یا اسم وایفای و رمز آن و کلید ربات تلگرامی خود را در ابتدای کد وارد کنید (خطوط 9 و 10 و 11 از برنامه)، بعد برنامه را کامپایل و برروی ESP8266 پروگرام کنید.
فایل های دانلودی موردنیاز
منبع: سیسوگ
[…] […]