جرعت و حقیقت با اُسکُلَک :)))

  • شروع کننده موضوع
  • مدیر
  • #1

ememlia

⁦(⊙_◎)⁩
عضو مدیران انجمن
ارسال‌ها
856
امتیاز
19,972
نام مرکز سمپاد
شهید بهشتی
شهر
.
سال فارغ التحصیلی
1397
سلام ... بازم من :)
چند روزیه ک با بچه ها قرار گذاشتیم ج.ح بازی کنیم (با تشکر از نسیم و بقیه دست‌اندر کار ها :) )
دیروز راجب اینکه چطور بازی کنیم داشتیم حرف میزدیم و پیشنهاد ساختن بات اختصاصی مطرح شد (با تشکر از آرمین :) )
خب من ک اصن اینکاره نیستم یکم پایتون بلدم و اینترنت نسبتا خوبی دارم .... با خودم فک کردم مگه چقد میتونه سخت باشه ها .... کامان خوش میگذره

قسمت اول
خب اصن دنبال چی میگردیم؟
یه بات میخوایم ک بازیکنارو بگیره -> رندوم دونفرو مقابل هم قرار بده
امکان تایید بازیکنا وجود داشته باشه -> یعنی هرکسی نتونه به بازی وارد بشه
ادمین بتونه کاربر ب بازی اضافه / حذف کنه
کاربر بتونه تو بازی شرکت بکنه/نکنه
فعلا همینا کافیه
قسمت یک و نیم
اسکلک ینی اسکل و کوچک
فانه
منم تو انتخاب اسم بد سلیقه ام :)
قسمت دوم
خب بات های تلگرام از api استفاده میکنن -> یعنی منطقا با هرزبونی میشه واسش بات نوشت
و فریمورک ها و کتابخونه ها کارمون رو خیلی راحت میکنن
و واسه اینجور پروژه ها من ب پایتون علاقه دارم
-------
پایتون چنتا کتابخونه واسه api تلگرام داره
من python-telegram-bot رو انتخاب کردم چون قبلنا یکم باهاش بازی کرده بودم
ولی احتمالا انتخاب های بهتری هم وجود داره
قسمت سوم
قدم اول استفاده از هرچیزی نصب اونه -> مث آدم تو ترمینال مینویسیم :
کد:
(sudo) pip3 install --user python-telegram-bot
یا از ریپازیتوری گیتهابش دانلود و نصبش کنیم:
https://github.com/python-telegram-bot/python-telegram-bot
کد:
git clone https://github.com/python-telegram-bot/python-telegram-bot.git
cd python-telegram-bot
python3 setup.py install
ب هرحال وقتی تموم شد احتیاج ب داکیومنتاش داریم ک بفهمیم باید چجوری ازش استفاده کنیم:
https://python-telegram-bot.readthedocs.io/en/stable/داکیومنت خیلی خسته و مفصلی داره
قسمت چهارم
تلگرام رو درنظر بگیرین ک تو آسموناس
سروری ک بات ما رو ران میکنه هم تو آسمونه
من و شما ک رو زمینیم چطور باید با بات ارتباط بگیریم؟
این ارتباط رو تلگرام درست میکنه ولی لازمه ک تلگرام بتونه بات مون رو بشناسه
ربات botfather واسه ما ربات میسازه و بهمون یه توکن میده ک بتونیم ازش تو برنامه مون استفاده کنیم
19-min-19-232x405.png

این توکن رو باید محرمانه نگهش داریم :)
قسمت پنجم
برنامه رو ب دوفایل تقسیم کردم
تو app.py منطق برنامه رو مینوسیم
و تو config.py کانفیگ ها و استرینگ ها و ... میزارم
اول یه برنامه بنویسیم ک وقتی استارت کردیم یه خوشآمد بهمون بگه :
Python:
from telegram.ext import Updater, CommandHandler
from config import *

updater = Updater(TOKEN)

def start(bot, update):
    bot.sendMessage(update.message.chat_id, startMessage)
   
start_command = CommandHandler('start', start)
updater.dispatcher.add_handler(start_command)

updater.start_polling()
updater.idle()

updater توکن مارو میگیره و ارتباط ما با سرورمونو برقرار میکنه
متود استارت اینجوره ک وقتی صدا زده میشه استارت مسیج رو(ک تو کانفیگ تعریف شده) ب همون کاربر میفرسته
commandHandler متود استارت رو به کامند /start متصل میکنه
منطقا باید کار کنه ولی نمیکنه :)‌)) چرا؟
تو کشور عزیز ما تلگرام مث خیلی جاهای دیگه :) فیلتره
من یه فیلتر شکن tor تو پورت ۹۰۵۰ کامپیوترم دارم ک از نوع socks5 عه ..... با یکم گشتن تو نت پیدا میکنم چطوری باید ترافیک بات رو ازون پورت منتقل کرد:
Python:
#for iran internet :)
REQUEST_KWARGS={
    'proxy_url': 'socks5://127.0.0.1:9050'
}

