
مرحبا يا هبر! اسمحوا لي أن أقدم نفسي: اسمي سيرجي أغالتسوف ، وأنا "مبرمج في الحياة". هذا يعني أنني كنت منذ فترة طويلة مدير تكنولوجيا المعلومات ، وليس مبرمجًا على الإطلاق بالمهنة ، لكني أستخدم البرمجة طوال الوقت ، سواء في نشاطي الرئيسي أو هوايتي. كما قال أحد رؤسائي السابقين غالبًا - "Seryoga! لقد انزلقت مرة أخرى إلى البرمجة!" صحيح ، لا أستطيع أن أقول أنه أو أي شخص آخر لم يكن راضيًا عن هذا.
بعد ظهور واجهة برمجة تطبيقات Bot على برنامج TamTam messenger ، قمت ، كمبرمج حقيقي ، وبالتالي كسول ، بإنشاء مكتبتي Python للعمل معها:
- open Client API (المشار إليها فيما يلي - OAC) - تم إنشائها مبدئيًا باستخدام OpenAPI Generator استنادًا إلى مخطط API ، ثم تكييفها مع مراعاة ميزات المولد ؛
- shell لهذا العميل هو TamTamBot (المشار إليه فيما يلي - TTB) ، مما يبسط العمل مع OAC.
لذلك كان هناك بعض TamTam Python SDK.
لقد فعلت ذلك أولاً وقبل كل شيء "لنفسي ، من أجل الروح" ، لكنني اقترحت أيضًا أن يستخدمه مجتمع TamTam ، إذا رغبت في ذلك. لكن ، كما تعلمون ، ليس هناك عمل صالح واحد يمر دون عقاب - حيث طلب من الناس كتابة مقال تدريبي. وهنا أنا مع هذا المقال. في ذلك ، سوف أخبرك عن كيفية تطوير روبوت بسيط باستخدام هذه المكتبات.
مهمة
تطوير روبوت مصممة لتبسيط إجراءات مطوري الروبوت. يجب أن يعمل الروبوت في وضع الاقتراع الدائم للدولة bot-api (الاقتراع الطويل). في هذه المقالة ، سيتم تدريب الروبوت على إظهار العناصر الداخلية للرسالة المرسلة إليه ، وكذلك تكوينه لمطابقة الوظيفة المطورة.
من المعلوم أن القارئ قام بتثبيت Python 3 ، git ، المتصل ببيئة تطوير PyCharm (قد تكون بيئة التطوير مختلفة ، ولكن القصة ستعتمد على PyCharm). فهم أساسيات OOP أمر مرغوب فيه.
الحصول على رمزية الروبوت
يتم الحصول على الرمز المميز من خلال مكالمة إلى الروبوت المتخصص PrimeBot
نجد هذا الروبوت في TamTam ، أدخل الأمر / create والإجابة على الأسئلة:
- أدخل الاسم القصير الفريد للروبوت بالأحرف اللاتينية - هذا هو اسم المستخدم للروبوت الذي سيكون متاحًا عبر @ أو بواسطة رابط النموذج
https://tt.me/username
. لا توجد قيود خاصة على اسم المستخدم. على وجه الخصوص ، كلمة بوت هو اختياري. - أدخل اسمًا - هذا هو اسم العرض الخاص بالبوت. هنا يمكنك بالفعل استخدام الأبجدية السيريلية.
إذا تم إدخال كل شيء بشكل صحيح ، ستتم إضافة الروبوت الذي تم إنشاؤه إلى جهات الاتصال وفي المقابل سنحصل على رمز مميز - سلسلة من الأحرف في النموذج: HDyDvomx6TfsXkgwfFCUY410fv-vbf4XVjr8JVSUu4c.
الإعداد الأولي
عرضإنشاء دليل:
mkdir ttBotDevHelper
اذهب إليها:
cd ttBotDevHelper/
نحن تهيئة مستودع بوابة:
git init
قم بتنزيل المكتبات اللازمة ، وإضافتها باعتبارها وحدات فرعية من بوابة:
git submodule add https://github.com/asvbkr/openapi_client.git openapi_client git submodule add https://github.com/asvbkr/TamTamBot.git TamTamBot
نفتح الدليل الذي تم إنشاؤه في PyCharm (على سبيل المثال ، من المستكشف ضمن قائمة السياق "Open Folder as PyCharm project") وننشئ ملفًا سيحتوي عليه الروبوت الخاص بنا - File / New / Python. في مربع الحوار الذي يظهر ، أدخل الاسم - ttBotDevHelper ، ثم أجب بشكل إيجابي على سؤال الإضافة إلى git.
نحن الآن بحاجة إلى إنشاء بيئة افتراضية لمشروعنا.
لإنشاء بيئة افتراضية ، حدد ملف / إعدادات وحدد المفتاح الفرعي لمترجم المشروع في علامة تبويب المشروع. بعد ذلك ، على اليمين ، انقر فوق رمز الترس وحدد إضافة:

