اذهب إلى المحتوى

نشرح في هذا المقال طريقة بناء بوت على تليجرام بخطوات سهلة وواضحة، فمنصة تليجرام واحدة من أشهر منصات التراسل الفوري في الوقت الحالي، وهي توفر لنا إمكانية تخزين الرسائل على التخزين السحابي Cloud بدلاً من تخزينها على الجهاز المحلي فقط، كما أنه يدعم التشغيل على عدة منصات، مثل أندرويد و iOS  وويندوز، وأي منصة تدعم نسخة الويب. 

سنتعلم كيفية إنشاء بوت تليجرام خاص بنا بلغة البرمجة بايثون python وإطار عملها Flask، وستكون وظيفة هذا البوت هو عرض صورة رمزية مصغرة avatar من موقع Adorable Avatars، وسننشر البوت على سيرفر مجاني من Heroku.

متطلبات العمل

لإتمام هذا العمل، نحتاج إلى الأمور التالية:

  • تثبيت نسخة بايثون python على جهازنا بالإضافة إلى معرفة أساسيات البرمجة باستخدام بايثون.
  • معرفة بأساسيات التعامل مع إطار العمل فلاسك Flask
  • تثبيت نظام التحكم بالإصدارات Git على جهازنا ومعرفة أساسيات التعامل معه
  • وجود حساب على تليجرام، ويمكن التسجيل مجاناً من هذا الرابط
  • وجود حساب على Heroku، ويمكنك الحصول عليه مجانًا من هذا الرابط
  • فهم كيفية عمل التطبيقات سيكون إضافة جيدة، ولكنه ليس شرطًا ضروريًا، حيث سنشرح معظم النقاط بالتفصيل

ما هو بوت تليجرام

بوت تيليجرام هو برنامج مؤتمت مهمته مساعدة المستخدمين في تلبية احتياجاتهم بأقل قدر من التفاعل مع النظام، وتقديم أفضل النتائج من خلال فهم ما يقوله المستخدم، مما يحسن تجربة المستخدم ويساعده على أتمتة المهام المتكررة وتوفير الوقت والجهد.

برمجيُا يعتمد بوت تلغرام على استخدام واجهة برمجية خاصة بمنصة تيليجرام Telegram Bot API تسمح لنا بالاتصال بخوادم تيلجرام وتنفيذ مهام مختلفة بسرعة وكفاءة، فعندما يتفاعل المستخدم مع البوت عبر إرسال رسالة مثلًا، سيستخدم البوت الواجهة البرمجية لتيليجرام لاستقبال الرسالة وتحليلها وبناءً على المدخلات، يمكن للبوت تنفيذ إجراء معين مثل الرد على الرسالة، أو إرسال إشعار، أو تنفيذ طلبات مخصصة باستخدام منطق برمجي معين أو بلاستعانة بالذكاء الاصطناعي.

خطوات إنشاء بوت تليجرام

لإنشاء بوت تفاعلي على تيليجرام، سنحتاج إلى التواصل مع البوت المسمى BotFather، وهو بوت خاص يُستخدم لإنشاء بوتات أخرى، سنستخدم لذلك الأمر newbot/ والذي سيقودنا إلى الخطوات التالية لإنشاء البوت المخصص:

001 botfather

يجب أن يحتوي البوت على صفتين هما: اسم البوت name و اسم المستخدم للإشارة إلى البوت ومشاركته. بعد اختيار اسم البوت واسم المستخدم الذي يجب أن ينتهي بكلمة bot ، سنتلقى بعدها رسالة تحتوي على رمز الوصول Access Token ومن الضروري الاحتفاظ بهذا الرمز وباسم المستخدم لاستخدامهما لاحقًا.

إعداد بيئة العمل

سنستخدم نظام تشغيل Ubuntu في برمجة بوتنا المخصص، وستعمل معظم الأوامر المذكورة هنا دون مشكلات بالنسبة لمستخدمي نظام تشغيل ويندوز، وفي حال واجهتكم أي صعوبات في إعداد بيئة العمل، يمكن الرجوع إلى لمقالتنا إعداد بيئة العمل للمشاريع مع بايثون، أما بالنسبة لمستخدمي نظام تشغيل Mac، فمن المفترض أن تعمل كل الخطوات بشكل صحيح.