updater = Updater(TOKEN, request_kwargs=REQUEST_KWARGS)
----------
#for real internet
updater = Updater(TOKEN)
فیلترینگ رو دور زدیم و حالا برنامه مون بهمون خوشامد میگه :)

قسمت شیشم
توی گروه باید بتونیم بات رو صدا بزنیم و ازش بخوایم بازی شروع کنه
بهش میگن InlineQuery
داکیومنت هاشو باید خوند هرچند یکم گیج کننده اس:
کد:
from telegram.ext import Updater, CommandHandler, InlineQueryHandler
from telegram.ext import CallbackQueryHandler
from telegram import InlineQueryResultArticle, InputTextMessageContent
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from uuid import uuid4

def startInlineQuery(bot, update):
    query = update.inline_query.query
    results = list()
    keyBoard = [[InlineKeyboardButton(inBtn, callback_data="start")]]
    keyBoard2 = [[InlineKeyboardButton("قرعه کشی ", callback_data="choice")]]
    keyBoard3 = [[InlineKeyboardButton("آره ", callback_data="rest")]]
    results.append(InlineQueryResultArticle(id = uuid4(), title="شروع بازی جدید", reply_markup=InlineKeyboardMarkup(keyBoard), input_message_content=InputTextMessageContent(inMessage)))
    results.append(InlineQueryResultArticle(id = uuid4(), title="قرعه کشی :) ", reply_markup=InlineKeyboardMarkup(keyBoard2), input_message_content=InputTextMessageContent(readyForChoice)))
    results.append(InlineQueryResultArticle(id = uuid4(), title="ریست کردن نوبت ها ", reply_markup=InlineKeyboardMarkup(keyBoard3), input_message_content=InputTextMessageContent(readyForReset)))
    results.append(InlineQueryResultArticle(id = uuid4(), title="همه رو خبر کن :)) ", input_message_content=InputTextMessageContent('  '.join(accepted_users))))
    results.append(InlineQueryResultArticle(id = uuid4(), title="من کی ام؟ ", input_message_content=InputTextMessageContent(whoAmI)))
    bot.answerInlineQuery(update.inline_query.id, results=results)
تو داکیومنت گفته ک اینلاین کوعری! ها باید تو یه لیست باشن واسه همین لیست result رو ساختم
همچنین سه تا از پنج تا اینلاین ها احتیاج ب دکمه دارن و باید کیبوردشونو تو یه لیست دو بعدی تعریف کرد(طبق داکیومنت)
واسه کیبورد ها کال بک گذاشتم ک وقتی کلیک شدن یه دیتا واسمون بفرستن ک ادامه کارو انجام بدیم
کال بک رو مینویسیم:
Python:
users = list()

def userHandler(bot, update):
    query = update.callback_query
    #import pdb; pdb.set_trace()
    if query.data == "start":
        user_name = query.from_user.username
        keyBoard = [[InlineKeyboardButton(inBtn, callback_data="start")]]
        if not("@"+user_name in users) and ('@'+user_name in accepted_users):
            users.append("@"+user_name)
            query.answer(addPlayer)
        else:
            if "@"+user_name in accepted_users:
                query.answer(youAreIn)
            else:
                query.answer(notPermision)
        query.edit_message_text(inMessage + "\n \n" +afterGetIn+ "\n" + "\n".join(users),reply_markup = InlineKeyboardMarkup(keyBoard))
    elif query.data == "choice":
        query.edit_message_text(rand_choice_result())
    elif query.data == "reset":
        for i in users :
            users.remove(i)
        query.edit_message_text(afterReset)
چون بات شخصیه و تنها یوزر هاش خودمونیم فعلا لازم نیس دیتابیس درست کنم
یه آرایه users درست کردم ک بازیکن هارو تو همون ذخیره میکنیم (درواقع تو رم ذخیره میشن)
توی کانفیگ هم یه آرایه از یوزرنیم بچه های گروه درست کردم و فقط همونا میتونن تو بازی شرکت کنن :)
بقیه اش دیگه بازی با کاندیشناس و توضیح خاصی نداره
واسه اینکه کالبک و اینلاین مون کار کنه باید به updater بدیمشون :
Python:
startInline = InlineQueryHandler(startInlineQuery)
user = CallbackQueryHandler(userHandler)