ستقدم PyCharm خيار الإقامة الخاص بها.

من المنطقي أن نتفق معه.
بعد إنشاء البيئة الافتراضية ، سيتم فتح الشاشة السابقة ، لكنها ستتضمن بالفعل معلومات حول البيئة التي تم إنشاؤها. في هذه الشاشة ، تحتاج إلى تثبيت الحزم اللازمة من خلال النقر على أيقونة "+" على اليمين وإدخال أسماء الحزمة:
ثم نضيف ملف .gitignore إلى المشروع ، باستثناء الملفات غير المطلوبة في git ، مع المحتويات التالية:
venv/ .idea/ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class *.log *.log.* .env ttb.sqlite3
أضف متغير البيئة المسمى TT_BOT_API_TOKEN
، حيث نشير إلى قيمة الرمز المميز TT_BOT_API_TOKEN
الذي تم استلامه من https://tt.me/primebot وأعد تشغيل PyCharm.
(!) بدلاً من إضافة متغير بيئة مباشرة إلى بيئة نظام التشغيل ، يستخدم PyCharm بشكل أمثل ملف .env خاص. سيتم مناقشته التكوين أدناه.
مبروك ، الآن يمكنك المتابعة إلى الجزء الأكثر إثارة للاهتمام - كتابة روبوتك.
إطلاق بوت بسيط
افتح الملف ttBotDevHelper.py واكتب الأسطر الأولى:
هنا نقوم بإنشاء فئة الروبوت لدينا بناءً على فئة TamTamBot.
يقترح PyCharm أن تحتوي فئة BotDevHelper على طرق مجردة تحتاج إلى تنفيذها. اضغط على المفتاح Alt-Enter في اسم الفصل الدراسي ، وحدد "تطبيق الأساليب المجردة" ، وحدد جميع الطرق (2 منها) التي اقترحها PyCharm وانقر فوق "موافق". نتيجة لذلك ، سيتم إضافة طريقتين خاصية فارغة: الرمز المميز والوصف. نقوم بتعديل الكود الناتج كما يلي:
تقوم خاصية token
بإرجاع الرمز المميز لبرنامج TT_BOT_API_TOKEN
الخاص بنا ، والذي يتم الحصول على القيمة من متغير البيئة TT_BOT_API_TOKEN
. تقوم خاصية description
بإرجاع وصف ممتد لبوت ، والذي سيتم عرضه على المستخدمين.
هناك حاجة إلى رمز في نهاية الملف لتشغيل الروبوت لدينا في وضع الاقتراع الحالة.
ألاحظ أن الفئة الأساسية TamTamBot
تتضمن استخدام خادم الويب django للعمل في وضع ربط الويب. لكن المهمة أصبحت الآن أكثر بساطة ، ولا نحتاج إلى django ، وهو ما نبلغ عنه في set_use_django(False)
. هنا ، يتم استدعاء طريقة polling()
للكائن من صفنا ، والذي يضمن التشغيل في الوضع المطلوب.
يتم الحد الأدنى الضروري. هذا الرمز هو بالفعل تعمل تماما. تشغيله لتشغيل. للقيام بذلك ، اضغط على تركيبة المفاتيح Ctrl-Shift-F10.
إذا لم تقم بإضافة متغير بيئة سابقًا ، مباشرة إلى نظام التشغيل ، فسيحدث خطأ عند ظهور رسالة "No access_token" عند بدء التشغيل. لإصلاحه ، قم بتكوين PyCharm لاستخدام ملف .env.
اظهار كيفقم بإنشاء ملف نصي .env. يجب أن يكون محتواه في حالتنا كما يلي:
TT_BOT_API_TOKEN=__
تحتاج الآن إلى توصيله بتكوين الإطلاق في PyCharm:
نختار تشغيل / تحرير التكوين وعلى علامة التبويب EnvFile نقوم بتوصيل ملف .env لدينا:

