;...z@nko!#
;...z@nko!#
خواندن ۱۱ دقیقه·۴ سال پیش

نوشتن ربات CLI تلگرام با زبان PYTHON و با لایبرری pyrogram قسمت سوم

pyrogram
pyrogram


خب سلام دوستان در ادمه ماجرا رسیدیم به قسمت دیلیت کردن پیام هایی که ذخیره کرده بودیم و تو این قسمت میخوایم اپشن del_msg , status و info رو به ربات اضافه کنیم و از یه سری متود جدید هم استفاده میکنم...

در اخر این پست لینک گیت هاب هستش میتونید برید کد هایی که نوشتیم رو ببینید و...




Delete_Message

اولین اپشنی که میخوایم اضافه کنیم دیلیت کردن جمله ها از دیتابیس هستش .

del msg
del msg


مثل همیشه یه هندلر تعریف کردیم و پرایویت چت و یوزر ادمین رو فیلتر کردیم + کامند del_msg و بعد اومدیم چت اکشن فرستادیم برای کاربر و مثل قبل چک کردیم اگر کلید Messages داخل دیتابیسمون بود بیاد به کاربر بگه شماره جملش رو بفرسته تا حذف بشه و یا * رو بفرسته که همه پیام های موجود رو پاک کنیم، اگر هم نبود کلا Messages وجود نداشت داخل دیتابیس بیاد بگه جمله ای وجود نداره .

اینجا ما نمیتونیم حذف بکنیم پیام رو از دیتابیس چرا؟

چونکه باید ورودی بگیریم از کاربر پس میایم مثل add msg که قبلا نوشتیم اینجا هم step بندی میکنیم الان اگر ما جمله ای داخل دیتابیسمون وجود داشت میایم step این del:msg رو برابر 1 قرار میدیم الان کافیه یه هندلر دیگه تعریف کنیم که بیاد پیام کاربر رو بگیره و از دیتابیس حذف بکنه.

اینجا از کاربر خواستیم که عدد مربوط به اون جملش رو بفرسته چونکه سخته کاربر بیاد کل متن رو بنویسه یا کپی کنه... اگه یادتون باشه تو اموزش قبلی ما اومدیم به هر جمله داخل دیتابیس یه شماره دادیم الان جمله هامون اینشکلی ذخیره شده بودن

messages
messages

هر جمله یک عدد قبلش هست که ما از همین عدد برای حذف کردنش از دیتابیس استفاده میکنیم.

خروجی:

del msg tm
del msg tm





Get Message id

del-msg
del-msg


خب یه هندلر تعریف کردیم مثل قبل فقط اینجا چون نمیخواستیم با هندلر قبلیمون که برای گرفتن جمله ها بود قاتی بشه(درواقع نادیده گرفته بشه) اومدیم group رو گذاشتیم 2.

اول مثل قبل چک کردیم که اگر del:msg برابر 1 بود و همچنین پیام کاربر با / شروع نشده بود بیا داخل شرط ، داخل شرط متغیر چت ایدی رو تعریف کردیم و همچنین یه اکشن تایپینگ هم ارسال کردیم بعد اومدیم یه شرط گذاشتیم که اگر پیام برابر بود با * کلا هرچی پیام هست رو از دیتابیس پاک کنه (‌r.delete در ردیس میاد اون کلید رو از دیتابیس پاک میکنه و هرچی ولیو داشته باشه هم پاک میشه) و اگر پیام کاربر * نبود پس یک عدد هستش که اول میایم با استفاده از متود sscan داخل دیتابیس سرچ میکینم؛ این متود یه ارگمان match میگیره که باهاش میتونیم طبق یک الگو اون ولیو رو پیدا کنیم مثلا اینجا ما گفتیم اولش اون عدد کاربر باشه : بعدش هرچی بود بود اینجوری پیام دقیق رو میگیره از دیتابیس و نمایش میده. اینجا میتونید برسی هم بکنید که ببینید چیزی که کاربر میده اول عدد بوده یا علکی پیام فرستاده.(البته مشکلی بوجود نمیاد اگر علکی هم داده باشه چون متود sscan چیزی رو برنمیگردونه پس میره داخل else و به کاربر میگه جمله وجود نداره) برای اینکار چون msg استرینگ هستش msg میتونید داخل یک try و except این عمل رو انجام بدید مثلا int(msg)‌ اگر ValueError داد پس عدد نبوده!....

خروجی :

delete message
delete message





Check Status

خب قسمت بعدی که باید به ربات اضافه کنیم برای status گرفتن هستش فایل قبلی که برای ادمین پنل بود زیاد شده بود برای همین یه فایل به اسم info_section ساختیم و قسمت مربوط به گرفتن status ربات رو اینجا قرار میدم.