updater.dispatcher.add_handler(startInline)
updater.dispatcher.add_handler(user)
حالا باید یه تابع بنویسیم ک رندوم یوزر های مقابل هم بزاره :
Python:
from random import choice

def rand_choice_result():
    #import pdb; pdb.set_trace()
    if len(users) > 1:

        p1 = choice(users)
        users.remove(p1)
        p2 = choice(users)
        users.remove(p2)
        result = randCoice.format(p1,p2)
        return result
    else:
        return noPlayer
اگه تعداد یوزر هایی ک هنوز نوبتشون نشده کمتر از ۲ نفر باشه بازی تموم میشه :)
قسمت هفتم
حالا یسری ادمین باید مشخص کنیم تا بتونن به بات یوزر اضافه/کم کنن
یه آرایه admins تو کانفیگ درست کردم و آیدی ۴ نفر رو بهش دادم ->
اولین آپشن ادمین باید این باشه ک بتونه همه یوزر های بات رو ببینه :
کد:
def return_users(bot, update):
    bot.sendMessage(update.message.chat_id, "  ".join(accepted_users))
   
return_user_command = CommandHandler('users', return_users)
updater.dispatcher.add_handler(return_user_command)
البته خیلی مهم نیس ک فقط ادمین اینو ببینه پس عمومیش کردم
آپشن دوم اضافه کردن یوزر به کاربرای باته :
Python:
def add_new_user(bot, update, args):
    #import pdb; pdb.set_trace()
    sender = update.message.chat.username
    if "@"+sender in admins:
        if len(args)>0 :
            if "@"+args[0] in accepted_users:
                bot.sendMessage(update.message.chat_id, duplicateUser)
            else:
                accepted_users.append("@"+args[0])
                bot.sendMessage(update.message.chat_id, added)
        else:
            bot.sendMessage(update.message.chat_id, confused)
    else:
        bot.sendMessage(update.message.chat_id, cantAddUser)
        bot.sendMessage(update.message.chat_id, "\n".join(admins))
       
add_user_command = CommandHandler('add_new_user', add_new_user, pass_args=True)
updater.dispatcher.add_handler(add_user_command)
و نهایتا حذف یوزر از بازیکنا :
Python:
def delete_user(bot, update, args):
    #import pdb; pdb.set_trace()
    sender = update.message.chat.username
    if "@"+sender in admins:
        if len(args)>0 :
            if "@"+args[0] in accepted_users:
                accepted_users.remove("@"+args[0])
                bot.sendMessage(update.message.chat_id, deleted)
            else:
                bot.sendMessage(update.message.chat_id, notFoundToDelete)

        else:
            bot.sendMessage(update.message.chat_id, confused2)
    else:
        bot.sendMessage(update.message.chat_id, cantDeleteUser)
        bot.sendMessage(update.message.chat_id, "\n".join(admins))
       
delete_user_command = CommandHandler('delete_user', delete_user, pass_args=True)
updater.dispatcher.add_handler(delete_user_command)
بنظر میاد همه چی خوبه:)
همینو رو یه سرور دیپلوی کردم ببینیم چی میشه :)

امیدوارم سوتی بزرگی نداده باشم و کار کنه (هنوز تستش نکردم :)) )

Python:
from telegram.ext import Updater, CommandHandler, InlineQueryHandler
from telegram.ext import CallbackQueryHandler
from telegram import InlineQueryResultArticle, InputTextMessageContent
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from config import *
from uuid import uuid4
from random import choice

'''
#for iran internet :)
REQUEST_KWARGS={
    'proxy_url': 'socks5://127.0.0.1:9050'
}

updater = Updater(TOKEN, request_kwargs=REQUEST_KWARGS)
'''

#for real internet
updater = Updater(TOKEN)


users = list()

def rand_choice_result():
    #import pdb; pdb.set_trace()
    if len(users) > 1:

        p1 = choice(users)
        users.remove(p1)
        p2 = choice(users)
        users.remove(p2)
        result = randCoice.format(p1,p2)
        return result
    else:
        return noPlayer
   

def start(bot, update):
    bot.sendMessage(update.message.chat_id, startMessage)

def return_users(bot, update):
    bot.sendMessage(update.message.chat_id, "  ".join(accepted_users))

def add_new_user(bot, update, args):
    #import pdb; pdb.set_trace()
    sender = update.message.chat.username
    if "@"+sender in admins:
        if len(args)>0 :
            if "@"+args[0] in accepted_users:
                bot.sendMessage(update.message.chat_id, duplicateUser)
            else:
                accepted_users.append("@"+args[0])
                bot.sendMessage(update.message.chat_id, added)
        else:
            bot.sendMessage(update.message.chat_id, confused)
    else:
        bot.sendMessage(update.message.chat_id, cantAddUser)
        bot.sendMessage(update.message.chat_id, "\n".join(admins))

