├── .gitignore ├── README.md ├── explaining.py ├── first_project ├── README.md ├── keyboards.py ├── main.py └── test.py ├── inline_bot └── bot.py ├── intermediate_level ├── asynchronous_basic.py ├── asyncio_practice.py ├── callbackData.py ├── callback_count.py ├── callback_count_practice.py ├── callback_structure.py ├── callback_structure_practice.py ├── errors_handler.py ├── fsm_briefly.py ├── fsm_dialogs.py ├── inlineArticle.py ├── inlineModeEcho_practice.py ├── inlineMode_echo.py ├── inlineMode_text.py └── inlineMode_url.py ├── lesson-1 └── main.py ├── lesson-10 └── main.py ├── lesson-2 └── main.py ├── lesson-3 ├── main.py └── practice.py ├── lesson-4 └── main.py ├── lesson-8 ├── main.py └── practice.py ├── lesson-9 ├── keyboards.py ├── main.py └── practice.py ├── projects ├── bot.py ├── keyboards.py ├── new.db └── sqlite_db.py └── sqlite_aiogram ├── bot.py ├── new.db └── sqlite.py /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | */__pycache__ 3 | */config.py -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Курс видеоуроков Aiogram - необходимый минимум. 2 | 3 | --- 4 | 5 | _Самый первый курс для людей, кто не имеет представлений о проектировании Telegram ботов._ 6 | 7 | _Плейлист на Youtube_ - **https://www.youtube.com/watch?v=ayUBlf9pvn0&list=PLe-iIMbo5JOJm6DRTjhleHojroS-Bbocr** 8 | 9 | --- 10 | 11 | _Каждая директория данного проекта представляет собой отдельного бота, 12 | функционал которого был рассмотрен в соотвествующем виде ._ -------------------------------------------------------------------------------- /explaining.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkorgik/Aiogram/4e4b66eb72746c4c66abea123df4613b5fc8f716/explaining.py -------------------------------------------------------------------------------- /first_project/README.md: -------------------------------------------------------------------------------- 1 | ### The first Telegram Bot project 2 | 3 | ___ 4 | 5 | _Шаблон для вашего первого самостоятельного проекта в телеграмм боте._ 6 | _Можете использовать в виде подсказки. Однако не рассчитывайте на него, как эталонный._ 7 | _В коде существует ряд некорректных алгоритмов, реализация которых нежелательна._ 8 | _Тем не менее, избежать этого, используя ненышнее количество знаний, предоставленных мною - невозможно._ 9 | 10 | ___ 11 | 12 | _В следующих видеороликах мы узнаем много нового материала, закрепим всё на практике. После чего сделаем рефакторинг данного кода_ 13 | 14 | 15 | _Спасибо за проявленный интерес, буду рад выслушать любые ваши конструктивные мысли!_ -------------------------------------------------------------------------------- /first_project/keyboards.py: -------------------------------------------------------------------------------- 1 | from aiogram.types import ReplyKeyboardMarkup, KeyboardButton 2 | from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup 3 | 4 | kb = ReplyKeyboardMarkup(resize_keyboard=True) 5 | b1 = KeyboardButton(text='/help') 6 | b2 = KeyboardButton(text='/description') 7 | b3 = KeyboardButton(text='Random photo') 8 | b4 = KeyboardButton(text='/location') 9 | 10 | kb.add(b1, b2).add(b3).add(b4) 11 | 12 | kb_photo = ReplyKeyboardMarkup(resize_keyboard=True) 13 | bp1 = KeyboardButton(text='Рандом') 14 | bp2 = KeyboardButton(text='Главное меню') 15 | 16 | kb_photo.add(bp1, bp2) 17 | 18 | ikb = InlineKeyboardMarkup(row_width=2) 19 | ib1 = InlineKeyboardButton(text='❤️', 20 | callback_data='like') 21 | ib2 = InlineKeyboardButton(text='👎', 22 | callback_data='dislike') 23 | ib3 = InlineKeyboardButton(text='Следующая фотка', 24 | callback_data='next') 25 | ib4 = InlineKeyboardButton(text='Главное меню', 26 | callback_data='main') 27 | 28 | ikb.add(ib1, ib2).add(ib3).add(ib4) 29 | -------------------------------------------------------------------------------- /first_project/main.py: -------------------------------------------------------------------------------- 1 | import aiogram.utils.exceptions 2 | from aiogram import Bot, Dispatcher, executor, types 3 | from aiogram.dispatcher.filters import Text 4 | from aiogram.types import ReplyKeyboardRemove 5 | import random 6 | 7 | 8 | from config import TOKEN_API 9 | from keyboards import kb, kb_photo, ikb 10 | 11 | 12 | bot = Bot(token=TOKEN_API) # создаём экземпляр бота, подключаясь к API 13 | dp = Dispatcher(bot=bot) 14 | 15 | HELP_COMMAND = """ 16 | /help - список команд 17 | /start - запуск бота 18 | /description - описание бота""" 19 | 20 | arr_photos = ["https://travel.home.sndimg.com/content/dam/images/travel/fullset/2015/08/03/america-the-beautiful-ss/adirondack-park-new-york-state.jpg.rend.hgtvcom.616.462.suffix/1491580836599.jpeg", 21 | "https://i.ytimg.com/vi/u71QsZvObHs/maxresdefault.jpg", 22 | "https://images.unsplash.com/photo-1613967193490-1d17b930c1a1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8YmVhdXRpZnVsJTIwbGFuZHNjYXBlfGVufDB8fDB8fA%3D%3D&w=1000&q=80"] 23 | 24 | photos = dict(zip(arr_photos, ['Lake', 'Waterfall', 'Shore'])) 25 | random_photo = random.choice(list(photos.keys())) 26 | 27 | flag = False 28 | 29 | 30 | async def on_startup(_): 31 | print('Я запустился!') 32 | 33 | 34 | async def send_random(message: types.Message): 35 | global random_photo 36 | random_photo = random.choice(list(photos.keys())) 37 | await bot.send_photo(chat_id=message.chat.id, 38 | photo=random_photo, 39 | caption=photos[random_photo], 40 | reply_markup=ikb) 41 | 42 | 43 | @dp.message_handler(Text(equals="Random photo")) 44 | async def open_kb_photo(message: types.Message): 45 | await message.answer(text='Рандомная фотка!', 46 | reply_markup=ReplyKeyboardRemove()) 47 | await send_random(message) 48 | await message.delete() 49 | 50 | 51 | @dp.message_handler(Text(equals="Главное меню")) 52 | async def open_kb(message: types.Message): 53 | await message.answer(text='Добро пожаловать в главное меню!', 54 | reply_markup=kb) 55 | await message.delete() 56 | 57 | 58 | @dp.message_handler(commands=['start']) 59 | async def cmd_start(message: types.Message): 60 | await message.answer(text='Добро пожаловать в наш бот! 🐝', 61 | reply_markup=kb) 62 | await message.delete() 63 | 64 | 65 | @dp.message_handler(commands=['help']) 66 | async def cmd_help(message: types.Message): 67 | await message.answer(text=HELP_COMMAND, 68 | parse_mode='HTML') 69 | await message.delete() 70 | 71 | 72 | @dp.message_handler(commands=['description']) 73 | async def cmd_help(message: types.Message): 74 | await message.answer(text='Наш бот умеет отправлять рандомные фотки') 75 | await bot.send_sticker(chat_id=message.chat.id, 76 | sticker="CAACAgQAAxkBAAEFSnRi0oSKdBsMkJrWq1Wb_gJe4bH8lgACzAADzjkIDd9nfGV-RLlkKQQ") 77 | await message.delete() 78 | 79 | 80 | @dp.message_handler(commands=['location']) 81 | async def cmd_location(message: types.Message): 82 | await bot.send_location(chat_id=message.chat.id, 83 | latitude=random.randint(0, 50), 84 | longitude=random.randint(0, 50)) 85 | 86 | 87 | @dp.callback_query_handler() 88 | async def callback_random_photo(callback: types.CallbackQuery): 89 | global random_photo # ! нежелательно использование глобальных переменных 90 | global flag 91 | if callback.data == 'like': 92 | if not flag: 93 | await callback.answer("Вам понравилось!") 94 | flag = not flag 95 | else: 96 | await callback.answer("Вы уже лайкнули!") 97 | # await callback.message.answer('Вам понравилось!') 98 | elif callback.data == 'dislike': 99 | await callback.answer("Вам не понравилось!") 100 | # await callback.message.answer('Вам не понравилось!') 101 | elif callback.data == 'main': 102 | await callback.message.answer(text='Добро пожаловать в главное меню!', 103 | reply_markup=kb) 104 | await callback.message.delete() 105 | await callback.answer() 106 | else: 107 | random_photo = random.choice(list(filter(lambda x: x != random_photo, list(photos.keys())))) 108 | await callback.message.edit_media(types.InputMedia(media=random_photo, 109 | type='photo', 110 | caption=photos[random_photo]), 111 | reply_markup=ikb) 112 | await callback.answer() 113 | 114 | 115 | if __name__ == "__main__": 116 | executor.start_polling(dispatcher=dp, 117 | skip_updates=True, 118 | on_startup=on_startup) 119 | -------------------------------------------------------------------------------- /first_project/test.py: -------------------------------------------------------------------------------- 1 | import pprint 2 | 3 | arr_photos = ["https://travel.home.sndimg.com/content/dam/images/travel/fullset/2015/08/03/america-the-beautiful-ss/adirondack-park-new-york-state.jpg.rend.hgtvcom.616.462.suffix/1491580836599.jpeg", 4 | "https://i.ytimg.com/vi/u71QsZvObHs/maxresdefault.jpg", 5 | "https://images.unsplash.com/photo-1613967193490-1d17b930c1a1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8YmVhdXRpZnVsJTIwbGFuZHNjYXBlfGVufDB8fDB8fA%3D%3D&w=1000&q=80"] 6 | 7 | photos = dict(zip(arr_photos, ['1', '2', '3'])) 8 | 9 | pprint.pprint(photos) 10 | print(photos.keys()) 11 | -------------------------------------------------------------------------------- /inline_bot/bot.py: -------------------------------------------------------------------------------- 1 | from aiogram import types, executor, Dispatcher, Bot 2 | from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup 3 | 4 | from config import TOKEN_API 5 | 6 | bot = Bot(TOKEN_API) 7 | dp = Dispatcher(bot) 8 | 9 | def get_ikb() -> InlineKeyboardMarkup: 10 | ikb = InlineKeyboardMarkup(inline_keyboard=[ 11 | [InlineKeyboardButton('Кнопка 1', callback_data='menu_1'), 12 | InlineKeyboardButton('Кнопка 2', callback_data='menu_2'), 13 | InlineKeyboardButton('Кнопка 3', callback_data='menu_3'), 14 | InlineKeyboardButton('Кнопка 4', callback_data='menu_4'), ] 15 | ]) 16 | 17 | return ikb 18 | 19 | 20 | def get_back_ikb() -> InlineKeyboardMarkup: 21 | ikb = InlineKeyboardMarkup(inline_keyboard=[ 22 | [InlineKeyboardButton('Назад', callback_data='menu_back')] 23 | ]) 24 | 25 | return ikb 26 | 27 | 28 | @dp.message_handler(commands=['start']) 29 | async def cmd_start(message: types.Message) -> None: 30 | await bot.send_message(chat_id=message.from_user.id, 31 | text='Какой-то текст - описание', 32 | reply_markup=get_ikb()) 33 | 34 | 35 | @dp.callback_query_handler(text='menu_1') 36 | async def cb_menu_1(callback: types.CallbackQuery) -> None: 37 | await callback.message.edit_text('Ты нажал на кнопку 1', 38 | reply_markup=get_back_ikb()) 39 | 40 | 41 | @dp.callback_query_handler(text='menu_2') 42 | async def cb_menu_1(callback: types.CallbackQuery) -> None: 43 | await callback.message.edit_text('Ты нажал на кнопку 2', 44 | reply_markup=get_back_ikb()) 45 | 46 | 47 | @dp.callback_query_handler(text='menu_3') 48 | async def cb_menu_1(callback: types.CallbackQuery) -> None: 49 | await callback.message.edit_text('Ты нажал на кнопку 3', 50 | reply_markup=get_back_ikb()) 51 | 52 | 53 | @dp.callback_query_handler(text='menu_4') 54 | async def cb_menu_1(callback: types.CallbackQuery) -> None: 55 | await callback.message.edit_text('Ты нажал на кнопку 4', 56 | reply_markup=get_back_ikb()) 57 | 58 | 59 | @dp.callback_query_handler(text='menu_back') 60 | async def cb_menu_back(callback: types.CallbackQuery) -> None: 61 | await callback.message.edit_text(text='Какой-то текст - описание', 62 | reply_markup=get_ikb()) 63 | 64 | 65 | if __name__ == '__main__': 66 | executor.start_polling(dp, 67 | skip_updates=True) -------------------------------------------------------------------------------- /intermediate_level/asynchronous_basic.py: -------------------------------------------------------------------------------- 1 | # import asyncio 2 | # 3 | # async def send_hello() -> None: 4 | # await asyncio.sleep(2) 5 | # print('Hello!') 6 | # 7 | # 8 | # async def send_bye() -> None: 9 | # await asyncio.sleep(1) 10 | # print('Bye') 11 | # 12 | # 13 | # async def main(): 14 | # task_1 = asyncio.create_task(send_hello()) 15 | # task_2 = asyncio.create_task(send_bye()) 16 | # 17 | # await task_1 18 | # await task_2 19 | # 20 | # 21 | # asyncio.run(main()) 22 | import asyncio 23 | 24 | async def send_one() -> None: 25 | n = 0 26 | while True: 27 | await asyncio.sleep(1) 28 | n += 1 29 | if n%3!=0: 30 | print(f'Прошло {n} секунд') 31 | 32 | 33 | async def send_three() -> None: 34 | n = 0 35 | while True: 36 | await asyncio.sleep(3) 37 | n+=3 38 | print(f'Прошло ещё {n} секунды') 39 | 40 | 41 | async def main() -> None: 42 | task_1 = asyncio.create_task(send_one()) 43 | task_2 = asyncio.create_task(send_three()) 44 | 45 | await task_1 46 | await task_2 47 | 48 | 49 | if __name__ == '__main__': 50 | asyncio.run(main()) 51 | 52 | 53 | -------------------------------------------------------------------------------- /intermediate_level/asyncio_practice.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | async def send_time(sec: int) -> None: 4 | while True: 5 | await asyncio.sleep(sec) 6 | 7 | print(f'Прошло {sec} секунд') 8 | 9 | 10 | # print(send_time(2), send_time(5), sep='\n') 11 | 12 | async def main() -> None: 13 | task_1 = asyncio.create_task(send_time(2)) # различные объекты корутин!!! 14 | task_2 = asyncio.create_task(send_time(5)) 15 | 16 | await task_1 17 | await task_2 18 | 19 | 20 | if __name__ == "__main__": 21 | asyncio.run(main()) 22 | -------------------------------------------------------------------------------- /intermediate_level/callbackData.py: -------------------------------------------------------------------------------- 1 | from aiogram.utils.callback_data import CallbackData 2 | 3 | from aiogram import executor, Bot, Dispatcher, types 4 | from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton 5 | 6 | from config import TOKEN_API 7 | 8 | bot = Bot(TOKEN_API) 9 | dp = Dispatcher(bot) 10 | 11 | cb = CallbackData('ikb', 'action') 12 | cb_2 = CallbackData('ikb_2', 'action') 13 | 14 | 15 | ikb = InlineKeyboardMarkup(inline_keyboard=[ 16 | [InlineKeyboardButton('Button', callback_data=cb.new('push')), InlineKeyboardButton('Butn21', callback_data=cb_2.new('push'))] 17 | ]) 18 | 19 | 20 | @dp.message_handler(commands=['start']) 21 | async def cmd_start(message: types.Message) -> None: 22 | await message.answer('Text', 23 | reply_markup=ikb) 24 | 25 | 26 | @dp.callback_query_handler(cb.filter()) 27 | async def ikb_cb_handler(callback: types.CallbackQuery, callback_data: dict) -> None: 28 | if callback_data['action'] == 'push': 29 | await callback.answer('Something!') 30 | 31 | 32 | if __name__ == '__main__': 33 | executor.start_polling(dp, 34 | skip_updates=True) 35 | -------------------------------------------------------------------------------- /intermediate_level/callback_count.py: -------------------------------------------------------------------------------- 1 | """Lesson - the callback data count""" 2 | 3 | from aiogram import types, executor, Dispatcher, Bot 4 | from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton 5 | 6 | from config import TOKEN_API 7 | 8 | bot = Bot(TOKEN_API) 9 | dp = Dispatcher(bot) 10 | 11 | number = 0 12 | 13 | def get_inline_keyboard() -> InlineKeyboardMarkup: 14 | ikb = InlineKeyboardMarkup(inline_keyboard=[ 15 | [InlineKeyboardButton('Increase', callback_data='btn_increase'), InlineKeyboardButton('Decrease', callback_data='btn_decrease')], 16 | ]) 17 | 18 | return ikb 19 | 20 | 21 | @dp.message_handler(commands=['start']) 22 | async def cmd_start(message: types.Message) -> None: 23 | await message.answer(f'The current number is {number}', 24 | reply_markup=get_inline_keyboard()) 25 | 26 | 27 | @dp.callback_query_handler(lambda callback_query: callback_query.data.startswith('btn')) 28 | async def ikb_cb_handler(callback: types.CallbackQuery) -> None: 29 | global number 30 | if callback.data == 'btn_increase': 31 | number += 1 32 | await callback.message.edit_text(f'The current number is {number}', 33 | reply_markup=get_inline_keyboard()) 34 | elif callback.data == 'btn_decrease': 35 | number -= 1 36 | await callback.message.edit_text(f'The current number is {number}', 37 | reply_markup=get_inline_keyboard()) 38 | else: 39 | 1/0 40 | 41 | 42 | if __name__ == "__main__": 43 | executor.start_polling(dispatcher=dp, 44 | skip_updates=True) 45 | -------------------------------------------------------------------------------- /intermediate_level/callback_count_practice.py: -------------------------------------------------------------------------------- 1 | """Practical lesson - the callback data count""" 2 | import random 3 | 4 | from aiogram import types, executor, Dispatcher, Bot 5 | from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton 6 | 7 | from config import TOKEN_API 8 | 9 | bot = Bot(TOKEN_API) 10 | dp = Dispatcher(bot) 11 | 12 | number = 0 13 | 14 | def get_inline_keyboard() -> InlineKeyboardMarkup: 15 | ikb = InlineKeyboardMarkup(inline_keyboard=[ 16 | [InlineKeyboardButton('Increase', callback_data='btn_increase'), InlineKeyboardButton('Decrease', callback_data='btn_decrease')], 17 | [InlineKeyboardButton('Random Value', callback_data='btn_random')] 18 | ]) 19 | 20 | return ikb 21 | 22 | 23 | @dp.message_handler(commands=['start']) 24 | async def cmd_start(message: types.Message) -> None: 25 | await message.answer(f'The current number is {number}', 26 | reply_markup=get_inline_keyboard()) 27 | 28 | 29 | @dp.callback_query_handler(lambda callback_query: callback_query.data.startswith('btn')) 30 | async def ikb_cb_handler(callback: types.CallbackQuery) -> None: 31 | global number 32 | if callback.data == 'btn_increase': 33 | number += 1 34 | await callback.message.edit_text(f'The current number is {number}', 35 | reply_markup=get_inline_keyboard()) 36 | elif callback.data == 'btn_decrease': 37 | number -= 1 38 | await callback.message.edit_text(f'The current number is {number}', 39 | reply_markup=get_inline_keyboard()) 40 | elif callback.data == 'btn_random': 41 | number = random.randint(1, 59) 42 | await callback.message.edit_text(f'The current number is {number}', 43 | reply_markup=get_inline_keyboard()) 44 | else: 45 | 1/0 46 | 47 | 48 | if __name__ == "__main__": 49 | executor.start_polling(dispatcher=dp, 50 | skip_updates=True) 51 | -------------------------------------------------------------------------------- /intermediate_level/callback_structure.py: -------------------------------------------------------------------------------- 1 | """In this lesson we're gonna take a look at callback: types.CallbackQuery structure""" 2 | 3 | from aiogram import Bot, Dispatcher, executor, types 4 | from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup 5 | 6 | from config import TOKEN_API 7 | 8 | ikb = InlineKeyboardMarkup(inline_keyboard=[ 9 | [InlineKeyboardButton('❤️', callback_data='like'), InlineKeyboardButton('👎', callback_data='dislike')], 10 | ]) 11 | 12 | bot = Bot(token=TOKEN_API) 13 | dp = Dispatcher(bot) 14 | 15 | 16 | @dp.message_handler(commands=['start']) 17 | async def cmd_start(message: types.Message) -> None: 18 | await bot.send_photo(chat_id=message.from_user.id, 19 | photo='https://assets.traveltriangle.com/blog/wp-content/uploads/2018/03/acj-2003-beautiful-landscapes-around-the-world-23.jpg', 20 | caption='Нравится ли тебе фотография?', 21 | reply_markup=ikb) 22 | 23 | 24 | @dp.callback_query_handler() 25 | async def ikb_cb_handler(callback: types.CallbackQuery) -> None: 26 | print(callback) 27 | if callback.data == 'like': 28 | await callback.answer('Тебе понравилась фотография!') 29 | await callback.answer('Тебе не понравилось!') 30 | 31 | 32 | if __name__ == '__main__': 33 | executor.start_polling(dispatcher=dp, 34 | skip_updates=True) 35 | -------------------------------------------------------------------------------- /intermediate_level/callback_structure_practice.py: -------------------------------------------------------------------------------- 1 | """In this lesson we're gonna take a look at callback: types.CallbackQuery structure on practice""" 2 | 3 | from aiogram import Bot, Dispatcher, executor, types 4 | from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup 5 | 6 | from config import TOKEN_API 7 | 8 | bot = Bot(TOKEN_API) 9 | dp = Dispatcher(bot) 10 | 11 | is_voted = False 12 | 13 | ikb = InlineKeyboardMarkup(inline_keyboard=[ 14 | [InlineKeyboardButton('Like', callback_data='like'), InlineKeyboardButton('Dislike', callback_data='dislike')], 15 | [InlineKeyboardButton('Close keyboard', callback_data='close')] 16 | ]) 17 | 18 | 19 | @dp.message_handler(commands=['start']) 20 | async def cmd_start(message: types.Message) -> None: 21 | await bot.send_photo(chat_id=message.from_user.id, 22 | photo='https://www.usnews.com/object/image/00000162-f3a3-d0d5-a57f-fbf32fe60000/1-intro-iguazu-falls.jpg?update-time=1524505980902&size=responsive640', 23 | caption='Do you like?', 24 | reply_markup=ikb) 25 | 26 | 27 | @dp.callback_query_handler(text='close') 28 | async def ikb_close_cb_handler(callback: types.CallbackQuery) -> None: 29 | await callback.message.delete() 30 | 31 | 32 | @dp.callback_query_handler() 33 | async def ikb_close_cb_handler(callback: types.CallbackQuery) -> None: 34 | global is_voted 35 | if not is_voted: 36 | if callback.data == 'like': 37 | await callback.answer(show_alert=False, 38 | text='Тебе понравилось') 39 | is_voted = True # client has voted 40 | await callback.answer(show_alert=False, 41 | text='Тебе не понравилось понравилось') 42 | is_voted = True 43 | await callback.answer('Ты уже голосовал', 44 | show_alert=True) 45 | 46 | 47 | if __name__ == '__main__': 48 | executor.start_polling(dispatcher=dp, 49 | skip_updates=True) 50 | -------------------------------------------------------------------------------- /intermediate_level/errors_handler.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | from aiogram import executor, Bot, Dispatcher, types 4 | from aiogram.utils.exceptions import BotBlocked 5 | 6 | from config import TOKEN_API 7 | 8 | 9 | bot = Bot(TOKEN_API) 10 | dp = Dispatcher(bot) 11 | 12 | @dp.message_handler(commands=['start']) 13 | async def cmd_start(message: types.Message) -> None: 14 | await asyncio.sleep(10) 15 | await message.answer('sdhfkjsdf') 16 | 17 | 18 | @dp.errors_handler(exception=BotBlocked) 19 | async def error_bot_blocked_handler(update: types.Update, exception: BotBlocked) -> bool: 20 | print('Низя отправить сообщение, потому что нас заблокировали!') 21 | 22 | return True 23 | 24 | 25 | if __name__ == "__main__": 26 | executor.start_polling(dp, 27 | skip_updates=True) 28 | -------------------------------------------------------------------------------- /intermediate_level/fsm_briefly.py: -------------------------------------------------------------------------------- 1 | """examples 2 | program model 3 | finite-state-machine 4 | """ 5 | from aiogram import types, executor, Bot, Dispatcher 6 | from aiogram.contrib.fsm_storage.memory import MemoryStorage 7 | from aiogram.dispatcher import FSMContext 8 | from aiogram.dispatcher.filters.state import StatesGroup, State 9 | from aiogram.types import ReplyKeyboardMarkup, KeyboardButton 10 | 11 | from config import TOKEN_API 12 | 13 | storage = MemoryStorage() 14 | bot = Bot(TOKEN_API) 15 | dp = Dispatcher(bot, 16 | storage=storage) 17 | 18 | 19 | class ProfileStatesGroup(StatesGroup): 20 | 21 | photo = State() 22 | name = State() 23 | age = State() 24 | description = State() 25 | 26 | 27 | def get_kb() -> ReplyKeyboardMarkup: 28 | kb = ReplyKeyboardMarkup(resize_keyboard=True) 29 | kb.add(KeyboardButton('/create')) 30 | 31 | return kb 32 | 33 | def get_cancel_kb() -> ReplyKeyboardMarkup: 34 | kb = ReplyKeyboardMarkup(resize_keyboard=True) 35 | kb.add(KeyboardButton('/cancel')) 36 | 37 | return kb 38 | 39 | 40 | @dp.message_handler(commands=['cancel'], state='*') 41 | async def cmd_cancel(message: types.Message, state: FSMContext): 42 | if state is None: 43 | return 44 | 45 | await state.finish() 46 | await message.reply('Вы прервали создание анкеты!', 47 | reply_markup=get_kb()) 48 | 49 | 50 | @dp.message_handler(commands=['start']) 51 | async def cmd_start(message: types.Message) -> None: 52 | await message.answer('Welcome! So as to create profile - type /create', 53 | reply_markup=get_kb()) 54 | 55 | 56 | @dp.message_handler(commands=['create']) 57 | async def cmd_create(message: types.Message) -> None: 58 | await message.reply("Let's create your profile! To begin with, send me your photo!", 59 | reply_markup=get_cancel_kb()) 60 | await ProfileStatesGroup.photo.set() # установили состояние фото 61 | 62 | 63 | @dp.message_handler(lambda message: not message.photo, state=ProfileStatesGroup.photo) 64 | async def check_photo(message: types.Message): 65 | await message.reply('Это не фотография!') 66 | 67 | 68 | @dp.message_handler(content_types=['photo'], state=ProfileStatesGroup.photo) 69 | async def load_photo(message: types.Message, state: FSMContext) -> None: 70 | async with state.proxy() as data: 71 | data['photo'] = message.photo[0].file_id 72 | 73 | await message.reply('Теперь отправь своё имя!') 74 | await ProfileStatesGroup.next() 75 | 76 | 77 | @dp.message_handler(lambda message: not message.text.isdigit() or float(message.text) > 100, state=ProfileStatesGroup.age) 78 | async def check_age(message: types.Message): 79 | await message.reply('Введите реальный возраст!') 80 | 81 | 82 | @dp.message_handler(state=ProfileStatesGroup.name) 83 | async def load_name(message: types.Message, state: FSMContext) -> None: 84 | async with state.proxy() as data: 85 | data['name'] = message.text 86 | 87 | await message.reply('Сколько тебе лет?') 88 | await ProfileStatesGroup.next() 89 | 90 | 91 | @dp.message_handler(state=ProfileStatesGroup.age) 92 | async def load_age(message: types.Message, state: FSMContext) -> None: 93 | async with state.proxy() as data: 94 | data['age'] = message.text 95 | 96 | await message.reply('А теперь расскажи немного о себе!') 97 | await ProfileStatesGroup.next() 98 | 99 | 100 | @dp.message_handler(state=ProfileStatesGroup.description) 101 | async def load_desc(message: types.Message, state: FSMContext) -> None: 102 | async with state.proxy() as data: 103 | data['description'] = message.text 104 | await bot.send_photo(chat_id=message.from_user.id, 105 | photo=data['photo'], 106 | caption=f"{data['name']}, {data['age']}\n{data['description']}") 107 | 108 | await message.reply('Ваша акнета успешно создана!') 109 | await state.finish() 110 | 111 | 112 | if __name__ == '__main__': 113 | executor.start_polling(dp, 114 | skip_updates=True) 115 | 116 | 117 | -------------------------------------------------------------------------------- /intermediate_level/fsm_dialogs.py: -------------------------------------------------------------------------------- 1 | from aiogram import executor, Bot, Dispatcher, types 2 | from aiogram.contrib.fsm_storage.memory import MemoryStorage 3 | from aiogram.dispatcher.filters import Text 4 | from aiogram.dispatcher.filters.state import StatesGroup, State 5 | from aiogram.types import ReplyKeyboardMarkup, KeyboardButton 6 | from aiogram.dispatcher import FSMContext 7 | 8 | from config import TOKEN_API 9 | 10 | 11 | storage = MemoryStorage() 12 | bot = Bot(TOKEN_API) 13 | dp = Dispatcher(bot=bot, 14 | storage=storage) 15 | 16 | def get_keyboard() -> ReplyKeyboardMarkup: 17 | kb = ReplyKeyboardMarkup(resize_keyboard=True) 18 | kb.add(KeyboardButton('Начать работу!')) 19 | 20 | return kb 21 | 22 | def get_cancel() -> ReplyKeyboardMarkup: 23 | return ReplyKeyboardMarkup(resize_keyboard=True).add(KeyboardButton('/cancel')) 24 | 25 | 26 | class ClientStatesGroup(StatesGroup): 27 | 28 | photo = State() 29 | desc = State() 30 | 31 | 32 | @dp.message_handler(commands=['start']) 33 | async def cmd_start(message: types.Message) -> None: 34 | await message.answer('Добро пожаловать', 35 | reply_markup=get_keyboard()) 36 | 37 | 38 | @dp.message_handler(commands=['cancel'], state='*') 39 | async def cmd_start(message: types.Message, state: FSMContext) -> None: 40 | current_state = await state.get_state() 41 | if current_state is None: 42 | return 43 | 44 | await message.reply('Отменил', 45 | reply_markup=get_keyboard()) 46 | await state.finish() 47 | 48 | 49 | @dp.message_handler(Text(equals='Начать работу!', ignore_case=True), state=None) 50 | async def start_work(message: types.Message) -> None: 51 | await ClientStatesGroup.photo.set() 52 | await message.answer('Сначала отправь нам фотографию!', 53 | reply_markup=get_cancel()) 54 | 55 | 56 | @dp.message_handler(lambda message: not message.photo, state=ClientStatesGroup.photo) 57 | async def check_photo(message: types.Message): 58 | return await message.reply('Это не фотография!') 59 | 60 | 61 | @dp.message_handler(lambda message: message.photo, content_types=['photo'], state=ClientStatesGroup.photo) 62 | async def load_photo(message: types.Message, state: FSMContext): 63 | async with state.proxy() as data: 64 | data['photo'] = message.photo[0].file_id 65 | 66 | await ClientStatesGroup.next() 67 | await message.reply('А теперь отправь нам описание!') 68 | 69 | 70 | @dp.message_handler(state=ClientStatesGroup.desc) 71 | async def load_photo(message: types.Message, state: FSMContext): 72 | async with state.proxy() as data: 73 | data['desc'] = message.text 74 | 75 | await message.reply('Ваша фотография сохранена!') 76 | 77 | async with state.proxy() as data: 78 | await bot.send_photo(chat_id=message.from_user.id, 79 | photo=data['photo'], 80 | caption=data['desc']) 81 | 82 | await state.finish() 83 | 84 | 85 | if __name__ == '__main__': 86 | executor.start_polling(dp, 87 | skip_updates=True) 88 | -------------------------------------------------------------------------------- /intermediate_level/inlineArticle.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | 3 | from aiogram import types, executor, Bot, Dispatcher 4 | 5 | from config import TOKEN_API 6 | 7 | 8 | bot = Bot(TOKEN_API) 9 | dp = Dispatcher(bot) 10 | 11 | 12 | @dp.inline_handler() 13 | async def inline_article(inline_query: types.InlineQuery) -> None: 14 | text = inline_query.query or 'Empty' 15 | input_content_bold = types.InputTextMessageContent(message_text=f'*{text}*', 16 | parse_mode='markdown') 17 | input_content_italic = types.InputTextMessageContent(message_text=f'_{text}_', 18 | parse_mode='markdown') 19 | 20 | item_1 = types.InlineQueryResultArticle( 21 | id=str(uuid.uuid4()), 22 | input_message_content=input_content_bold, 23 | title='Bold', 24 | description=text, 25 | thumb_url='https://static.tildacdn.com/tild3431-3464-4164-b838-343934373537/Bold_logo.jpg', 26 | ) 27 | 28 | item_2 = types.InlineQueryResultArticle( 29 | id=str(uuid.uuid4()), 30 | input_message_content=input_content_italic, 31 | title='Italic', 32 | description=text, 33 | thumb_url='https://cdn.shopify.com/s/files/1/2791/8222/files/italiclogo400x100_410x2_a55cbb9e-32f6-42ba-a6c8-06e62883ccf0.png?height=628&pad_color=fff&v=1551276189&width=1200', 34 | ) 35 | 36 | await bot.answer_inline_query(inline_query_id=inline_query.id, 37 | results=[item_1, item_2], 38 | cache_time=1) 39 | 40 | 41 | if __name__ == '__main__': 42 | executor.start_polling(dispatcher=dp, 43 | skip_updates=True) -------------------------------------------------------------------------------- /intermediate_level/inlineModeEcho_practice.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | 3 | from aiogram import executor, Bot, Dispatcher, types 4 | from aiogram.types import InlineQueryResultArticle, InputTextMessageContent # INLINE MODE! 5 | 6 | from config import TOKEN_API 7 | 8 | bot = Bot(TOKEN_API) 9 | dp = Dispatcher(bot) 10 | 11 | 12 | # inlineQuery handlers 13 | 14 | 15 | @dp.inline_handler() 16 | async def inline_echo(inline_query: types.InlineQuery) -> None: 17 | text = inline_query.query or 'Echo' 18 | result_id: str = hashlib.md5(text.encode()).hexdigest() 19 | 20 | if text == 'photo': 21 | input_content = InputTextMessageContent('This is a photo') 22 | else: 23 | input_content = InputTextMessageContent(text) 24 | 25 | item = InlineQueryResultArticle( 26 | id=result_id, 27 | input_message_content=input_content, 28 | title=text, 29 | ) 30 | 31 | await bot.answer_inline_query(inline_query_id=inline_query.id, 32 | results=[item]) 33 | 34 | 35 | if __name__ == '__main__': 36 | executor.start_polling(dispatcher=dp, 37 | skip_updates=True) 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /intermediate_level/inlineMode_echo.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | 3 | from aiogram import executor, Bot, Dispatcher, types 4 | 5 | from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton 6 | from aiogram.utils.callback_data import CallbackData 7 | 8 | from aiogram.types import InlineQueryResultArticle, InputTextMessageContent # INLINE MODE! 9 | 10 | from config import TOKEN_API 11 | 12 | cb = CallbackData('ikb', 'action') # pattern 13 | bot = Bot(TOKEN_API) 14 | dp = Dispatcher(bot) 15 | 16 | 17 | def get_ikb() -> InlineKeyboardMarkup: 18 | ikb = InlineKeyboardMarkup(inline_keyboard=[ 19 | [InlineKeyboardButton('Button_1', callback_data=cb.new('push_1'))], # callback_data = {'action': 'push_1'} 20 | [InlineKeyboardButton('Button_2', callback_data=cb.new('push_2'))] # callback_data = {'action': 'push_2'} 21 | ]) 22 | 23 | return ikb 24 | 25 | 26 | @dp.message_handler(commands=['start']) 27 | async def cmd_start(message: types.Message) -> None: 28 | await message.answer(text='Welcome to my Aiogram YouTube Bot! Don\'t forget to subscribe to my channel!', 29 | reply_markup=get_ikb()) 30 | 31 | 32 | @dp.callback_query_handler(cb.filter(action='push_1')) # single responsibility principle 33 | async def push_first_cb_handler(callback: types.CallbackQuery) -> None: 34 | await callback.answer('Hello!') 35 | 36 | 37 | @dp.callback_query_handler(cb.filter(action='push_2')) 38 | async def push_second_cb_handler(callback: types.CallbackQuery) -> None: 39 | await callback.answer('World!') 40 | 41 | 42 | # inlineQuery handlers 43 | 44 | @dp.inline_handler() # process InlineQuery() is formed by Telegram API 45 | async def inline_echo(inline_query: types.InlineQuery) -> None: 46 | text = inline_query.query or 'Echo' # получили текст от пользователя, либо "Echo" 47 | input_content = InputTextMessageContent(text) # формируем контент ответного сообщения 48 | result_id: str = hashlib.md5(text.encode()).hexdigest() # сделали уникальный ID результата 49 | 50 | item = InlineQueryResultArticle( 51 | input_message_content=input_content, 52 | id=result_id, 53 | title='Inline Echo Mode 🤕', 54 | ) 55 | 56 | await bot.answer_inline_query(inline_query_id=inline_query.id, # 57 | results=[item], 58 | cache_time=1) 59 | 60 | 61 | if __name__ == '__main__': 62 | executor.start_polling(dispatcher=dp, 63 | skip_updates=True) 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /intermediate_level/inlineMode_text.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | 3 | from aiogram import executor, Bot, Dispatcher, types 4 | from aiogram.types import InlineQueryResultArticle, InputTextMessageContent # INLINE MODE! 5 | 6 | from config import TOKEN_API 7 | 8 | bot = Bot(TOKEN_API) 9 | dp = Dispatcher(bot) 10 | 11 | user_data = '' 12 | 13 | @dp.message_handler(commands=['start']) 14 | async def cmd_start(message: types.Message) -> None: 15 | await message.answer('Введите число!') 16 | 17 | 18 | @dp.message_handler() 19 | async def text_handler(message: types.Message) -> None: 20 | global user_data 21 | user_data = message.text 22 | await message.reply('Ваши данные сохранены!') 23 | 24 | 25 | @dp.inline_handler() 26 | async def inline_echo(inline_query: types.InlineQuery) -> None: 27 | text = inline_query.query or 'Echo' 28 | result_id: str = hashlib.md5(text.encode()).hexdigest() 29 | input_content = InputTextMessageContent(f'{text} - {user_data}', 30 | parse_mode='html') 31 | 32 | item = InlineQueryResultArticle( 33 | input_message_content=input_content, 34 | id=result_id, 35 | title='Echo Bot!', 36 | description='Привет, я не простой ЭХО БОТ!', 37 | ) 38 | 39 | await bot.answer_inline_query(results=[item], 40 | inline_query_id=inline_query.id, 41 | cache_time=1) 42 | 43 | 44 | if __name__ == '__main__': 45 | executor.start_polling(dispatcher=dp, 46 | skip_updates=True) 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /intermediate_level/inlineMode_url.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | 3 | from aiogram import types, executor, Bot, Dispatcher 4 | from aiogram.types import InlineQueryResultArticle, InputTextMessageContent 5 | 6 | from config import TOKEN_API 7 | 8 | bot = Bot(TOKEN_API) 9 | dp = Dispatcher(bot) 10 | 11 | 12 | @dp.inline_handler() 13 | async def inline_link(inline_query: types.InlineQuery) -> None: 14 | result_id: str = str(uuid.uuid4()) 15 | 16 | item = InlineQueryResultArticle( 17 | input_message_content=InputTextMessageContent('Take your link!', 18 | parse_mode='html'), 19 | title='YouTube', 20 | description='That\'s my YouTube channel!', 21 | url='https://www.youtube.com/channel/UCOWaWydDLr2unk_F0LcvT1w/videos', 22 | hide_url=False, 23 | thumb_url='https://www.youtube.com/img/desktop/yt_1200.png', 24 | id=result_id, 25 | ) 26 | 27 | await bot.answer_inline_query(results=[item], 28 | inline_query_id=inline_query.id, 29 | cache_time=1) 30 | 31 | 32 | if __name__ == '__main__': 33 | executor.start_polling(dp, 34 | skip_updates=True) 35 | -------------------------------------------------------------------------------- /lesson-1/main.py: -------------------------------------------------------------------------------- 1 | from aiogram import Bot, Dispatcher, types, executor 2 | from config import TOKEN_API 3 | 4 | 5 | bot = Bot(TOKEN_API) 6 | dp = Dispatcher(bot) 7 | 8 | 9 | @dp.message_handler() 10 | async def echo_upper(message: types.Message): 11 | await message.answer(message.text) 12 | 13 | 14 | if __name__ == '__main__': 15 | executor.start_polling(dp) -------------------------------------------------------------------------------- /lesson-10/main.py: -------------------------------------------------------------------------------- 1 | from aiogram import Bot, Dispatcher, executor, types 2 | from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardMarkup, KeyboardButton 3 | 4 | from first_project.config import TOKEN_API 5 | 6 | bot = Bot(TOKEN_API) 7 | dp = Dispatcher(bot) 8 | 9 | async def on_startup(_): 10 | print('I have been started up') 11 | 12 | kb = ReplyKeyboardMarkup(resize_keyboard=True) 13 | b1 = KeyboardButton(text="/help") 14 | b2 = KeyboardButton(text="/vote") 15 | kb.add(b1, b2) 16 | 17 | @dp.message_handler(commands=['start']) 18 | async def start_command(message: types.Message): 19 | await bot.send_message(chat_id=message.from_user.id, 20 | text='Welcome to our bot!', 21 | reply_markup=kb) 22 | 23 | @dp.message_handler(commands=['vote']) # handler example 24 | async def vote_command(message: types.Message): 25 | ikb = InlineKeyboardMarkup(row_width=2) 26 | ib1 = InlineKeyboardButton(text='❤️', 27 | callback_data="like") 28 | ib2 = InlineKeyboardButton(text='👎', 29 | callback_data="dislike") 30 | ikb.add(ib1, ib2) 31 | 32 | await bot.send_photo(chat_id=message.from_user.id, 33 | photo="https://cdn.mos.cms.futurecdn.net/xs77NtybWu6MPkoRtYApuJ-320-80.jpg", 34 | caption='Нравится ли тебе данная фотография?', 35 | reply_markup=ikb) 36 | 37 | @dp.callback_query_handler() 38 | async def vote_callback(callback: types.CallbackQuery): 39 | if callback.data == 'like': 40 | await callback.answer(text='Тебе понравилась данная фотография!') 41 | await callback.answer('Тебе не понравилась данная фотография!') 42 | 43 | 44 | if __name__ == "__main__": 45 | executor.start_polling(dispatcher=dp, 46 | skip_updates=True, 47 | on_startup=on_startup) 48 | -------------------------------------------------------------------------------- /lesson-2/main.py: -------------------------------------------------------------------------------- 1 | from aiogram import Bot, Dispatcher, executor, types 2 | 3 | # from config import TOKEN_API 4 | 5 | import string 6 | import random 7 | 8 | bot = Bot(TOKEN_API) 9 | dp = Dispatcher(bot) 10 | 11 | count = 0 12 | 13 | 14 | @dp.message_handler(commands=['description']) 15 | async def desc_command(message: types.Message): 16 | await message.answer('Данный бот умеет отправлять рандомные символы латинского алфавита') 17 | await message.delete() 18 | 19 | @dp.message_handler(commands=['count']) 20 | async def check_count(message: types.Message): 21 | global count 22 | await message.answer(f'COUNT: {count}') 23 | count += 1 24 | 25 | @dp.message_handler() 26 | async def check_zero(message: types.Message): 27 | if '0' in message.text: 28 | await message.reply('YES') 29 | await message.reply('NO') 30 | 31 | @dp.message_handler() #ASCII 32 | async def send_random_letter(message: types.Message): 33 | await message.reply(random.choice(string.ascii_letters)) 34 | 35 | 36 | if __name__ == "__main__": 37 | executor.start_polling(dp) 38 | -------------------------------------------------------------------------------- /lesson-3/main.py: -------------------------------------------------------------------------------- 1 | from aiogram import Bot, Dispatcher, executor, types 2 | 3 | from config import TOKEN_API 4 | 5 | bot = Bot(TOKEN_API) 6 | dp = Dispatcher(bot) 7 | 8 | async def on_startup(_): 9 | print('Бот был успешно запущен!') 10 | 11 | @dp.message_handler(commands=['start']) 12 | async def start_command(message: types.Message): 13 | await message.answer('Привет, добро пожаловать в наш бот!', parse_mode="HTML") 14 | 15 | 16 | @dp.message_handler(commands=['give']) 17 | async def start_command(message: types.Message): 18 | await bot.send_sticker(message.from_user.id, sticker="CAACAgQAAxkBAAEFO5ViyWw0_ma5hwag-9xvvpO3GZSA6gACWAADzjkIDRhMYBsy9QjTKQQ") 19 | await message.delete() 20 | 21 | 22 | @dp.message_handler() 23 | async def send_emoji(message: types.Message): 24 | await message.reply(message.text + '❤️') 25 | 26 | 27 | if __name__ == "__main__": 28 | executor.start_polling(dp, on_startup=on_startup) 29 | -------------------------------------------------------------------------------- /lesson-3/practice.py: -------------------------------------------------------------------------------- 1 | from aiogram import Bot, Dispatcher, types, executor 2 | 3 | from config import TOKEN_API 4 | 5 | 6 | bot = Bot(TOKEN_API) 7 | dp = Dispatcher(bot) 8 | 9 | HELP_COMMAND = """ 10 | /help - показывает список команд 11 | /give - отправляет кота 12 | /start - запускает бота""" 13 | 14 | 15 | async def on_startup(_): 16 | print('Я запустился') 17 | 18 | 19 | @dp.message_handler(commands=['help']) 20 | async def help_command(message: types.Message): 21 | await message.reply(text=HELP_COMMAND, parse_mode='HTML') 22 | 23 | @dp.message_handler(content_types=['sticker']) 24 | async def send_sticker_id(message: types.Message): 25 | await message.answer(message.sticker.file_id) 26 | await bot.send_sticker(message.from_user.id, sticker="CAACAgQAAxkBAAO3YsmWkTZGlI3-C20hAR0Ni7VX1OwAAlgAA845CA0YTGAbMvUI0ykE") 27 | 28 | # @dp.message_handler() 29 | # async def count(message: types.Message): 30 | # await message.answer(text=str(message.text.count('✅'))) 31 | 32 | # @dp.message_handler(commands=['give']) 33 | # async def send_sticker(message: types.Message): 34 | # await message.answer("Смотри какой котик ❤️") 35 | # await bot.send_sticker(message.from_user.id, sticker="CAACAgQAAxkBAAEFO5ViyWw0_ma5hwag-9xvvpO3GZSA6gACWAADzjkIDRhMYBsy9QjTKQQ") 36 | # 37 | # @dp.message_handler() 38 | # async def send_sticker(message: types.Message): 39 | # if message.text == "❤️": 40 | # await message.answer("🖤") 41 | 42 | 43 | if __name__ == "__main__": 44 | executor.start_polling(dp, on_startup=on_startup) 45 | -------------------------------------------------------------------------------- /lesson-4/main.py: -------------------------------------------------------------------------------- 1 | from aiogram import Bot, Dispatcher, executor, types 2 | 3 | from config import TOKEN_API 4 | 5 | bot = Bot(TOKEN_API) 6 | dp = Dispatcher(bot) 7 | 8 | HELP_COMMAND = """ 9 | /start - начало нашей работы 10 | /help - начало нашей работы 11 | /картинка - начало нашей работы""" 12 | 13 | @dp.message_handler(commands=['help']) 14 | async def help_command(message: types.Message): 15 | # await message.answer(message.text) 16 | # await bot.send_message(chat_id=message.from_user.id, 17 | # text="Hello!") 18 | await bot.send_message(chat_id=message.from_user.id, 19 | text=HELP_COMMAND, 20 | parse_mode='HTML') 21 | await message.delete() 22 | 23 | 24 | @dp.message_handler(commands=['картинка']) 25 | async def send_image(message: types.Message): 26 | await bot.send_photo(chat_id=message.chat.id, 27 | photo="https://i.ytimg.com/vi/OOFGdRmN70k/maxresdefault.jpg") 28 | await message.delete() 29 | 30 | @dp.message_handler(commands=['location']) 31 | async def send_point(message: types.Message): 32 | await bot.send_location(chat_id=message.from_user.id, 33 | latitude=55, 34 | longitude=74) 35 | await message.delete() 36 | 37 | if __name__ == "__main__": 38 | executor.start_polling(dp, skip_updates=True) 39 | -------------------------------------------------------------------------------- /lesson-8/main.py: -------------------------------------------------------------------------------- 1 | from aiogram import Bot, Dispatcher, executor, types 2 | from aiogram.types import ReplyKeyboardMarkup, KeyboardButton, ReplyKeyboardRemove 3 | 4 | from config import TOKEN_API 5 | 6 | bot = Bot(TOKEN_API) 7 | dp = Dispatcher(bot) 8 | 9 | kb = ReplyKeyboardMarkup(resize_keyboard=True) # default - False 10 | b1 = KeyboardButton('/help') 11 | b2 = KeyboardButton('/description') 12 | b3 = KeyboardButton('/photo') 13 | kb.add(b1).insert(b2).add(b3) 14 | 15 | HELP_COMMAND = """ 16 | /help - список команд 17 | /start - старт бота 18 | /description - описание бота 19 | /photo - отправка нашего фото""" 20 | 21 | @dp.message_handler(commands=['help']) 22 | async def help_command(message: types.Message): 23 | await bot.send_message(chat_id=message.from_user.id, 24 | text=HELP_COMMAND, 25 | parse_mode="HTML") 26 | await message.delete() 27 | 28 | @dp.message_handler(commands=['start']) 29 | async def start_command(message: types.Message): 30 | await bot.send_message(chat_id=message.from_user.id, 31 | text="Добро пожаловать в наш Бот!", 32 | parse_mode="HTML", 33 | reply_markup=kb) 34 | await message.delete() 35 | 36 | @dp.message_handler(commands=['description']) 37 | async def desc_command(message: types.Message): 38 | await bot.send_message(chat_id=message.from_user.id, 39 | text="Наш бот умеет отправлять фотографии", 40 | parse_mode="HTML") 41 | await message.delete() 42 | 43 | @dp.message_handler(commands=['photo']) 44 | async def photo_command(message: types.Message): 45 | await bot.send_photo(message.from_user.id, 46 | photo='https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSHfQfXQD-FhEfRlBCrWZiLi5PMIYWLRr2d6A&usqp=CAU') 47 | await message.delete() 48 | 49 | if __name__ == "__main__": 50 | executor.start_polling(dp, skip_updates=True) 51 | -------------------------------------------------------------------------------- /lesson-8/practice.py: -------------------------------------------------------------------------------- 1 | from aiogram import Bot, Dispatcher, executor, types 2 | from aiogram.types import ReplyKeyboardRemove, ReplyKeyboardMarkup, KeyboardButton 3 | from random import randrange 4 | 5 | from config import TOKEN_API 6 | 7 | bot = Bot(TOKEN_API) 8 | dp = Dispatcher(bot) 9 | 10 | kb = ReplyKeyboardMarkup(resize_keyboard=True) 11 | kb.add(KeyboardButton('/help')).insert(KeyboardButton('/orange')).add(KeyboardButton('/random')) 12 | 13 | HELP_COMMAND = """ 14 | /help - список команд 15 | /start - старт бота 16 | /description - описание бота 17 | /photo - отправка нашего фото""" 18 | 19 | async def on_startup(_): 20 | print('Я запустился!') 21 | 22 | @dp.message_handler(commands=['start']) 23 | async def command_start(message: types.Message): 24 | await bot.send_message(chat_id=message.chat.id, 25 | text='Добро пожаловать!', 26 | reply_markup=kb) 27 | 28 | @dp.message_handler(commands=['help']) 29 | async def command_help(message: types.Message): 30 | await bot.send_message(chat_id=message.from_user.id, 31 | text=HELP_COMMAND, 32 | parse_mode='HTML') 33 | 34 | @dp.message_handler(commands=['description']) 35 | async def command_desc(message: types.Message): 36 | await bot.send_message(chat_id=message.from_user.id, 37 | text='Наш бот просто прикольный!') 38 | 39 | @dp.message_handler(commands=['orange']) 40 | async def send_orange(message: types.Message): 41 | await bot.send_photo(chat_id=message.chat.id, 42 | photo="https://cdn.britannica.com/24/174524-050-A851D3F2/Oranges.jpg") 43 | 44 | @dp.message_handler(commands=['random']) 45 | async def send_random(message: types.Message): 46 | await bot.send_location(chat_id=message.chat.id, 47 | latitude=randrange(1, 100), 48 | longitude=randrange(1, 100)) 49 | 50 | # @dp.message_handler() 51 | # async def send_cat(message: types.Message): 52 | # if message.text == '❤️': 53 | # await bot.send_sticker(chat_id=message.from_user.id, 54 | # sticker="CAACAgQAAxkBAAEFO9hiyZapnjUwZ0cgIelk-Qe49P2R5gACWAADzjkIDRhMYBsy9QjTKQQ") 55 | 56 | if __name__ == "__main__": 57 | executor.start_polling(dp, skip_updates=True, on_startup=on_startup) 58 | -------------------------------------------------------------------------------- /lesson-9/keyboards.py: -------------------------------------------------------------------------------- 1 | from aiogram.types import KeyboardButton, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton 2 | 3 | ikb = InlineKeyboardMarkup(row_width=2) 4 | ib1 = InlineKeyboardButton(text="YouTube", 5 | url="https://www.youtube.com/channel/UCOWaWydDLr2unk_F0LcvT1w/videos") 6 | ib2 = InlineKeyboardButton(text="Google", 7 | url="https://www.google.com") 8 | ikb.add(ib1).add(ib2) 9 | 10 | kb = ReplyKeyboardMarkup(resize_keyboard=True, 11 | one_time_keyboard=True) 12 | b = KeyboardButton(text="/links") 13 | kb.add(b) 14 | -------------------------------------------------------------------------------- /lesson-9/main.py: -------------------------------------------------------------------------------- 1 | from aiogram import Bot, Dispatcher, executor, types 2 | from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup 3 | 4 | from projects.config import TOKEN_API 5 | 6 | bot = Bot(TOKEN_API) 7 | dp = Dispatcher(bot) 8 | 9 | ikb = InlineKeyboardMarkup(row_width=2) 10 | ib1 = InlineKeyboardButton(text='Button 1', 11 | url="https://www.youtube.com/channel/UCOWaWydDLr2unk_F0LcvT1w/videos") 12 | ib2 = InlineKeyboardButton(text='Button 2', 13 | url="https://www.youtube.com/channel/UCOWaWydDLr2unk_F0LcvT1w/videos") 14 | 15 | ikb.add(ib1, ib2) 16 | 17 | @dp.message_handler(commands=['start']) 18 | async def send_kb(message: types.Message): 19 | await bot.send_message(chat_id=message.from_user.id, 20 | text='Hello World!', 21 | reply_markup=ikb) 22 | 23 | if __name__ == "__main__": 24 | executor.start_polling(dp, skip_updates=True) 25 | -------------------------------------------------------------------------------- /lesson-9/practice.py: -------------------------------------------------------------------------------- 1 | from aiogram import Bot, executor, Dispatcher, types 2 | 3 | from projects.config import TOKEN_API 4 | from keyboards import kb, ikb 5 | 6 | bot = Bot(TOKEN_API) 7 | dp = Dispatcher(bot) 8 | 9 | 10 | async def on_startup(_): 11 | print('Я был запущен!') 12 | 13 | @dp.message_handler(commands=['start']) 14 | async def start_command(message: types.Message): 15 | await message.answer(text='Добро пожаловать в главное меню', 16 | reply_markup=kb) 17 | 18 | @dp.message_handler(commands=['links']) 19 | async def links_command(message: types.Message): 20 | await message.answer(text='Выберите опцию...', 21 | reply_markup=ikb) 22 | 23 | 24 | if __name__ == "__main__": 25 | executor.start_polling(dispatcher=dp, 26 | skip_updates=True, 27 | on_startup=on_startup) -------------------------------------------------------------------------------- /projects/bot.py: -------------------------------------------------------------------------------- 1 | # list of all products 2 | 3 | from aiogram import types, executor, Dispatcher, Bot 4 | from aiogram.contrib.fsm_storage.memory import MemoryStorage 5 | from aiogram.dispatcher import FSMContext 6 | from aiogram.dispatcher.filters.state import StatesGroup, State 7 | 8 | from config import TOKEN_API 9 | from keyboards import * 10 | import sqlite_db 11 | 12 | bot = Bot(TOKEN_API) 13 | storage = MemoryStorage() 14 | dp = Dispatcher(bot, 15 | storage=storage) 16 | 17 | 18 | class ProductStatesGroup(StatesGroup): 19 | 20 | title = State() 21 | photo = State() 22 | 23 | new_title = State() 24 | 25 | 26 | async def on_startup(_): 27 | await sqlite_db.db_connect() 28 | print('Подключение к БД выполнено успешно') 29 | 30 | 31 | async def show_all_products(callback: types.CallbackQuery, products: list) -> None: 32 | for product in products: 33 | await bot.send_photo(chat_id=callback.message.chat.id, 34 | photo=product[2], 35 | caption=f'{product[1]} {product[0]}', 36 | parse_mode='HTML', 37 | reply_markup=get_edit_ikb(product[0])) 38 | 39 | 40 | @dp.message_handler(commands=['start']) 41 | async def cmd_start(message: types.Message): 42 | await bot.send_message(chat_id=message.from_user.id, 43 | text='Добро пожаловать!', 44 | reply_markup=get_start_kb()) 45 | 46 | 47 | @dp.message_handler(commands=['cancel'], state='*') 48 | async def cmd_cancel(message: types.Message, state: FSMContext): 49 | if state is None: 50 | return 51 | 52 | await state.finish() 53 | await message.answer('Вы отменили действие!', 54 | reply_markup=get_start_kb()) 55 | 56 | 57 | @dp.message_handler(commands=['products']) 58 | async def cmd_products(message: types.Message): 59 | await message.delete() 60 | await message.answer('Управление продуктами', 61 | reply_markup=get_products_ikb()) 62 | 63 | 64 | @dp.callback_query_handler(text='get_all_products') 65 | async def cb_get_all_products(callback: types.CallbackQuery): 66 | products = await sqlite_db.get_all_products() # 67 | 68 | if not products: 69 | await callback.message.delete() 70 | await callback.message.answer('Вообще продуктов нет!') 71 | return await callback.answer() 72 | 73 | await callback.message.delete() 74 | await show_all_products(callback, products) 75 | await callback.answer() 76 | 77 | 78 | @dp.callback_query_handler(text='add_new_product') 79 | async def cb_add_new_product(callback: types.CallbackQuery) -> None: 80 | await callback.message.delete() 81 | await callback.message.answer('Отправь название продукта!', 82 | reply_markup=get_cancel_kb()) 83 | 84 | await ProductStatesGroup.title.set() 85 | 86 | 87 | @dp.message_handler(state=ProductStatesGroup.title) 88 | async def handle_title(message: types.Message, state: FSMContext) -> None: 89 | async with state.proxy() as data: 90 | data['title'] = message.text 91 | 92 | await message.reply('А теперь нам фотографию!') 93 | await ProductStatesGroup.next() 94 | 95 | 96 | @dp.message_handler(lambda message: not message.photo, state=ProductStatesGroup.photo) 97 | async def check_photo(message: types.Message): 98 | await message.reply('Это не фотография!') 99 | 100 | 101 | @dp.message_handler(content_types=['photo'], state=ProductStatesGroup.photo) 102 | async def handle_photo(message: types.Message, state: FSMContext) -> None: 103 | async with state.proxy() as data: 104 | data['photo'] = message.photo[0].file_id 105 | 106 | await sqlite_db.create_new_product(state) 107 | await message.reply('Спасибо, ваш продукт создан!', 108 | reply_markup=get_start_kb()) 109 | 110 | await state.finish() 111 | 112 | 113 | @dp.callback_query_handler(products_cb.filter(action='delete')) 114 | async def cb_delete_product(callback: types.CallbackQuery, callback_data: dict): 115 | await sqlite_db.delete_product(callback_data['id']) 116 | 117 | await callback.message.reply('Ваш продукт был успешно удалён!') 118 | await callback.answer() 119 | 120 | 121 | @dp.callback_query_handler(products_cb.filter(action='edit')) 122 | async def cb_edit_product(callback: types.CallbackQuery, callback_data: dict, state: FSMContext): 123 | await callback.message.answer('Отправь нам новое название продукта!', 124 | reply_markup=get_cancel_kb()) 125 | await ProductStatesGroup.new_title.set() 126 | 127 | async with state.proxy() as data: 128 | data['product_id'] = callback_data['id'] 129 | 130 | await callback.answer() 131 | 132 | 133 | @dp.message_handler(state=ProductStatesGroup.new_title) 134 | async def load_new_title(message: types.Message, state: FSMContext) -> None: 135 | async with state.proxy() as data: 136 | await sqlite_db.edit_product(data['product_id'], message.text) 137 | 138 | await message.reply('Новое название продукта установлено!', 139 | reply_markup=get_start_kb()) 140 | await state.finish() 141 | 142 | 143 | if __name__ == '__main__': 144 | executor.start_polling(dispatcher=dp, 145 | skip_updates=True, 146 | on_startup=on_startup) 147 | -------------------------------------------------------------------------------- /projects/keyboards.py: -------------------------------------------------------------------------------- 1 | from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardMarkup, KeyboardButton 2 | from aiogram.utils.callback_data import CallbackData 3 | 4 | products_cb = CallbackData('product', 'id', 'action') 5 | 6 | def get_products_ikb() -> InlineKeyboardMarkup: 7 | ikb = InlineKeyboardMarkup(inline_keyboard=[ 8 | [InlineKeyboardButton('Просмотр всех продуктов', callback_data='get_all_products')], 9 | [InlineKeyboardButton('Добавить новый продукт', callback_data='add_new_product')], 10 | ]) 11 | 12 | return ikb 13 | 14 | 15 | def get_edit_ikb(product_id: int) -> InlineKeyboardMarkup: 16 | ikb = InlineKeyboardMarkup(inline_keyboard=[ 17 | [InlineKeyboardButton('Редактировать продукт', callback_data=products_cb.new(product_id, 'edit'))], 18 | [InlineKeyboardButton('Удалить продукт', callback_data=products_cb.new(product_id, 'delete'))], 19 | ]) 20 | 21 | return ikb 22 | 23 | 24 | def get_start_kb() -> ReplyKeyboardMarkup: 25 | kb = ReplyKeyboardMarkup(keyboard=[ 26 | [KeyboardButton('/products')] 27 | ], resize_keyboard=True) 28 | 29 | return kb 30 | 31 | 32 | def get_cancel_kb() -> ReplyKeyboardMarkup: 33 | kb = ReplyKeyboardMarkup(keyboard=[ 34 | [KeyboardButton('/cancel')] 35 | ], resize_keyboard=True) 36 | 37 | return kb 38 | -------------------------------------------------------------------------------- /projects/new.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkorgik/Aiogram/4e4b66eb72746c4c66abea123df4613b5fc8f716/projects/new.db -------------------------------------------------------------------------------- /projects/sqlite_db.py: -------------------------------------------------------------------------------- 1 | import sqlite3 as sq 2 | 3 | async def db_connect() -> None: 4 | global db, cur 5 | 6 | db = sq.connect('new.db') 7 | cur = db.cursor() 8 | 9 | cur.execute("CREATE TABLE IF NOT EXISTS product(product_id INTEGER PRIMARY KEY, title TEXT, photo TEXT)") 10 | 11 | db.commit() 12 | 13 | 14 | async def get_all_products(): 15 | 16 | products = cur.execute("SELECT * FROM product").fetchall() 17 | 18 | return products # list 19 | 20 | 21 | async def create_new_product(state): 22 | 23 | async with state.proxy() as data: 24 | product = cur.execute("INSERT INTO product (title, photo) VALUES (?, ?)", (data['title'], data['photo'])) 25 | db.commit() 26 | 27 | return product 28 | 29 | 30 | async def delete_product(product_id: int) -> None: 31 | cur.execute("DELETE FROM product WHERE product_id = ?", (product_id,)) 32 | db.commit() 33 | 34 | 35 | async def edit_product(product_id: int, title: str) -> None: 36 | cur.execute("UPDATE product SET title = ? WHERE product_id = ?", (title, product_id,)) 37 | db.commit() 38 | -------------------------------------------------------------------------------- /sqlite_aiogram/bot.py: -------------------------------------------------------------------------------- 1 | """examples 2 | program model 3 | finite-state-machine 4 | """ 5 | from aiogram import types, executor, Bot, Dispatcher 6 | from aiogram.contrib.fsm_storage.memory import MemoryStorage 7 | from aiogram.dispatcher import FSMContext 8 | from aiogram.dispatcher.filters.state import StatesGroup, State 9 | from aiogram.types import ReplyKeyboardMarkup, KeyboardButton 10 | 11 | from config import TOKEN_API 12 | from sqlite import db_start, create_profile, edit_profile 13 | 14 | 15 | async def on_startup(_): 16 | await db_start() 17 | 18 | 19 | storage = MemoryStorage() 20 | bot = Bot(TOKEN_API) 21 | dp = Dispatcher(bot, 22 | storage=storage) 23 | 24 | 25 | class ProfileStatesGroup(StatesGroup): 26 | 27 | photo = State() 28 | name = State() 29 | age = State() 30 | description = State() 31 | 32 | 33 | def get_kb() -> ReplyKeyboardMarkup: 34 | kb = ReplyKeyboardMarkup(resize_keyboard=True) 35 | kb.add(KeyboardButton('/create')) 36 | 37 | return kb 38 | 39 | def get_cancel_kb() -> ReplyKeyboardMarkup: 40 | kb = ReplyKeyboardMarkup(resize_keyboard=True) 41 | kb.add(KeyboardButton('/cancel')) 42 | 43 | return kb 44 | 45 | 46 | @dp.message_handler(commands=['cancel'], state='*') 47 | async def cmd_cancel(message: types.Message, state: FSMContext): 48 | if state is None: 49 | return 50 | 51 | await state.finish() 52 | await message.reply('Вы прервали создание анкеты!', 53 | reply_markup=get_kb()) 54 | 55 | 56 | @dp.message_handler(commands=['start']) 57 | async def cmd_start(message: types.Message) -> None: 58 | await message.answer('Welcome! So as to create profile - type /create', 59 | reply_markup=get_kb()) 60 | 61 | await create_profile(user_id=message.from_user.id) 62 | 63 | 64 | @dp.message_handler(commands=['create']) 65 | async def cmd_create(message: types.Message) -> None: 66 | await message.reply("Let's create your profile! To begin with, send me your photo!", 67 | reply_markup=get_cancel_kb()) 68 | await ProfileStatesGroup.photo.set() # установили состояние фото 69 | 70 | 71 | @dp.message_handler(lambda message: not message.photo, state=ProfileStatesGroup.photo) 72 | async def check_photo(message: types.Message): 73 | await message.reply('Это не фотография!') 74 | 75 | 76 | @dp.message_handler(content_types=['photo'], state=ProfileStatesGroup.photo) 77 | async def load_photo(message: types.Message, state: FSMContext) -> None: 78 | async with state.proxy() as data: 79 | data['photo'] = message.photo[0].file_id 80 | 81 | await message.reply('Теперь отправь своё имя!') 82 | await ProfileStatesGroup.next() 83 | 84 | 85 | @dp.message_handler(lambda message: not message.text.isdigit() or float(message.text) > 100, state=ProfileStatesGroup.age) 86 | async def check_age(message: types.Message): 87 | await message.reply('Введите реальный возраст!') 88 | 89 | 90 | @dp.message_handler(state=ProfileStatesGroup.name) 91 | async def load_name(message: types.Message, state: FSMContext) -> None: 92 | async with state.proxy() as data: 93 | data['name'] = message.text 94 | 95 | await message.reply('Сколько тебе лет?') 96 | await ProfileStatesGroup.next() 97 | 98 | 99 | @dp.message_handler(state=ProfileStatesGroup.age) 100 | async def load_age(message: types.Message, state: FSMContext) -> None: 101 | async with state.proxy() as data: 102 | data['age'] = message.text 103 | 104 | await message.reply('А теперь расскажи немного о себе!') 105 | await ProfileStatesGroup.next() 106 | 107 | 108 | @dp.message_handler(state=ProfileStatesGroup.description) 109 | async def load_desc(message: types.Message, state: FSMContext) -> None: 110 | async with state.proxy() as data: 111 | data['description'] = message.text 112 | await bot.send_photo(chat_id=message.from_user.id, 113 | photo=data['photo'], 114 | caption=f"{data['name']}, {data['age']}\n{data['description']}") 115 | 116 | await edit_profile(state, user_id=message.from_user.id) 117 | await message.reply('Ваша акнета успешно создана!') 118 | await state.finish() 119 | 120 | 121 | if __name__ == '__main__': 122 | executor.start_polling(dp, 123 | skip_updates=True, 124 | on_startup=on_startup) 125 | 126 | 127 | -------------------------------------------------------------------------------- /sqlite_aiogram/new.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nkorgik/Aiogram/4e4b66eb72746c4c66abea123df4613b5fc8f716/sqlite_aiogram/new.db -------------------------------------------------------------------------------- /sqlite_aiogram/sqlite.py: -------------------------------------------------------------------------------- 1 | import sqlite3 as sq 2 | 3 | async def db_start(): 4 | global db, cur 5 | 6 | db = sq.connect('new.db') 7 | cur = db.cursor() 8 | 9 | cur.execute("CREATE TABLE IF NOT EXISTS profile(user_id TEXT PRIMARY KEY, photo TEXT, age TEXT, description TEXT, name TEXT)") 10 | 11 | db.commit() 12 | 13 | 14 | async def create_profile(user_id): 15 | user = cur.execute("SELECT 1 FROM profile WHERE user_id == '{key}'".format(key=user_id)).fetchone() 16 | if not user: 17 | cur.execute("INSERT INTO profile VALUES(?, ?, ?, ?, ?)", (user_id, '', '', '', '')) 18 | db.commit() 19 | 20 | 21 | async def edit_profile(state, user_id): 22 | async with state.proxy() as data: 23 | cur.execute("UPDATE profile SET photo = '{}', age = '{}', description = '{}', name = '{}' WHERE user_id == '{}'".format( 24 | data['photo'], data['age'], data['description'], data['name'], user_id)) 25 | db.commit() 26 | --------------------------------------------------------------------------------