ابتدا چیز هایی که نیاز داریم رو import میکنیم:

imports
imports

خب مثل قبل Client, filters و از پلاگین ها هم r , admin رو ایمپورت کردیم اما اینجا 2 تا مورد جدید هستن لایبرری asyncio رو هم ایمپورت کردیم البته اینجا زیاد کاری باهاش نداریم فقط از متود sleepش میخوای استفاده کنیم و اما اون raw که بالا ایمپورت کردیم مربوط به raw متود ها داخل پایرو گرام هستش این مثال رو خواستم با اون بزنم که با این raw متود ها هم اشنا بشید در ادامه بیشتر میگیم...


خب الان بریم قسمت گرفتن وضعیت اکانت رو بنویسیم:«

get status
get status

خب در کد بالا اول اومدیم هندلر مون رو مثل قبل تعریف کردیم و فیلتر هامون رو هم قرار دادیم در ادامه اومدیم چت ایدی رو هم داخل متغیر chat_id ذخیره کردیم چون در ادامه بهش نیاز داریم و بعد از raw متود StartBot استفاده کردیم برای استارت کردن SpamBot ، از این ربات برای چک کردن وضعیت اکانتتون میتونید استفاده کنید اگر محدودیتی چیزی داشته باشه اکانت بهمون میگه.

اما یکم بیشتر راجب raw متود ها حرف بزنیم بعدا به کد برمیگردیم.

زمانی که در پایروگرام بخواید با api تلگرام در سطح پایین( low-level) تری کار کنید میتونید از raw متود ها استفاده کنید در بعضی از موارد ممکن پیش بیاد که نیاز شما با متود های سطح بالا(high-level) برطرف نشه و یا اصلا بخواید برای داشتن سرعت بهتر از raw متود ها استفاده کنید... کار کردن باهاشون یکم ممکنه گنگ باشه اول کار ولی یه مدت باهاشون کار کنید دستتون میاد ... ( همه متود هایی که در سطح بالا داریم ازشون استفاده میکنیم با همین raw متود ها نوشته شدن پس برای همین هم پرفرمنس بهتری رو خواهید داشت با استفاده از این متود ها ولی یکم ممکنه کدتون شلوغ بشه و یکم پیچیده بشه...)

برای اینکه از این متود ها استفاده کنید باید اول ایمپورتشون کنید:

from pyrogram import Client, filters, raw

در تصویر get-status اومدیم از raw متود StartBot استفاده کردیم این متود 4 پارامتر رو به عنوان ورودی میگیره که شامل این 4 مورد میشه:

  • bot(InputUser)
  • peer(InputPeer)
  • random_id(int)
  • star_param

پارامتر اول رباتی که میخواید باهاش کار کنید رو مشخص میکنید ولی مثل قبل نمیتونید بگید ربات x چون دارید low-level کار میکنید و باید چیزی که تغریف شده براش رو بدید بهش که اینجا گفته ورودیش فقط InputUser باید باشه که اگه داکیومنتش رو بخونید میگه inputUser شامل id و access_hash میشه که اینجا باید ست کنید براش ولی پایروگرام برای اینکه یه مقدار کار شما رو راحت تر کنه یه متود گذاشته به اسم resolve_peer که دقیقا این id و access_hash رو بهتون برمیگردونه فقط کافی یوزر نیم یا چت ایدی یا شماره تلفن رو بهش بدید تا بهتون چیزی که میخواید رو بده:

inputUser = client.resolve_peer(&quotSpamBot&quot)

اگر الان inputUser رو پرینت کنید میبینید که در خروجی id و access_hash قرار داره(البته این رو هم بگم اگر میخواید خودتون دستی باز این access_hash , id رو بدید بهش باید از type ها و تایپ InputPeerUser استفاده کنید و اون رو بسازید).

خب پارامتر دوم هم جایی هستش که میخواید به ربات پیام بدید و اون کانورسیشن رو شروع کنید که میتونه گروه باشه یا اینکه پیوی خود ربات باشه اون هم باید حتما بهش InputPeer بدید که باز هم با همین resolve_peer مثل قبلی میتونید انجامش بدید ( اگه اسم گروه بدید بهش میره ربات رو اونجا استارت میکنه اگه داخل گروه نباشه ربات رو add میکنه تو گروه و اگر دست رسی add کردن نداشته باشه ربات، میاد ارور میده بهتون که دست رسی نداره)