def delete_user(bot, update, args):
    #import pdb; pdb.set_trace()
    sender = update.message.chat.username
    if "@"+sender in admins:
        if len(args)>0 :
            if "@"+args[0] in accepted_users:
                accepted_users.remove("@"+args[0])
                bot.sendMessage(update.message.chat_id, deleted)
            else:
                bot.sendMessage(update.message.chat_id, notFoundToDelete)

        else:
            bot.sendMessage(update.message.chat_id, confused2)
    else:
        bot.sendMessage(update.message.chat_id, cantDeleteUser)
        bot.sendMessage(update.message.chat_id, "\n".join(admins))

def startInlineQuery(bot, update):
    query = update.inline_query.query
    results = list()
    keyBoard = [[InlineKeyboardButton(inBtn, callback_data="start")]]
    keyBoard2 = [[InlineKeyboardButton("قرعه کشی ", callback_data="choice")]]
    keyBoard3 = [[InlineKeyboardButton("آره ", callback_data="rest")]]
    results.append(InlineQueryResultArticle(id = uuid4(), title="شروع بازی جدید", reply_markup=InlineKeyboardMarkup(keyBoard), input_message_content=InputTextMessageContent(inMessage)))
    results.append(InlineQueryResultArticle(id = uuid4(), title="قرعه کشی :) ", reply_markup=InlineKeyboardMarkup(keyBoard2), input_message_content=InputTextMessageContent(readyForChoice)))
    results.append(InlineQueryResultArticle(id = uuid4(), title="ریست کردن نوبت ها ", reply_markup=InlineKeyboardMarkup(keyBoard3), input_message_content=InputTextMessageContent(readyForReset)))
    results.append(InlineQueryResultArticle(id = uuid4(), title="همه رو خبر کن :)) ", input_message_content=InputTextMessageContent('  '.join(accepted_users))))
    results.append(InlineQueryResultArticle(id = uuid4(), title="من کی ام؟ ", input_message_content=InputTextMessageContent(whoAmI)))
    bot.answerInlineQuery(update.inline_query.id, results=results)

def userHandler(bot, update):
    query = update.callback_query
    #import pdb; pdb.set_trace()
    if query.data == "start":
        user_name = query.from_user.username
        keyBoard = [[InlineKeyboardButton(inBtn, callback_data="start")]]
        if not("@"+user_name in users) and ('@'+user_name in accepted_users):
            users.append("@"+user_name)
            query.answer(addPlayer)
        else:
            if "@"+user_name in accepted_users:
                query.answer(youAreIn)
            else:
                query.answer(notPermision)
        query.edit_message_text(inMessage + "\n \n" +afterGetIn+ "\n" + "\n".join(users),reply_markup = InlineKeyboardMarkup(keyBoard))
    elif query.data == "choice":
        query.edit_message_text(rand_choice_result())
    elif query.data == "reset":
        for i in users :
            users.remove(i)
        query.edit_message_text(afterReset)



start_command = CommandHandler('start', start)
return_user_command = CommandHandler('users', return_users)

add_user_command = CommandHandler('add_new_user', add_new_user, pass_args=True)
delete_user_command = CommandHandler('delete_user', delete_user, pass_args=True)

startInline = InlineQueryHandler(startInlineQuery)
user = CallbackQueryHandler(userHandler)

updater.dispatcher.add_handler(start_command)
updater.dispatcher.add_handler(startInline)
updater.dispatcher.add_handler(user)
updater.dispatcher.add_handler(add_user_command)
updater.dispatcher.add_handler(delete_user_command)
updater.dispatcher.add_handler(return_user_command)


updater.start_polling()
updater.idle()

ازونجا ک بات خودمونه و هرکاری دلمون بخواد باهاش انجام میدیم راجب جزییاتش پذیرای نظراتتونم :)
 

dark shadow

خائــن.
ارسال‌ها
1,166
امتیاز
13,561
نام مرکز سمپاد
Farz2
شهر
KRG
سال فارغ التحصیلی
1399
یک:افرین ب ایده ات و موفق باشی.مرسی از این وقتی ک میذاری و نمیذاری صرفا یه ایده باقی بمونه
دو:من نمیدونم داری چیکار میکنی و نمیفهمم داری چیکار میکنی اما چت کردن فراموشت نشه :))
سه:نگران نباش و ما ازت حمایت میکنیم :)

دیگه حرفی ندارم :))
 
بالا