├── .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 |
--------------------------------------------------------------------------------