أولاً، دعونا ننشئ بيئة عمل افتراضية لنتمكن من عزل متطلبات مشروعنا عن البيئة العامة للغة بايثون.

$ python -m venv botenv/

الآن، سيكون لدينا مجلد botenv/ يحتوي على جميع مكتبات بايثون التي سنستخدمها. نفعِّل البيئة الافتراضية باستخدام الأمر التالي:

$ source botenv/bin/activate

المكتبات التي نحتاجها لإنشاء البوت هي:

  • إطار عمل Flask وهو إطار عمل ويب صغير مبني بلغة بايثون
  • مكتبة بايثون Python-telegram-bot وهي توفر واجهة برمجية لتليجرام
  • مكتبة بايثون  Requests وهي مكتبة شائعة للتعامل مع طلبات HTTP

يمكننا تثبيت المكتبات أعلاه في البيئة الافتراضية باستخدام أمر pip كالتالي:

(telebot) $ pip install flask 
(telebot) $ pip install python-telegram-bot 
(telebot) $ pip install requests

ستكون هيكلة الملفات فى مجلد مشروعنا كالتالي:

. 
├── app.py 
├── telebot 
│   ├── credentials.py 
│   |   . 
│   |   you can build your engine here 
│   |   . 
│   └── __init__.py 
└── botenv

لنشرح أهمية كل الملفات والمجلدات الخاصة ببنية مشروعنا:

  • app.py: سنكتب فيه الكود الرئيسي لعمل البوت
  • telebot/: يحتوي هذا المجلد على الملفات الخاصة بالبوت
  • credentials.py: نخزن في هذا الملف المتغيرات الحساسة كاسم المستخدم ورمز الوصول
  • init.py: ملف خاص في بايثون يحدد أن المجلد الذي يحتوي عليه هو حزمة Package

سنحتاج في الملف credentials.py، لتعريف ثلاثة متغيرات كما يلي:

bot_token = "here goes your access token from BotFather" 
bot_user_name = "the username you entered"
URL = "the heroku app link that we will create later"

لنعد إلى ملف app.py ونكتب أسطر الكود التالية لاستيراد المكتبات و إنشاء المتغيرات الضرورية:

from flask import Flask, request 
import telegram from telebot.credentials 
import bot_token, bot_user_name, URL  

global bot 
global TOKEN 
TOKEN = bot_token 
bot = telegram.Bot(token=TOKEN)

الآن أصبح لدينا كائن bot سيُستخدام لتنفيذ أي إجراء نحتاجه من البوت. 

الخطوة التالية هي إنشاء تطبيق باستخدام إطار عمل فلاسك Flask كالتالي:

app = Flask(__name__)

نحتاج أيضًا إلى ربط الدوال بموجهات محددة routes لإخبار Flask بما يجب فعله عندما يستدعى عنوان معين.

في مشروعنا، تستجيب دالة الموجّه route function لعنوان URL الذي هو في الأساس {token}/، وهذا هو العنوان URL الذي سيستدعيه تيليجرام للحصول على ردود على الرسائل المرسلة إلى البوت.

@app.route('/{}'.format(TOKEN), methods=['POST'])
def respond():
   # retrieve the message in JSON and then transform it to Telegram object
   update = telegram.Update.de_json(request.get_json(force=True), bot)

   chat_id = update.message.chat.id
   msg_id = update.message.message_id

   # Telegram understands UTF-8, so encode text for unicode compatibility
   text = update.message.text.encode('utf-8').decode()
   # for debugging purposes only
   print("got text message :", text)
   # the first time you chat with the bot AKA the welcoming message
   if text == "/start":
       # print the welcoming message
       bot_welcome = """
       Welcome to coolAvatar bot, the bot is using the service from http://avatars.adorable.io/ to generate cool looking avatars based on the name you enter so please enter a name and the bot will reply with an avatar for your name.
       """
       # send the welcoming message
       bot.sendMessage(chat_id=chat_id, text=bot_welcome, reply_to_message_id=msg_id)

   else:
       try:
           # clear the message we got from any non alphabets
           text = re.sub(r"\W", "_", text)
           # create the api link for the avatar based on http://avatars.adorable.io/
           url = "https://api.adorable.io/avatars/285/{}.png".format(text.strip())
           # reply with a photo to the name the user sent,
           # note that you can send photos by url and telegram will fetch it for you
           bot.sendPhoto(chat_id=chat_id, photo=url, reply_to_message_id=msg_id)
       except Exception:
           # if things went wrong
           bot.sendMessage(chat_id=chat_id, text="There was a problem in the name you used, please enter different name", reply_to_message_id=msg_id)

   return 'ok'