پارامتر سوم هم یه عدد رندم هستش برای اینکه پیام قاتی نشه چون low-level کار میکنیم و اگه مثلا یه عد ثابت بدیم دفعه بعدی پیام رو به ربات ارسال نمیکنه چون قبلا کرده برای همین باز یه متود داریم به این شکل :

client.rnd_id()

با استفاده از این متود میتونید id های یونیکی رو بسازید و استفاده کنید دیگه پیام ها id یکسانی نمیگیرن و مشکلی پیش نمیاد به درستی کار خواهد کرد.

و اما پارامتر اخر : خب این پارامتر دستوری هستش که میخوایم ربات انجام بده مثلا میخوایم کامند help/ رو بفرستیم بهش یا start/ یا هر چیزی که اون ربات به عنوان ورودی قبول میکنه از شما. در این مثال ما start رو فرستادیم.

خب یکم ممکنه پیچیده باشه ولی گفتم که یه دیدی داشته باشید به raw متود ها چون خیلی جاها میتونید استفاده کنید و نتیجه بهینه تری رو بدست بیارید....


بعد از اینکه raw فانکشن مون رو ساختیم باید بیایم با استفاده از متود invoke(ورژن های قبلی send) ارسالش کنیم به تلگرام( فقط برای raw متود ها از این متود استفاده میشه):

از ورژن 2.0 اسم این متود به invoke تغیر پیدا کرد.

client.invoke(........)

خود این متود invoke چند پارامتر رو به عنوان ورودی میگیره :

  • data(RawFunction)
  • retries(int)
  • timeout(float)
  • sleep_threshold(float)

اولین پارامتر همین raw فانکشن مون هستش که ساختیم دومین پارامتر هم تعداد تلاش هایی مجدد هستش یعنی چی؟ خب مثلا ما میخوایم اگر دفعه اول به هر دلیلی ارسال نشد ریسپانسی(جوابی) دریافت نکردیم بیاد دوباره ارسال کنه یه عدد رو به عنوان ورودی میدیم بهش، پارامتر سوم هم از اسمش معلومه !! یه زمانی رو صبر میکنه اگر جوابی دریافت نکرد تایم اوت میده و پارامتر اخر هم برای این هستش که مثلا بگیم n ثانیه صبر کن بعد ارسال کند.


خب موارد لازم رو گفتیم الان برمیگردیم به کدمون .

الان اومدیم پیام start رو فرستادیم به ربات و این پیامی که فرستادیم یه ریسپانسی برمیگردونه که داخلش id این پیامی که الان ارسال شده هستش و ما این رو نیاز داریم یکم دیگه میگم چرا...

حالا ما این پیامی که فرستادیم به ربات SpamBot یه جوابی هم باید داشته باشه!! پس باید بیایم اون جوابی که SpamBot بهمون میده رو بگیریم تا بفهمیم اکانت محدودیتی داره یا نه... برای اینکار 2 تا راه دارید اول اینکه بیاید یه هندلر مثل قبل بسازید و فیلتر کنید مثلا یوزر SpamBot رو و پیامی که میده رو دریافت کنید راه دوم هم این هستش که از متود get_messages استفاده کنیم و بیایم دقیقا اون پیامی که ربات داده رو بگیریم الان ما میام از همین مورد دوم استفاده میکینم.

Get Status
Get Status

خب ببینید اینجا اول اومدیم یه چت اکشن ارسال کردیم مثل قبل و بعد اومدیم 1 ثانیه اسلیپ دادیم این اسلیپ برای این هستش که وقتی شما پیام رو میدید و ربات بهتون پیامی رو میده یکم طول میکشه این 1 ثانیه برای همین هستش که صبر کنه تا ربات جواب رو بده بعد بیایم get_messages بکنیم و اون پیامی که ربات فرستاده رو بگیریم.

در ادمه یه متغیر به اسم spambot_msg ساختیم که در واقع اومدیم id مسیجی که فرستادیم به اسپم بات رو + 1 کردیم درواقع ایدی پیامی هستش که قرار اسپم بات برامون بفرسته(داخل تلگرام هر پیامی که میفرستید یه ایدی عددی داره که هربار یکی بهش اضافه میشه حالا چه داخل کانال چه داخل گروه چه پرایویت چت چه پیوی ربات...)‌ و بعد اومدیم از متود get_messages استفاده کردیم برای اینکه پیام رو از اون چت بگیریم در اینجا ما دو ارگمان chat_id و message_ids رو دادیم بهش میتونید لیست مسیج ایدی بدید بهش ولی اینجا ما فقط میخوایم اون پیامی که ربات فرستاده رو بگیریم برای همین همون اون spambot_msg که ساختیم رو میدیم بهش در انتها پیامی که spambot فرستاده رو ما میفرستیم به کاربر(میتونید اینجا از متود فوروارد هم استفاده بکنید مستقیم اون پیام رو از پیوی اسپم بات فوروارد کنید یا از متود copy_message استفاده کنید که در قسمت اخر میگیم...) .

