تعداد بازدید ها: 2,516
در این مقاله قصد داریم یک بات تلگرام ساده با استفاده از پایتون بسازیم و آن را روی سرور Heroku منتشر کنیم. تلگرام نیز در ظاهر مانند بسیاری از اپلیکیشنهای پیامرسانی دیگر است. این اپلیکیشن خود را به صورت یک برنامه امن، سریع، بدون تبلیغ و غیره تبلیغ میکند. با این وجود، یک ویژگی هست که قطعاً آن را از اپلیکیشنهای مشابه متمایز میسازد و آن باتها هستند.
باتها را میتوان یک حساب کاربری خودکار دانست که میتوانند برخی کارهای جالب برای ما انجام دهند. برای نمونه اگر میخواهید لینکی به یک ویدئوی یوتیوب را در یک گروه به اشتراک بگذارید؛ اما هنوز چنین لینکی ندارید، میتوانید از یک بات کمک بگیرید. بدون استفاده از بات باید مراحل زیر را طی کنید:
- وبسایت یوتیوب را در مرورگر وب خود باز کنید.
- به دنبال ویدئویی که میخواهید به اشتراک بگذارید، بگردید.
- گزینه share via… را انتخاب کنید و امیدوار باشید که اپلیکیشن موردنظرتان در فهرست اشتراک یوتیوب باشد.
- به اپلیکیشن پیامرسانی خود بازگردید و لینک را به اشتراک بگذارید.
البته اغلب ما به این فرایند عادت کردهایم و به خوبی از آن استفاده میکنیم؛ اما اگر بک بات تلگرامی داشته باشید:
- زمانی که در حال ارتباط با افراد مختلف درون اپلیکیشن تلگرام هستید.
- کلمه vid@ را به همراه ویدئویی که دوست دارید یافته و به اشتراک بگذارید وارد میکنید.
- دکمه ارسال را میزنید تا ویدیو به اشتراک گذاشته شود.
مطمئناً موافق هستید که روش دوم بسیار آسانتر و کاربرپسندتر است و به زمان کمتری هم نیاز دارد. این تنها یک نمونه از قابلیتهای باتها است. تلگرام با ایجاد امکان بات به کاربران، کاری بسیار عالی انجام داده است. اگر بپرسید دلیل عالی بودن این امر چیست، باید پاسخ داد که این بهترین روش برای دریافت ایده API ها محسوب میشود.
چگونه اولین بات خود را ایجاد کنیم؟
قبل از هر چیز باید یک حساب در تلگرام داشته باشید. پیشنهاد میکنیم جهت تست مفاهیم پایه از نسخه کلاینت وب تلگرام (+) استفاده کنید.
اپلیکیشن تلگرام را باز کنید و به دنبال عبارت botFather بگردید و چت را آغاز کنید. دستور newbot/ را ارسال کرده و دستورالعملها را پیگیری کنید. پس از تکمیل کردن مراحل اولیه موارد زیر را خواهید داشت:
اینک بات ما ایجاد شده است؛ اما کاملاً منفعل است.
ابتدا باید یک مکالمه با بات خود آغاز کنیم. بخش جستجو را باز کرده و نام بات خود را در آن وارد کنید. با کلیک روی دکمه start/ یک گفتگو با بات خود آغاز کنید. مثلاً چیزی مانند hello را وارد کنید. این پیام مهم است، زیرا نخستین بهروزرسانی بات قرار است دریافت شود.
اگر این نخستین بار است که میخواهید یک API بسازید، میتوانید با استفاده از مرورگر خود به سرعت ایده کلی را دریافت کنید. یک برگه در مرورگر خود باز کنید و به این آدرس (+) بروید. وقتی آدرس فوق را در مرورگر وب خود باز میکنید، یک درخواست به سرور تلگرام ارسال میشود که با JSON به آن پاسخی ارسال میشود. این پاسخ شبیه یک دیکشنری در پایتون است. در واقع باید چیزی مانند زیر را ببینید:
{"ok":true,"result":[{"update_id":523349956, "message":{"message_id":51,"from":{"id":303262877,"first_name":"YourName"},"chat":{"id":303262877,"first_name":"YourName","type":"private"},"date":1486829360,"text":"Hello"}}]} |
اگر مستندات باتها را باز کرده و به متد sendMessage/ مراجعه کنید، متوجه خواهید شد که این متد 2 پارامتر اضافی به نامهای chat_id و text دارد. در نوار جستجوی مرورگر خود میتوانید پارامترها را با استفاده از ? برای پارامتر اول و & برای پیامهای بعدی به همدیگر زنجیره کنید. بدین ترتیب یک پیام به صورت زیر خواهد بود:
/sendMessage?chat_id=303262877&text=test
تلاش کنید با جایگزینی آیدی بات خود به جای کلمه chat_id پاسخی از بات خود دریافت کنید. برای مثال اگر آیدی بات شما به صورت 303262877 باشد، و برای پارامتر text نیز از Hello استفاده کنید، درخواست شما به صورت زیر در خواهد آمد:
https://api.telegram.org/bot<token>/sendMessage?chat_id=303262877&text=Hello
آمادهسازی کدنویسی
اگر روی ویندوز کار میکنید و پایتون روی سیستم شما نصب نیست، میتوانید آن را از این آدرس (+) دریافت کنید. مهم نیست از نسخه 2 یا 3 پایتون استفاده میکنید؛ اما ما در مثالهای زیر از نسخه 3 پایتون استفاده کردهایم.
اگر سیستم عامل شما مک یا لینوکس است، احتمالاً هر دو نسخه پایتون و یا دستکم نسخه 2 آن روی سیستم شما نصب شده است. مرحله بعدی نصب pip است. پایتون 2.7.9 و بالاتر و پایتون 3.4 و بالاتر شامل pip نیز هستند.
اگر روی مک یا لینوکس کار میکنید، احتمالاً pip روی سیستم نصب شده است. این وضعیت را با وارد کردن دستور pip — version در ترمینال میتوانید بررسی کنید. اگر pip نصب نیست میتوانید روی لینوکسهای مبتنی بر دبیان با استفاده دستور زیر آن را نصب کنید:
sudo apt-get install python-pip |
بخش دشوار قضیه این است که نسخههای مختلف پایتون از نسخههای خاص pip استفاده میکنند. روی مک میتوانید از دستورالعملهای این صفحه استکاورفلو (+) استفاده کنید. روی ویندوز باید اسکریپت get-pip.py، را دانلود کرده و با رفتن به دایرکتوری که pip را نصب کردهاید روی cmd، دستور زیر را اجرا کنید:
این دشوارترین بخش قضیه است. سپس باید بستههای مورد نیاز را با استفاده از pip نصب کنید. از دستور زیر استفاده کنید:
مرحله بعدی اختیاری است؛ اما استفاده از آن کمک بزرگی خواهد کرد. برنامه PyCharm را نصب کنید.
کدنویسی
اگر ایده API برای شما روشن شده است و همه ابزارهای مورد نیاز را نیز گردآوری کردهاید، میتوانید یک اسکریپت پایتون بنویسید که به بررسی بهروزرسانیهای بات و پاسخ دادن با متنهای مورد نظر بپردازد.
قبل از هر چیز بات ما باید بهروزرسانیها را بررسی کند. پیام ما میتواند به عنوان جدیدترین بهروزرسانی تلقی شود. با این وجود، getUpdates همه بهروزرسانیهای 24 ساعت اخیر را باز میگرداند. یک اسکریپت کوچک برای دریافت جدیدترین بهروزرسانی ایجاد میکنیم.
import requests url="https://api.telegram.org/bot<token>/" def get_updates_json(request): response=requests.get(request+'getUpdates') returnresponse.json() def last_update(data): results=data['result'] total_updates=len(results)-1 returnresults[total_updates] |
دیکشنری بهروزرسانیها (updates) شامل 2 عنصر ok و results است. بخش result مورد علاقه ما است چون شامل فهرستی از همه بهروزرسانیهایی است که در طی 24 ساعت اخیر دریافت کردهایم.
برای بررسی اطلاعات بیشتر در مورد کتابخانه requests به این آدرس (+) مراجعه کنید. اساسیترین ایده این است که هر زمان بخواهید اطلاعاتی را روی سرور دریافت، بهروزرسانی یا حذف کنید، باید درخواستی برای دریافت پاسخ به سرور ارسال کنید.
در مرحله بعد 2 تابع دیگر اضافه میکنیم. تابع نخست chat_id را از update دریافت میکند و تابع دوم پیامی را ارسال خواهد کرد.
def get_chat_id(update): chat_id=update['message']['chat']['id'] returnchat_id def send_mess(chat,text): params={'chat_id':chat,'text':text} response=requests.post(url+'sendMessage',data=params) returnresponse chat_id=get_chat_id(last_update(get_updates_json(url))) send_mess(chat_id,'Your message goes here') |
به خاطر دارید که پارامترها با استفاده از ? و & به هم زنجیر میشدند. همین وضعیت در مورد افزودن دیکشنری به عنوان پارامتر اختیاری دوم به درخواستهای تابع get/post نیز صدق میکند.
اسکریپت آماده است. با این وجود، هنوز فاصله زیادی با یک اسکریپت کامل دارد. یکی از نواقص اصلی این است که هر بار که میخواهیم یک پیام به بات ارسال کنیم باید آن را اجرا کنیم. این وضعیت را در ادامه اصلاح میکنیم. برای این که بات ما به سرور گوش دهد و بهروزرسانیها را برای آغاز حلقه اصلی دریافت کند باید یک دستور sleep ایمپورت شده از time را درست پس از ایمپورت کردن درخواستها اضافه کنیم:
def main(): update_id=last_update(get_updates_json(url))['update_id'] whileTrue: ifupdate_id==last_update(get_updates_json(url))['update_id']: send_mess(get_chat_id(last_update(get_updates_json(url))),'test') update_id+=1 sleep(1) if__name__=='__main__': main() |
با این که یک timeout به مقدار 1 ثانیه اضافه کردهایم، مثال فوق باید تنها به منظور تست کردن استفاده شود چون مقدار polling آن کوتاه است. این وضعیت برای سرورهای تلگرام مناسب نیست و باید از آن اجتناب کرد. دو روش برای دریافت بهروزرسانیها به وسیله api بات وجود دارد که یکی polling طولانی و دیگری وبهوک است. با این وجود اگر با استفاده از یک متد getUpdates به بررسی بهروزرسانیها بدون هیچ پارامتری بپردازیم، میتوانیم از polling کوتاه استفاده کنیم.
به محض این که شروع به استفاده از mainloop در اسکریپت خود بکنیم باید از polling بلند استفاده کنیم. برای این که اسکریپت ما از polling بلند استفاده کند باید تابع اول را با افزودن پارامتر timeout اصلاح کنیم.
خود timeout باعث نمیشود که اسکریپت ما با فراوانی کمتری به بررسی بهروزرسانیها بپردازد، بلکه timeout تنها در صورتی کار میکند که بهروزرسانی جدیدی وجود نداشته باشد. اگر میخواهید تعیین کنید که بهروزرسانی خاصی قبلاً مشاهده شده است، باید یک پارامتر «افست» (offset) اضافه کنید.
def get_updates_json(request): params={'timeout':100,'offset':None} response=requests.get(request+'getUpdates',data=params) returnresponse.json() |
در حال حاضر، این بات باید بدون اشکال کار کند؛ با این وجود میتوانیم کل کد را اندکی بیشتر اصلاح کنیم. گنجاندن همه تابعهایی که تا به اینجا استفاده کردهایم در یک کلاس ایده مناسبی به نظر میرسد. بنابراین نسخه اصلاح شده باید چیزی شبیه زیر باشد:
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 | import requests import datetime classBotHandler: def __init__(self,token): self.token=token self.api_url="https://api.telegram.org/bot{}/".format(token) def get_updates(self,offset=None,timeout=30): method='getUpdates' params={'timeout':timeout,'offset':offset} resp=requests.get(self.api_url+method,params) result_json=resp.json()['result'] returnresult_json def send_message(self,chat_id,text): params={'chat_id':chat_id,'text':text} method='sendMessage' resp=requests.post(self.api_url+method,params) returnresp def get_last_update(self): get_result=self.get_updates() iflen(get_result)>0: last_update=get_result[-1] else: last_update=get_result[len(get_result)] returnlast_update |
اکنون مرحله نهایی است که متغیرها را اعلان کرده و برخی رفتارها را به بات خود آموزش دهیم. ایده ما ساخت یک بات است که روزی یک بار به شما سلام کند، و بسته به زمان روز، پاسخ متفاوتی بدهد. اگر میخواهید این اسکریپت را امتحان کنید باید import datetime را در خط پس از import requests اضافه کنید و کد زیر را به اسکریپت اضافه نمایید:
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 | greet_bot=BotHandler(token) greetings=('hello','hi','greetings','sup') now=datetime.datetime.now() def main(): new_offset=None today=now.day hour=now.hour whileTrue: greet_bot.get_updates(new_offset) last_update=greet_bot.get_last_update() last_update_id=last_update['update_id'] last_chat_text=last_update['message']['text'] last_chat_id=last_update['message']['chat']['id'] last_chat_name=last_update['message']['chat']['first_name'] iflast_chat_text.lower()ingreetings andtoday==now.day and6<=hour<12: greet_bot.send_message(last_chat_id,'Good Morning {}'.format(last_chat_name)) today+=1 elif last_chat_text.lower()ingreetings andtoday==now.day and12<=hour<17: greet_bot.send_message(last_chat_id,'Good Afternoon {}'.format(last_chat_name)) today+=1 elif last_chat_text.lower()ingreetings andtoday==now.day and17<=hour<23: greet_bot.send_message(last_chat_id,'Good Evening {}'.format(last_chat_name)) today+=1 new_offset=last_update_id+1 if__name__=='__main__': try: main() except KeyboardInterrupt: exit() |
از این جا به بعد هزاران روش برای سفارشیسازی بات وجود دارد. برای نمونه میتوانید از برخی متدهای رسانهای استفاده کنید یا افزودن دکمههای custom را بررسی کنید.
انتشار و استفاده عملی از بات
مرحله نهایی ساخت یک بات واقعی، انتشار آن روی یک سرور است. احتمالاً شما سرور ندارید و قصد هم ندارید سروری بخرید و چنین الزامی هم برای شما وجود ندارد. راهحلهای ابری زیادی وجود دارند که میتوانند از اپلیکیشن شما به صورت رایگان میزبانی کنند. در ادامه روش انتشار این اسکریپت کوچک روی کلود Heroku را آموزش میدهیم.
ابتدا باید یک حساب کاربری در وبسایت گیتهاب داشته باشید. این حساب کاربری در صورتی که به برنامهنویسی علاقهمند باشید یک امر ضروری محسوب میشود. علاوه بر حساب کاربری در گیتهاب باید git را نیز نصب کنید.
برای نصب git دستور زیر را روی لینوکسهای مبتنی بر دبیان اجرا کنید:
sudo apt-get install git-all |
در مورد سیستمهای عامل دیگر نیز میتوانید گیت را برای ویندوز از این آدرس (+) و برای مک از این آدرس (+) دانلود کنید. سپس یک حساب کاربری در Heroku (+) باز کنید. در ادامه Virtualenv را با استفاده از دستور زیر نصب کنید:
اکنون باید اندکی فایلها خود را سازماندهی کنیم. به این منظور یک پوشه ایجاد کرده و در ادامه Terminal/CMD را باز کنید و به پوشه مورد نظر بروید. Virtualenv را در پوشه جدید ایجاد کرده و دستور زیر را وارد کنید:
نام این محیط مجازی اهمیت چندانی ندارد، با این وجود بهتر است به اندازه کافی گویا باشد. به پوشه my_env بروید. در مرحله بعد باید ریپازیتوری گیت خود را کلون کنید. به این منظور دستور زیر را وارد کنید:
git clone https://github.com/yourprofilename/yourreponame
اسکریپت خود را در پوشه کلون گیت قرار دهید. سپس به پوشه my_env بروید و با استفاده از دستور زیر یک محیط مجازی ایجاد کنید:
ویندوز:
لینوکس/مک:
اگر محیط مجازی را با موفقیت فعال کرده باشید، اعلان کنسول شما باید با my_env آغاز شود. در مرحله بعد به ریپویی که کلون کردهاید بروید و یک بار دیگر ماژول requests پایتون را با وارد کردن دستور زیر نصب کنید:
مرحله بعد این است که فهرستی از وابستگیهای Heroku را ایجاد کنید. این کار ساده است و کافی است دستور زیر را وارد کنید:
pip freeze>requirements.txt |
یک Procfile ایجاد کنید. در این فایل دستورالعملهای مورد نیاز برای آنچه میخواهید در اسکریپت انجام دهید را وارد کنید. نام آن باید دقیقاً Procfile و در ویندوز نیز Procfile.windows باشد. این فایل نمیتواند پسوندهایی مانند txt. یا py. یا موارد دیگر داشته باشد. محتوای فایل باید به صورت زیر باشد. دقت کنید که به جای my_bot نام اسکریپت خود را وارد کنید:
فایل init__.py__ را در پوشه خود اضافه کنید. این فایل میتواند خالی باشد؛ اما باید آنجا باشد. دستورهای زیر را برای کامیت و پوش کردن تغییرات ایجاد شده وارد کنید:
git init git add. git commit-m‘shortmessage that describe changes tocommit’ git push-uhttps://github.com/yourusername/nameofrepo |
در مرحله بعد به طور واقع بات را روی سرورهای Heroku منتشر میکنیم. این کار از طریق داشبورد وب Heroku میسر است؛ اما استفاده از رابط خط فرمان نیز آسان است. در ادامه مختصری از مراحلی که برای انتشار بات روی سرورها لازم است را ارائه کردهایم. اگر روی مک یا ویندوز هستید میتوانید CLI را از این آدرس (+) دانلود کنید.
اگر روی اوبونتو کار میکنید از دستورهای زیر استفاده کنید:
sudo add-apt-repository"deb https://cliassets.heroku.com/branches/stable/apt./" curl-Lhttps://cli-assets.heroku.com/apt/release.key | sudo apt-key add- sudo apt-get update sudo apt-get install heroku |
در ادامه دستورهای زیر را وارد کنید:
heroku login heroku create git push heroku master heroku ps:scale web=1 heroku open |
از این لحظه به بعد اپلیکیشن ما روی سرور Heroku قرار گرفته است. اگر به هر دلیلی اپلیکیشن شما کار نمیکند، میتوانید با دستور زیر به بررسی log ها بپردازید:
کدهای خطا در این آدرس (+) موجود هستند. اکانت رایگان هروکو محدودیتهای خاص خود را دارد. هر چند ما هم اینک یک بات با امکانات کامل داریم.
اگر این مطلب برایتان مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی
- مجموعه آموزشهای طراحی و توسعه پروژه های وب
- نظرسنجی با استفاده از ربات در تلگرام — ترفندهای پیامرسان تلگرام
- مجموعه آموزش های برنامه نویسی پایتون
==
آیا این مطلب برای شما مفید بود؟