- شروع کننده موضوع
- مدیر
- #1
- ارسالها
- 856
- امتیاز
- 19,972
- نام مرکز سمپاد
- شهید بهشتی
- شهر
- .
- سال فارغ التحصیلی
- 1397
سلام ... بازم من :)
چند روزیه ک با بچه ها قرار گذاشتیم ج.ح بازی کنیم (با تشکر از نسیم و بقیه دستاندر کار ها :) )
دیروز راجب اینکه چطور بازی کنیم داشتیم حرف میزدیم و پیشنهاد ساختن بات اختصاصی مطرح شد (با تشکر از آرمین :) )
خب من ک اصن اینکاره نیستم یکم پایتون بلدم و اینترنت نسبتا خوبی دارم .... با خودم فک کردم مگه چقد میتونه سخت باشه ها .... کامان خوش میگذره
قسمت اول
قسمت یک و نیم
قسمت دوم
قسمت سوم
قسمت چهارم
قسمت پنجم
قسمت شیشم
قسمت هفتم
امیدوارم سوتی بزرگی نداده باشم و کار کنه (هنوز تستش نکردم )
ازونجا ک بات خودمونه و هرکاری دلمون بخواد باهاش انجام میدیم راجب جزییاتش پذیرای نظراتتونم :)
چند روزیه ک با بچه ها قرار گذاشتیم ج.ح بازی کنیم (با تشکر از نسیم و بقیه دستاندر کار ها :) )
دیروز راجب اینکه چطور بازی کنیم داشتیم حرف میزدیم و پیشنهاد ساختن بات اختصاصی مطرح شد (با تشکر از آرمین :) )
خب من ک اصن اینکاره نیستم یکم پایتون بلدم و اینترنت نسبتا خوبی دارم .... با خودم فک کردم مگه چقد میتونه سخت باشه ها .... کامان خوش میگذره
قسمت اول
خب اصن دنبال چی میگردیم؟
یه بات میخوایم ک بازیکنارو بگیره -> رندوم دونفرو مقابل هم قرار بده
امکان تایید بازیکنا وجود داشته باشه -> یعنی هرکسی نتونه به بازی وارد بشه
ادمین بتونه کاربر ب بازی اضافه / حذف کنه
کاربر بتونه تو بازی شرکت بکنه/نکنه
فعلا همینا کافیه
یه بات میخوایم ک بازیکنارو بگیره -> رندوم دونفرو مقابل هم قرار بده
امکان تایید بازیکنا وجود داشته باشه -> یعنی هرکسی نتونه به بازی وارد بشه
ادمین بتونه کاربر ب بازی اضافه / حذف کنه
کاربر بتونه تو بازی شرکت بکنه/نکنه
فعلا همینا کافیه
اسکلک ینی اسکل و کوچک
فانه
منم تو انتخاب اسم بد سلیقه ام :)
فانه
منم تو انتخاب اسم بد سلیقه ام :)
خب بات های تلگرام از api استفاده میکنن -> یعنی منطقا با هرزبونی میشه واسش بات نوشت
و فریمورک ها و کتابخونه ها کارمون رو خیلی راحت میکنن
و واسه اینجور پروژه ها من ب پایتون علاقه دارم
-------
پایتون چنتا کتابخونه واسه api تلگرام داره
من python-telegram-bot رو انتخاب کردم چون قبلنا یکم باهاش بازی کرده بودم
ولی احتمالا انتخاب های بهتری هم وجود داره
و فریمورک ها و کتابخونه ها کارمون رو خیلی راحت میکنن
و واسه اینجور پروژه ها من ب پایتون علاقه دارم
-------
پایتون چنتا کتابخونه واسه api تلگرام داره
من python-telegram-bot رو انتخاب کردم چون قبلنا یکم باهاش بازی کرده بودم
ولی احتمالا انتخاب های بهتری هم وجود داره
قدم اول استفاده از هرچیزی نصب اونه -> مث آدم تو ترمینال مینویسیم :
یا از ریپازیتوری گیتهابش دانلود و نصبش کنیم:
https://github.com/python-telegram-bot/python-telegram-bot
ب هرحال وقتی تموم شد احتیاج ب داکیومنتاش داریم ک بفهمیم باید چجوری ازش استفاده کنیم:
https://python-telegram-bot.readthedocs.io/en/stable/داکیومنت خیلی خسته و مفصلی داره
کد:
(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 واسه ما ربات میسازه و بهمون یه توکن میده ک بتونیم ازش تو برنامه مون استفاده کنیم
این توکن رو باید محرمانه نگهش داریم :)
سروری ک بات ما رو ران میکنه هم تو آسمونه
من و شما ک رو زمینیم چطور باید با بات ارتباط بگیریم؟
این ارتباط رو تلگرام درست میکنه ولی لازمه ک تلگرام بتونه بات مون رو بشناسه
ربات botfather واسه ما ربات میسازه و بهمون یه توکن میده ک بتونیم ازش تو برنامه مون استفاده کنیم
این توکن رو باید محرمانه نگهش داریم :)
برنامه رو ب دوفایل تقسیم کردم
تو app.py منطق برنامه رو مینوسیم
و تو config.py کانفیگ ها و استرینگ ها و ... میزارم
اول یه برنامه بنویسیم ک وقتی استارت کردیم یه خوشآمد بهمون بگه :
updater توکن مارو میگیره و ارتباط ما با سرورمونو برقرار میکنه
متود استارت اینجوره ک وقتی صدا زده میشه استارت مسیج رو(ک تو کانفیگ تعریف شده) ب همون کاربر میفرسته
commandHandler متود استارت رو به کامند /start متصل میکنه
منطقا باید کار کنه ولی نمیکنه :))) چرا؟
تو کشور عزیز ما تلگرام مث خیلی جاهای دیگه :) فیلتره
من یه فیلتر شکن tor تو پورت ۹۰۵۰ کامپیوترم دارم ک از نوع socks5 عه ..... با یکم گشتن تو نت پیدا میکنم چطوری باید ترافیک بات رو ازون پورت منتقل کرد:
فیلترینگ رو دور زدیم و حالا برنامه مون بهمون خوشامد میگه :)
تو 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
داکیومنت هاشو باید خوند هرچند یکم گیج کننده اس:
تو داکیومنت گفته ک اینلاین کوعری! ها باید تو یه لیست باشن واسه همین لیست result رو ساختم
همچنین سه تا از پنج تا اینلاین ها احتیاج ب دکمه دارن و باید کیبوردشونو تو یه لیست دو بعدی تعریف کرد(طبق داکیومنت)
واسه کیبورد ها کال بک گذاشتم ک وقتی کلیک شدن یه دیتا واسمون بفرستن ک ادامه کارو انجام بدیم
کال بک رو مینویسیم:
چون بات شخصیه و تنها یوزر هاش خودمونیم فعلا لازم نیس دیتابیس درست کنم
یه آرایه users درست کردم ک بازیکن هارو تو همون ذخیره میکنیم (درواقع تو رم ذخیره میشن)
توی کانفیگ هم یه آرایه از یوزرنیم بچه های گروه درست کردم و فقط همونا میتونن تو بازی شرکت کنن :)
بقیه اش دیگه بازی با کاندیشناس و توضیح خاصی نداره
واسه اینکه کالبک و اینلاین مون کار کنه باید به updater بدیمشون :
حالا باید یه تابع بنویسیم ک رندوم یوزر های مقابل هم بزاره :
اگه تعداد یوزر هایی ک هنوز نوبتشون نشده کمتر از ۲ نفر باشه بازی تموم میشه :)
بهش میگن 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)
همچنین سه تا از پنج تا اینلاین ها احتیاج ب دکمه دارن و باید کیبوردشونو تو یه لیست دو بعدی تعریف کرد(طبق داکیومنت)
واسه کیبورد ها کال بک گذاشتم ک وقتی کلیک شدن یه دیتا واسمون بفرستن ک ادامه کارو انجام بدیم
کال بک رو مینویسیم:
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 تو کانفیگ درست کردم و آیدی ۴ نفر رو بهش دادم ->
اولین آپشن ادمین باید این باشه ک بتونه همه یوزر های بات رو ببینه :
البته خیلی مهم نیس ک فقط ادمین اینو ببینه پس عمومیش کردم
آپشن دوم اضافه کردن یوزر به کاربرای باته :
و نهایتا حذف یوزر از بازیکنا :
بنظر میاد همه چی خوبه:)
همینو رو یه سرور دیپلوی کردم ببینیم چی میشه :)
یه آرایه 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()
ازونجا ک بات خودمونه و هرکاری دلمون بخواد باهاش انجام میدیم راجب جزییاتش پذیرای نظراتتونم :)