إعداد Webhook

سنستخدم خطافات الويب Webhooks لتنفيذ مشروعنا، فبدلاً من استدعاء الدالة كل ثانية باستخدام الحلقات التكرارية كي نتحقق من وصول رسالة جديدة للبوت، سيعلمنا خطاف  الويب البوت بالتواصل مع الخادم الخاص بنا كلما وصلت رسالة جديدة، مما يوفر استخدام الحلقات التكرارية التي تؤثر على أداء الخادم.

لتحقيق ذلك، سننشئ دالة تقوم بتفعيل Webhook، حيث نطلب من تيليجرام استدعاء رابط معين عندما تصل رسالة جديدة. وسنحتاج لتشغيل هذه الدالة مرة واحدة فقط عند إنشاء البوت، وإذا تغيّر رابط التطبيق، ستحتاج لتشغيلها مجددًا مع الرابط الجديد.

@app.route('/setwebhook', methods=['GET', 'POST'])
def set_webhook():
    # we use the bot object to link the bot to our app which live
    # in the link provided by URL
    s = bot.setWebhook('{URL}{HOOK}'.format(URL=URL, HOOK=TOKEN))
    # something to let us know things work
    if s:
        return "webhook setup ok"
    else:
        return "webhook setup failed"

بهذا نكون قد انتهينا من إعداد خطاف الويب، دعونا ننشئ صفحة رئيسية بسيطة للتحقق من أن الخادم يعمل:

@app.route('/')
def index():
    return '.'

if __name__ == '__main__':
    # note the threaded arg which allow
    # your app to have more than one thread
    app.run(threaded=True)

فيما يلي النسخة الكاملة لملف التطبيق app.py:

import re
from flask import Flask, request
import telegram
from telebot.credentials import bot_token, bot_user_name,URL


global bot
global TOKEN
TOKEN = bot_token
bot = telegram.Bot(token=TOKEN)

app = Flask(__name__)

@app.route('/{}'.format(TOKEN), methods=['POST'])
def respond():
   # retrieve the message in JSON and then transform it to Telegram object
   update = telegram.Update.de_json(request.get_json(force=True), bot)

   chat_id = update.message.chat.id
   msg_id = update.message.message_id

   # Telegram understands UTF-8, so encode text for unicode compatibility
   text = update.message.text.encode('utf-8').decode()
   # for debugging purposes only
   print("got text message :", text)
   # the first time you chat with the bot AKA the welcoming message
   if text == "/start":
       # print the welcoming message
       bot_welcome = """
       Welcome to coolAvatar bot, the bot is using the service from http://avatars.adorable.io/ to generate cool looking avatars based on the name you enter so please enter a name and the bot will reply with an avatar for your name.
       """
       # send the welcoming message
       bot.sendMessage(chat_id=chat_id, text=bot_welcome, reply_to_message_id=msg_id)

   else:
       try:
           # clear the message we got from any non alphabets
           text = re.sub(r"\W", "_", text)
           # create the api link for the avatar based on http://avatars.adorable.io/
           url = "https://api.adorable.io/avatars/285/{}.png".format(text.strip())
           # reply with a photo to the name the user sent,
           # note that you can send photos by url and telegram will fetch it for you
           bot.sendPhoto(chat_id=chat_id, photo=url, reply_to_message_id=msg_id)
       except Exception:
           # if things went wrong
           bot.sendMessage(chat_id=chat_id, text="There was a problem in the name you used, please enter different name", reply_to_message_id=msg_id)

   return 'ok'