ثم انقر فوق تطبيق.
بعد بدء الروبوت ، يمكنك الذهاب إلى TamTam ، وفتح حوار مع الروبوت لدينا والنقر على زر "ابدأ". سيقدم الروبوت معلومات حول القوى العظمى المخفية. هذا يعني أن الروبوت يعمل. بينما يعمل الروبوت في الوضع التجريبي ، تتوفر فيه 4 أوامر. فقط تحقق منها.
على الرغم من الرأي الواضح للبوت حول رباطة جأشته ، فإنه يلمح بخجل إلى حقيقة أنه حتى الآن لا يستطيع فعل أي شيء. مهمتنا هي أن نعلمه كل ما هو ضروري لغزو العالم.
تلقي رسالة مصدر وإرسال رسالة استجابة مع تمثيل داخلي للرسالة المصدر
receive_text()
طريقة receive_text()
، والتي يتم نقل السيطرة عليها عند إرسال نص إلى الدردشة مع الروبوت:
def receive_text(self, update): res = self.msg.send_message(NewMessageBody(f' : {update.message}', link=update.link), user_id=update.user_id) return bool(res)
يحتوي كائن update
الخاص UpdateCmn
، والذي يتم تمريره إلى هذه الطريقة ، على العديد من المعلومات المفيدة ، وعلى وجه الخصوص ، كل ما نحتاج إليه الآن:
update.message
- كائن يحتوي على الرسالة نفسها ؛update.link
- رابط استجابة جاهز لهذه الرسالة ؛update.user_id
- معرف المستخدم الذي أرسل الرسالة.
لإرسال رسالة من self.msg
، self.msg
المتغير self.msg
، الذي يحتوي على كائن MessagesApi
الذي ينفذ الوظيفة الموضحة في قسم الرسائل في وصف API . يحتوي هذا الكائن على أسلوب send_message()
الذي send_message()
، والذي يوفر إرسال الرسائل. كحد أدنى ، يجب أن يتم تمرير هذه الطريقة كائن من فئة NewMessageBody
والوجهة - معرف المستخدم ، في حالتنا.
بدوره ، يتم إنشاء كائن من فئة NewMessageBody
في هذه الحالة عن طريق إرسال تمثيل نصي لكائن الرسالة المصدر ورابط استجابة للرسالة المصدر.
نقوم بإعادة تشغيل برنامج الروبوت الخاص بنا ونفحص حوارًا مع برنامج الروبوت الذي يقوم البرنامج بإنشاء رد على أي من رسائلنا التي تحتوي على التمثيل الداخلي لكائن الرسالة المصدر.
شفرة المصدر لهذه الحالة هنا .
إضافة أمر bot جديد مع معلمة - يُظهر التمثيل الداخلي للرسالة بمعرفها
عند تطوير برامج الروبوت ، غالبًا ما يلزم النظر إلى التمثيل الداخلي للرسالة باستخدام معرّف واحد أو أكثر من معرّفات الرسائل المعروفة (معرف الرسالة - منتصف). إضافة هذه الوظيفة إلى الروبوت لدينا. للقيام بذلك ، أولاً ، نأخذ بطريقة منفصلة وظيفة إخراج المعلومات حول التمثيل الداخلي للرسائل:
def view_messages(self, update, list_mid, link=None): res = False msgs = self.msg.get_messages(message_ids=list_mid) if msgs: for msg in msgs.messages: r = self.msg.send_message(NewMessageBody(f' {msg.body.mid}:\n`{msg}`'[:NewMessageBody.MAX_BODY_LENGTH], link=link), user_id=update.user_id) res = res or r return res
في هذه الطريقة ، نمرر قائمة منتصف.
للحصول على كائنات الرسائل ، نستخدم طريقة self.msg.get_messages
، والتي تُرجع قائمة الكائنات في خاصية الرسائل.
علاوة على ذلك ، يتم إرسال تمثيل نصي لكل رسالة من الرسائل المستلمة إلى حوارنا في رسائل منفصلة. لتجنب الأخطاء ، يتم اقتطاع نص الرسالة التي تم إنشاؤها بواسطة ثابت الحد الأقصى لطول الرسالة - NewMessageBody.MAX_BODY_LENGTH
.
ثم أضف طريقة تعالج الأمر. دعنا نسميها vmp . يمكنك تمرير القائمة المتوسطة إلى الأمر بمسافة.
تم تصميم TTB بحيث يجب إنشاء معالج الأوامر كطريقة تحمل الاسم cmd_handler_%s
، حيث٪ s هو اسم الأمر. أي بالنسبة للأمر vmp ، سيتم استدعاء الطريقة cmd_handler_vmp
. يتم تمرير كائن من فئة UpdateCmn
إلى معالج الأوامر. بالإضافة إلى ذلك ، بالنسبة لأحد الأوامر ، قد يحتوي على خاصية cmd_args
، والتي تحتوي على قاموس للخطوط والكلمات التي تم إدخالها فيها باستخدام الأمر.
سيبدو الرمز كالتالي:
def cmd_handler_vmp(self, update): res = None if not update.this_cmd_response:
نحن إعادة تشغيل الروبوت. الآن ، إذا /vmp mid1 mid2
حوار bot مثل: /vmp mid1 mid2
(يمكنك /vmp mid1 mid2
) ، في المقابل ، نحصل على رسالتين مع تمثيل داخلي لكائنات الرسالة المصدر ، لكل من منتصف الإرسال.
شفرة المصدر لهذه الحالة هنا .
تعديل أمر بوت للعمل مع استجابة نصية
يمكنك أيضًا محاولة إعادة توجيه الرسالة من قناة / دردشة أخرى. ولكن في هذه الحالة ، سيتم عرض فقط ما هو موجود في الرسالة المصدر في حوار مع الروبوت. على وجه الخصوص ، عند إرسال رسالة ، لا يتم حفظ معلومات الزر.
ولكن ماذا لو كنا نريد أن نرى معلومات حول الرسالة الأصلية؟ في هذه الحالة ، تحتاج إلى اتخاذ منتصف من الرسالة المعاد توجيهها.
لتطبيق هذا الوضع ، نقوم بتعديل أمر vmp بحيث عندما يتم استدعاؤه بدون معلمات ، فإنه يتوقع إعادة توجيه الرسالة ، وبعد ذلك يستغرق منتصف الرسالة المرسلة ويعرض معلومات عنها.
(!) للتشغيل الصحيح لهذه الوظيفة ، يجب منح الروبوت إذنًا للقراءة من مصدر القناة / الدردشة.
نقوم بتعديل رمز الأمر كما يلي:
def cmd_handler_vmp(self, update): res = None if not update.this_cmd_response:
ومنذ ذلك الحين مع هذا النهج ، تزداد المخاطر بسبب عدم إمكانية الوصول إلى الرسائل ، ثم في طريقة view_messages()
نضيف التحقق من الامتثال لعدد الرسائل المطلوبة / المستلمة:
def view_messages(self, update, list_mid, link=None): res = False msgs = self.msg.get_messages(message_ids=list_mid) if msgs:
نحن نعيد تشغيل الروبوت ، ونمنح الأمر / vmp ، وبعد عرض المطالبة بضرورة إعادة التوجيه ، نقوم بإعادة توجيه الرسالة من القناة / الدردشة. إذا كان لدى الروبوت حقوق قراءة الرسائل في هذه القناة / الدردشة ، فسيتم عرض تمثيل نصي لكائن الرسالة المعاد توجيهها. إذا لم يكن هناك وصول ، فسيقوم الروبوت بالإبلاغ عن مشكلة محتملة وسينتظر إعادة التوجيه من المصدر الصحيح.
تحديد خصائص الروبوت
الآن يبقى لتحقيق لمعان. دعنا نغلق الخاصية about
، والتي تُرجع النص الذي يعرضه الروبوت عندما يبدأ العمل ، وكذلك الأمر / start.
@property def about(self): return ' .'
get_commands()
طريقة get_commands()
، والتي تعرض قائمة أوامر برنامج get_commands()
، والتي تظهر في مربع الحوار مع برنامج الروبوت.
def get_commands(self):
دعنا نوقف تشغيل خاصية main_menu_buttons ، التي تعرض قائمة الأزرار في القائمة الرئيسية ، والتي يطلق عليها أمر / menu.
def main_menu_buttons(self):
نحن إعادة تشغيل الروبوت ، تأكد من أن كل شيء في محله. تهانينا ، تم إنشاء روبوتك الأول ، وعلى الرغم من وجود بعض الألعاب ، فقد تطلب وظائفه تمامًا.
شفرة المصدر لهذه الحالة هنا .
@ بوت ديفلبوت العامل يمكن رؤيته هنا .
هذا كل شيء الآن. إذا كان الموضوع موضع اهتمام ، فعندئذٍ في المقالات التالية ، يمكنني النظر في مزيد من التطوير للبوت. على سبيل المثال ، إضافة أزرار مخصصة (على وجه الخصوص ، نعم / لا) ومعالجتها ، وإرسال أنواع مختلفة من المحتوى (ملفات ، صور ، وما إلى ذلك) ، والعمل في وضع webhook ، إلخ.
بالمناسبة ، يمكنك طرح الأسئلة بسرعة في دردشة خاصة . اقتراحات / أفكار مباشرة هناك.