خروجی ربات:

Status-1
Status-1

در تصویر بالا همونطور که میبینید بهم گفته که اکانت برای همیشه لیمیت هستش و در تصویر زیر برای یک اکانت دیگه تست کردیم و میگه که محدودیتی نداره..

Status-2
Status-2

خب به همین شکل میتونید لیستی از اکانت ها رو چک کنید(کار کردن با مولتی اکانت رو هم شاید یه قسمت توضیح دادیم!!) و...




Show info

اپشن بعدی یه قسمت مینویسیم که به ادمین یه اطلاعاتی راجب ربات نشون بدیم :

Show Info
Show Info


اطلاعتی که در بالا میخوایم به ادمین نمایش بدیم شامل گروه های ربات و تعداد کاربران ربات هستش + ایدی ادمین ربات.

در کد بالا اومدیم مثل همیشه هندلر مون رو نوشتیم و کامند info رو فیلتر کردیم و بعد متغیر chat_id رو ایجاد کردیم و همچنین دو متغیر groups و private_chats و مقدارشون رو 0 دادیم .

برای اینکه بفهمیم اکانت مون داخل چند تا گروه عضو هستش یا چنتا پیوی داره... میایم از متود iter_dialogs استفاده میکنیم این متود لیست تمام چت هایی که داریم رو بر میگردونه گروه، پیوی، چنل، ربات...(همه این ها دیالوگ هستن) ولی ما اینجا میخوایم فقط گروه و پراویت چت ها رو داشت باشیم برای همین میایم میگیم تایپ این چت ها برابر سوپرگروه یا گروه عادی بود به اون متغیر groups ما 1 دونه اضافه کن و همچنین اگر تایپش پرایویت چت بود به اون متغیر private_chats ما 1 دونه اضافه کن.

async for dialog in c.iter_dialogs(): if dialog.chat.type in [&quotsupergroup&quot, &quotgroup&quot]: groups += 1 if dialog.chat.type == &quotprivate&quot: private_chats += 1

میتونید این dialog رو هم برای خودتون پرینت کنید قبل از نوشتن شرط و... ک ببینید چه چیزی رو به شما برمیگردونه ( مثل اپدیت ک پرینت میکردیم) .

در ادامه اومدیم پیاممون رو نوشتیم اول تعداد گروه ها بعد تعداد کاربران و در اخر یوزر ادمین رو هم mention کردیم .

برای mention کردن یک یوزر شما یا میتونید از html style یا markdown style استفاده کنید در این لینک میتونید توضیحات کامل و مثال هاش رو ببینید .


خروجی این قسمت :

info-output
info-output


در اینجا میتونید بهش اپشن های دیگه یا رو هم اضافه کنید مثلا کاربران امروز رو بهتون بده یعنی امار امروزش جدا باشه از بقیه روز ها و مواردی مثل این....

یه مورد دیگه هم هستش اونم اینه که ما اینجا فقط پیوی های اون اکانتمون رو ست کردیم برای تعداد کاربران ولی این میتونه درست نباشه برای اینکه دقیق تر باشیم در قسمت بعدی میایم اون پیام هایی که ذخیره کردیم رو به کاربرانی که میان پیوی ربات میفرستیم و همونجا هم داخل دیتابیس اطلاعات اون یوزر ها رو ذخیره میکنیم و بعد اینجا تعداد رو از دیتابیس میگیرم و اینجوری بهتر هستش و امار پیوی های دقیق تری رو خواهیم داشت.



خب تا همینجا برای این قسمت کافی هستش در قسمت بعدی اپشن های دیگه رو هم بهش اضافه میکنیم .


اگر نظری انتقادی پیشنهادی چیزی داشتید میتونید کامنت بزارید✍️



کد هایی که نوشتیم رو هم در لینک زیر میتونید مشاهد کنید :‌

https://github.com/zankoAn/Pyrogram-Bolg-Project


قسمت اول اموزش ربات

قسمت دوم اموزش ربات

قسمت چهارم اموزش ربات<br/>

pythonpyrogramtelegram botbotamp amp
یه بک اند دولوپر پایتون، علاقمه مند به DevOps و دیپ شدن در مباحث مرتبط "-)
شاید از این پست‌ها خوشتان بیاید