@app.route('/set_webhook', methods=['GET', 'POST'])
def set_webhook():
   s = bot.setWebhook('{URL}{HOOK}'.format(URL=URL, HOOK=TOKEN))
   if s:
       return "webhook setup ok"
   else:
       return "webhook setup failed"

@app.route('/')
def index():
   return '.'


if __name__ == '__main__':
   app.run(threaded=True)

الآن يمكننا الانتقال إلى الخطوة التالية، وهي نشر تطبيقنا على منصة Heroku السحابية.

نشر التطبيق على منصة Heroku

نحتاج لإعداد بعض الأمور قبل أن نتمكن من نشر التطبيق. فلا يمكن أن تعرف منصة Heroku ما هي المكتبات التي يستخدمها مشروعنا، لذا علينا إبلاغها باستخدام ملف requirements.txt الذي يتضمن كافة المتطلبات، وننتبه لأن كتابة متطلبات التطبيق بشكل خاطئ من المشكلات الشائعة، لذا نحرص على إنشاء ملف المتطلبات باستخدام pip من خلال الأمر التالي:

pip freeze > requirements.txt

بهذا سيكون ملف المتطلبات جاهزًا الآن.

نحتاج أيضا إلى ملف Procfile الذي يخبر منصة Heroku بكيفية تشغيل تطبيقنا بشكل صحيح، لذا ننشئ ملف Procfile ونضيف إليه السطر التالي:

web: gunicorn app:app

يمكننا كخطوة إضافية إضافة ملف gitignore. إلى مشروعنا حتى لا تُرفع الملفات غير المستخدمة إلى المستودع.

بعدها نتبع الخطوات التالية من لوحة التحكم Heroku dashboard من أجل نشر التطبيق وربطه بالخدمات بشكل صحيح:

  1. ننشئ تطبيق جديد Create new app
  2. بمجرد أن نقوم بذلك، سيعاد توجيهنا إلى صفحة النشر Deploy page
  3. نفتح علامة التبويب Settings في نافذة جديدة وننسخ رابط نطاق التطبيق domain
  4. نلصق النطاق كقيمة للمتغير URL داخل ملف credentials.py.

002 heroku

نعود الآن لعلامة التبويب Deploy ونتابع في الخطوات التالية.

نسجل الدخول إلى Heroku من خلال كتابة الأمر التالي في الطرفية:

$ heroku login

يرجى ملاحظة أن هذه الطريقة قد تتعطل أحيانًا في حالة الانتظار لتسجيل الدخول waiting for login، إذا حدث ذلك، نجرب تسجيل الدخول باستخدام الأمر التالي:

$ heroku login -i

نهيئ مستودع Git في مجلد المشروع من خلال الأمرين التاليين:

$ git init 
$ heroku git:remote -a {heroku-project-name}

ننشر التطبيق كما يلي:

$ git add . 
$ git commit -m "first commit" 
$ git push heroku master

في هذه المرحلة، سنرى تقدم البناء في الطرفية terminal الخاصة بنا. إذا سارت الأمور بشكل جيد، سنحصل على خرج شبيه بالتالي:

remote: -----> Launching...
remote:        Released v6
remote:        https://project-name.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.

الآن سنكمل إعداد webhook، وهو الرابط الذي سيتواصل فيه تطبيقنا مع البوت، ننتقل إلى رابط صفحة التطبيق  أي لرابط النطاق الذي نسخناه سابقًا ونضيف لنهاية الرابط setwebhook/ حتى يكون العنوان شيئًا مشابهًا لما يلي:

 

https://appname.herokuapp.com/setwebhook

إذا رأينا النتيجة webhook setup ok، فهذا يعني أننا جاهزون للبدء والتحدث مع البوت، سنطلب منه إحضار صورة لطيفة بناء على اسمنا وستظهر النتيجة كما في الصورة التالية:

التحدث مع البوت

نصائح وتحسينات

لدينا الآن بوت تيليجرام يعمل على مدار الساعة، دون الحاجة إلى تدخل منا. يمكننا إضافة أي منطق نريده إلى البوت، على سبيل المثال، يمكن جعل البوت أكثر واقعية من خلال إضافة حالة الكتابة typing وإرسال حالة الصورة كما يلي:

