چگونه ربات تلگرام را برنامه نویسی کنیم
نویسنده : مینا علی زاده | زمان انتشار : 20 اسفند 1398 ساعت 21:52
سلام دوستان . شاید شما هم خواستید یک ربات تلگرام بسازید ، دانشش رو دارید اما متاسفانه هزینه های زیاد ! بنظرتون این اجازه را به شما نمی دهد . یا اینکه کلا نوشتن یک ربات تلگرام برای شما سردرگم کننده است . اگر اینطور هست با ما همراه باشید .
اساس ربات های تلگرام – آموزش برنامه نویسی ربات تلگرام
برای داشتن یک ربات ،ابتدا باید رباتمان را در @botFather ثبت نام بکنیم . توجه کنید که ما فقط ثبت نام انجام میدیم و اطلاعات ظاهری ربات رو تغییر میدیم و بات فادر درباره ی هسته ی ربات کاری انجام نمی دهد . در پایان ثبت نام botfather به ما یک token می دهد .
این توکن بسیار مهم هست و نباید گم شود . ما از طریق این توکن به تمام اطلاعات ربات دسترسی داریم و هر کاری میتوانیم انجام دهیم !
خوب حالا باید ببینیم یک ربات تلگرامی چطور کار میکند ؟
ما قرار است یک صفحه ی مثلا php در این آموزش بسازیم و از طریق این صفحه ، اطلاعاتی که تلگرام برای ما می فرستد را تجزیه تحلیل کنیم و در آخر اگر خواستیم به تلگرام ، اطلاعاتی را ارسال نماییم .
خوب اساس کار ربات های تلگرام چنین است اما برای دریافت اطلاعات جدید ما ۲ راه حل داریم .
راه حل اول به اصطلاح WebHook می باشد . یک صفحه ی تحت وب که هر آپدیت جدیدی که در تلگرام صورت میگیرد، هسته ی تلگرام اطلاعات را برای ما با استفاده از POST ارسال میکند . ما این اطلاعات را تجزیه تحلیل میکنیم و میتوانیم پاسخ هم بدهیم . یکی از بدی های این روش این است که شما باید حتما گواهی SSL داشته باشید که البته در آموزش های آینده یک ربات با استفاده از WebHook برنامه نویسی می کنیم و با استفاده از OpenShift به صورت کاملا رایگان ،آن را پیاده میکنیم .
راه حل دوم به اصطلاح Long Polling می باشد . در این روش تلگرام اطلاعات را برای ما ارسال نمی کند بلکه ما مثلا هر ۵ ثانیه با استفاده از cUrl ، اطلاعات جدید را دریافت میکنیم . خوبی این روش این است که ما حتی روی لوکال هاست هم میتوانیم یک ربات داشته باشیم و بدی این کار این است که ما مثلا اگر هر ۵ ثانیه یک درخواست بفرستیم ، احتمال اینکه در خیلی از درخواست ها ،آپدیت جدیدی وجود نداشته باشد بسیار است و این درخواست ها اضافه اند و فقط سرور را آزار میدهند !
آشنایی با داکیومنت های BOT API تلگرام
تلگرام یک داکیومنت برای Api ها دارد که خیلی از آن استفاده خواهیم کرد .
برای مشاهده ی این داکیومنت در سایت رسمی تلگرام کلیک نمایید .
بهتر است با یک مثال شروع کنیم . فرض کنید میخواهیم با یک درخواست تمام آپدیت های جدید را دریافت کنیم .
آپدیت ها در تلگرام شامل تمام رویداد های جدید می باشد . برای مثال پیام جدید ، کاربر حذف شذه از گروه، فایل جدید و …
ما در این آموزش از روش long Polling استفاده می کنیم . ابتدا باید ربات خود را در botfather بسازیم سپس اطلاعات Token را ذخیره کنیم .
برای دریافت اطلاعات جدید ما باید یک از متد getUpdates استفاده کنیم . اما بهتر است اول با متد ها آشنا شویم .
آشنایی با متد ها در ربات تلگرام
در ربات های تلگرام متد های متعددی وجود دارد .
برای مثال متد getMe .همانطور که در داکیومنت ها می بینید این متد هیچ ورودی ایی ندارد و فقط با دریافت اطلاعات صفحه مد نظر ،به ما مشخصات رباتمان را می دهد .
برای صدا زدن یک متد و دریافت اطلاعات باید اطلاعات صفحه ایی را با الگوی https://api.telegram.org/bot<token>/METHOD_NAME دریافت نماییم .
در اینجا <token> همان توکن ایی است که botFather به ما داده است و METHOD_NAME نام متد ایی است که میخواهیم صدا بزنیم . من برای اینکه قشنگ متوجه شوید یک نمونه آدرس با یک توکن واقعی آماده میکنم که البته در پایان آموزش توکن را تغییر میدهم .
https://api.telegram.org/bot113422787:AAGmxRD5ABzfGlEqMm4f0WzwavrHQeMCiNw/getMe
شما حتما توکن را مانند مثال بالا وارد کنید سپس در آخر هم جای METHOD_NAME عبارت getMe را قرار دهید چون ما میخواهیم این متد را صدا بزنیم .
همین لینک را اگر باز کنید عبارتی مانند عبارت زیر دریافت خواهید کرد :
{"ok":true,"result":{"id":113422787,"first_name":"mhrdev TEST","username":"mhrdevtestbot"}} |
همانطور که می بینید ما یک JSON داریم . در اصل تمام دریافتی های ما از تلگرام JSON می باشد .
خوب در لوکال هاست خود یک فایل به نام bot.php بسازید و اطلاعات زیر را در آن قرار بدهید :
<?php $telegram=json_decode( file_get_contents("https://api.telegram.org/bot113422787:AAGmxRD5ABzfGlEqMm4f0WzwavrHQeMCiNw/getMe") ); if($telegram->ok==true){ echo"<h1>اطلاعات ربات</h1>"; echo"<b>نام کاربری </b>: ".$telegram->result->username; echo"<br/><b> نام ربات </b>: ".$telegram->result->first_name; }else{ echo"مشکلی پیش آمد"; } |
همانطور که می بینید ما ابتدا اطلاعات را با استفاده از file_get_contents دریافت کردیم و json_decode کردیم .
حالت کلی تلگرام برای جواب های ما چنین هست . زمانی که decode انجام میدهیم باید از ok را چک کنیم که اگر true باشد یعنی درخواست ما درست بوده است .
سپس با توجه به نام متد ها اطلاعات را در result قرار می دهد .
میخواهید بدانید هر متد چه اطلاعاتی به ما میدهید؟ باید از داکیومنت متد مد نظر استفاده کنیم .
بیایید خواندن داکیومنت را با هم تمرین کنیم . لینک https://core.telegram.org/bots/api#getme را باز کنید .
همانطور که می بینید این متد ورودی ایی ندارد و فقط اطلاعات ربات را در قالب User به ما بر میگرداند . خوب حالا میخواهیم ببینیم دقیقا چه اطلاعاتی به ما میدهد ؟
first_name ویا username چی هستند ؟
برای این کار ما با Type ها سروکار داریم .
Type – تایپ ها در ربات تلگرام
متد های تلگرام ، پاسخ های بدون نظمی ندارند بلکه در قالب Type ها ، ما میتوانیم پیش بینی کنیم هر متد ، چطور خروجی ایی به ما می دهد .
در مثال قبلی ما گفتیم که خروجی ما در قالب User هست پس باید درباره ی Type User اطلاعات بدست آوریم :
در توضیحات این تایپ آمده که “این تایپ به ما یک ربات یا یک کاربر را نمایش می دهد”
منطقی هست ، getMe نیز قرار است اطلاعات یک ربات را به ما بدهد . خوب حالا باید ببینیم دقیقا چه اطلاعاتی به ما میدهد . حال باید به Field ها توجه کنیم .
۱. id : طبق گقته ی تلگرام این داده از نوع Int می باشد . که ای دی منحصر به فرد کاربر یا ربات می باشد .
۲.first_name: طبق گفته ی تلگرام یک رشته می باشد که نام کوچک ربات یا کاربر را به ما می دهد .
توجه کنید از ۳ و ۴ در بخش توضیحاتشان عبارت Optional آمده است . یعنی امکان دارد یک کاربر ، یا یک ربات نام کاربری یا نام بزرگ را نداشته باشند ( همانطوری که ربات ما نام بزرگ را نداشت ) اما حتما کاربر/ربات ۲ ورودی اول را دارد.
۳.last_name: نام بزرگ کاربر که غیر ضروری هست .
۴.username: که شناسه کاربر می باشد و غیر ضروری است .
ارسال اطلاعات به متد های ربات تلگرام
خوب حالا درباره ی متد هایی میخواهیم صحبت کنیم که باید به آن ها ورودی بدهیم . لینک https://core.telegram.org/bots/api#getupdates را باز کنید.
همانطور که می بینید متد getUpdates دارای ۳ ورودی است که با توجه به این که Optional هستند (ستون required ) اگر آن ها را وارد نکنیم باز تلگرام به ما خروجی می دهد .
یعنی اگر لینک زیر را باز کنیم ( توکن را به توکن رباتتان تغییر دهید ) خروجی را دریافت می کنید .
https://api.telegram.org/bot113422787:AAGmxRD5ABzfGlEqMm4f0WzwavrHQeMCiNw/getUpdates
توجه که اگر result در خروجی بالا برای شما [] می باشد ، کافیست به رباتتان در تلگرام پیام جدیدی بدهید تا result شما خالی نباشد . به اضای هر پیام یک update جدید در result دریافت می شود .
اما فرض کنید می خواهیم به getUpdates ورودی limit را بدهیم . این ورودی طبق توضیحات تلگرام تعداد آپدیت های دریافتی را محدود می کند .
ما برای این کار ها باید از متد POST استفاده نماییم . برای این کار از curl استفاده میکنیم . من از قبل برای این کار ها یک تابع نوشته ام که می توانید استفاده نمایید .
functionmakeCurl($api,$method,$datas=[]){ $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,"https://api.telegram.org/bot{$api}/{$method}"); curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS, http_build_query($datas)); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); $server_output=curl_exec($ch); curl_close($ch); return$server_output; } |
این متد ۳ ورودی دارد . ورودی اول api که همان توکن ربات است . ورودی دوم method که نام متد است و ورودی سوم datas که دیتاهای ورودی متد در قالب آرایه .
برای مثال کد bot.php را به کد زیر تغییر دهید :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php functionmakeCurl($api,$method,$datas=[]){ $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,"https://api.telegram.org/bot{$api}/{$method}"); curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS, http_build_query($datas)); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); $server_output=curl_exec($ch); curl_close($ch); return$server_output; } $api="113422787:AAGmxRD5ABzfGlEqMm4f0WzwavrHQeMCiNw"; $robot=makeCurl($api,"getMe"); $updates=makeCurl($api,"getUpdates",[ "limit"=>1 ]); |
خوب حالا میخواهیم رباتی بسازیم که به هر پیام ما ، عبارت پیام شما دریافت شد را ارسال کند .
آشنایی با روش Long Polling
ما نیاز داریم در هر ۵ ثانیه مثلا آپدیت های جدید را دریافت کنیم . برای این کار از روش زیر استفاده می کنیم .
functiongetUpdates(){ sleep(5); getUpdates(); } getUpdates(); |
در اصل ما یک interval ساختیم .
حالا باید آپدیت های جدید را دریافت کنیم . ما یک متغیر به نام last_updated_id می سازیم که ای دی هر آپدیت را بدست آوریم تا در هر دور حلقه ، آپدیت های قدیمی را تلگرام به ما ندهد .(ما از ورودی offset استفاده می کنیم .)
$last_updated_id=0; functiongetUpdates(){ global$last_updated_id; $updates=json_decode( makeCurl("113422787:AAGmxRD5ABzfGlEqMm4f0WzwavrHQeMCiNw","getUpdates",[ "offset"=>($last_updated_id+1) ]) ); if($updates->ok==true&&count($updates->result)>0){ } sleep(5); getUpdates(); } getUpdates(); |
خوب حالا ما هر آپدیت را داریم و میتوانیم با استفاده از sendMessage به هر پیام reply انجام دهیم .
طبق توضیحات تلگرام sendMessage نیازمند chat_id , text و برای reply کردنreply_to_message_id است .
توجه کنید که هر آپدیت ما Update می باشد .
من برای بدست آوردن chat id مسیر update->message->chat->id را در داکیومنت های تلگرام پیش گرفتم .
من برای بدست آوردنreply_to_message_id مسیر update->message->message_id را در داکیومنت های تلگرام پیش گرفتم .
پایان کار به شکل زیر است :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <?php set_time_limit(0); functionmakeCurl($api,$method,$datas=[]){ $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,"https://api.telegram.org/bot{$api}/{$method}"); curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS, http_build_query($datas)); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); $server_output=curl_exec($ch); curl_close($ch); return$server_output; } $last_updated_id=0; functiongetUpdates(){ global$last_updated_id; $updates=json_decode( makeCurl("113422787:AAGmxRD5ABzfGlEqMm4f0WzwavrHQeMCiNw","getUpdates",[ "offset"=>($last_updated_id+1) ]) ); if($updates->ok==true&&count($updates->result)>0){ foreach($updates->result as$update){ $last_updated_id=$update->update_id; $chat_id=$update->message->chat->id; $message_id=$update->message->message_id; $text="پیام شما رسید ."; makeCurl("113422787:AAGmxRD5ABzfGlEqMm4f0WzwavrHQeMCiNw","sendMessage",[ "chat_id"=>$chat_id, "reply_to_message_id"=>$message_id, "text"=>$text ]); } } sleep(5); getUpdates(); } getUpdates(); |
حالا برای اجرا کردن کد اگر به php دسترسی دارید ( لینوکسی ها منظورم رو میدونند ! و اگر از xamp استفاده می کنید با استفاده از shell )
به آدرس فایل bot.php بروید ( با استفاده از cd ) سپس کامند php -f bot.php را اجرا کنید .
اگر دسترسی ندارید مثل یک صفحه ی عادی در لوکال هاست آن را باز کنید .
برای خاموش کردن ربات هم اگر فایل را در ترمینال اجرا کردید ctrl+c و اگر مانند یک صفحه ی عادی باز کردید ، لوکال هاست خود را restart کنید .
با ارور max_execute_time مواجه شدید ؟
جون قرار است فایل php ما تا ابد اجرا شود نباید برای اجرا محدودیت داشته باشد و حتما باید از set_time_limit(0); در آغاز فایل php استفاده شود .
ادامه کار …
با متد ها و Type ها بیشتر کار کنید و سعی کنید با الگوریتم های زیادی آشنا شویم . روش Long Polling برای ربات های با کیفیت اصلا توصیه نمی شود.
بهتر است با روش WebHook آشنا شوید و با استفاده از OpenShift ، به صورت کاملا رایگان یک ربات با کیفیت بسازید .