عدلنا الأسطر التالية من الدالة ‎‪‭‬respond()

   if text == "/start":
       # print the welcoming message
       bot_welcome = """
       Welcome to coolAvatar bot, the bot is using the service from http://avatars.adorable.io/ to generate cool looking avatars based on the name you enter so please enter a name and the bot will reply with an avatar for your name.
       """
       # send the welcoming message
       bot.sendChatAction(chat_id=chat_id, action="typing")
       sleep(1.5)
       bot.sendMessage(chat_id=chat_id, text=bot_welcome, reply_to_message_id=msg_id)
   else:
       try:
           # clear the message we got from any non alphabets
           text = re.sub(r"\W", "_", text)
           # create the api link for the avatar based on http://avatars.adorable.io/
           url = "https://api.adorable.io/avatars/285/{}.png".format(text.strip())
           # reply with a photo to the name the user sent,
           # note that you can send photos by url and telegram will fetch it for you
           bot.sendChatAction(chat_id=chat_id, action="upload_photo")
           sleep(2)
           bot.sendPhoto(chat_id=chat_id, photo=url, reply_to_message_id=msg_id)
       except Exception:
           # if things went wrong
           bot.sendMessage(chat_id=chat_id, text="There was a problem in the name you used, please enter different name", reply_to_message_id=msg_id)

كما نلاحظ فى الجزء السابق، فقد أضفنا ميزة إظهار حالة أن البوت يكتب typing عندما نكون على وشك إرسال المعلومات النصية للبوت، وأضفنا حالة رفع صورة عندما نكون على وشك إرسال صورة لجعل البوت أكثر واقعية.

يمكن أيضًا تغيير صورة البوت ووصفه من قناة BotFather لإضافة لمسة شخصية وتحسين تجربة المستخدمـ ويمكن العثور على العديد من الأمثلة البسيطة الأخرى لبوتات تليجرام على صفحة python-telegram-bot على GitHub.

تحسين البوت

يمكن تطوير وتحسين هذا البوت وجعله يعمل بالذكاء الاصطناعي AI، كل ما علينا فعله هو دمج منطق الذكاء الاصطناعي في دالة معينة مثل ()respond كي يتمكن البوت من فهم الأسئلة بشكل أفضل والرد عليها بناءً على الذكاء الاصطناعي.

ننشئ الهيكلية التالية ضمن مشروعنا:

.
├── app.py
├── telebot
│   ├── credentials.py
│   ├── ai.py
│   |   .
│   |   you can build your engine here
│   |   .
│   └── __init__.py
└── botenv

نكتب بداخل الملف ai.py الكود التالي لتعريف الدالة التي ستولد رد ذكي بناءً على النص المُدخل:

def generate_smart_reply(text):
    # here we can do all our work
    return "this is a smart reply from the ai!"

نستوردها الآن في app.py:

import re
from time import sleep
from flask import Flask, request
import telegram
From telebot.ai import generate_smart_reply
from telebot.credentials import bot_token, bot_user_name,URL

ثم نستخدمها ببساطة داخل الدالة ‪‬‬‪:respond()

def respond():
   # retrieve the message in JSON and then transform it to Telegram object
   update = telegram.Update.de_json(request.get_json(force=True), bot)

   chat_id = update.message.chat.id
   msg_id = update.message.message_id

   # Telegram understands UTF-8, so encode text for unicode compatibility
   text = update.message.text.encode('utf-8').decode()
   # for debugging purposes only
   print("got text message :", text)
   # here call your smart reply message
   reply = generate_smart_reply(text)
   bot.sendMessage(chat_id=chat_id, text=reply, reply_to_message_id=msg_id)

الآن يمكن جعل البوت يعمل بالطريقة التي نريدها.

الخاتمة

شرحنا في هذا المقال خطوات إنشاء بوت تليجرام بلغة بايثون python يعرض صورة رمزية avatar باستخدام إطار عمل فلاسك Flask وبينا طريقة نشره على سيرفر مجاني من Heroku،  حان دوركم لبناء بوت خاص بكم بأفكار متنوعة.

ترجمة وبتصرف للمقال Building Your First Telegram Bot: A Step by Step Guide لكاتبه Ali Abdel Aal

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...