<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Xacker_Name_new</title><author><name>Xacker_Name_new</name></author><id>https://teletype.in/atom/xacker_name_new</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/xacker_name_new?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@xacker_name_new?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=xacker_name_new"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/xacker_name_new?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-05-02T08:12:04.630Z</updated><entry><id>xacker_name_new:XGXxVf7NbPH</id><link rel="alternate" type="text/html" href="https://teletype.in/@xacker_name_new/XGXxVf7NbPH?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=xacker_name_new"></link><title>Обучение #5</title><published>2023-10-20T19:42:24.084Z</published><updated>2023-10-20T19:42:24.084Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/50/e3/50e31141-824f-4f69-8473-ed3aa0599887.png"></media:thumbnail><category term="obuchenie-python-aiogram-my-sql" label="Обучение Python+aiogram+MySQL"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/3a/72/3a720c74-3487-46cc-ac94-4ec752d144cc.png&quot;&gt;Обучение #5</summary><content type="html">
  &lt;h3 id=&quot;9m4T&quot; data-align=&quot;center&quot;&gt;Хочу сразу извиниться за то что задержал урок, была срочная работа, думаю такого больше не повториться🥺&lt;/h3&gt;
  &lt;p id=&quot;S1uj&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;PkGH&quot;&gt;Сегодня мы научимся работать с API сайта 365sms.org (Новый домен 365sms.ru)&lt;/p&gt;
  &lt;p id=&quot;btqN&quot;&gt;Давайте попробуем понять зачем нам это.&lt;/p&gt;
  &lt;ol id=&quot;SBqI&quot;&gt;
    &lt;li id=&quot;fBQH&quot;&gt;Это для того что-бы мы в бота смогли пихать любые сервисы которые дают нам API для связи с ними (и не только в ботов)&lt;/li&gt;
    &lt;li id=&quot;S8An&quot;&gt;Для автоматизации процессов&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;l1u3&quot;&gt;Использовать будем такую библиотеку как &lt;a href=&quot;https://pypi.org/project/requests/&quot; target=&quot;_blank&quot;&gt;requests&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;EEgB&quot;&gt;pip install requests&lt;/pre&gt;
  &lt;p id=&quot;4jA6&quot;&gt;Переходим на сайт &amp;quot;&lt;a href=&quot;https://365sms.ru/api365&quot; target=&quot;_blank&quot;&gt;https://365sms.ru/api365&lt;/a&gt;&amp;quot;&lt;/p&gt;
  &lt;p id=&quot;wbIi&quot;&gt;и читаем документацию...&lt;/p&gt;
  &lt;p id=&quot;Utku&quot;&gt;Что нам это дало?&lt;/p&gt;
  &lt;figure id=&quot;ZESk&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/5e/12/5e1292cf-44c0-48b5-b706-46deed6fc7e8.png&quot; width=&quot;223&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;DQeK&quot;&gt;Есть несколько разделов в api документации&lt;br /&gt;Давайте разберём каждый по порядку:&lt;/p&gt;
  &lt;ol id=&quot;eOuD&quot;&gt;
    &lt;li id=&quot;9YHx&quot;&gt;&lt;strong&gt;Описание протокола API&lt;/strong&gt; - это нам не особо интересно, разве что строка описывающая какие запросы нам нужны &amp;quot;Все запросы (&lt;strong&gt;только GET&lt;/strong&gt;) должны идти на данный адрес&amp;quot;&lt;/li&gt;
    &lt;li id=&quot;W2lV&quot;&gt;&lt;strong&gt;Запрос количества доступных номеров getNumbersStatus&lt;/strong&gt; - описан примерный запрос к сайту для получения кол-во доступных номеров&lt;br /&gt;&lt;code&gt;https://365sms.org/stubs/handler_api.php?api_key=APIKEY&amp;amp;action=getNumbersStatus&amp;amp;country=COUNTRY&amp;amp;operator=OPERATOR&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;А так же предоставлены переменные которые нужно будет заменить:&lt;br /&gt;&lt;strong&gt;APIKEY &lt;/strong&gt;- ключ обеспечивает доступ к оплаченным услугам&lt;br /&gt;&lt;strong&gt;COUNTRY &lt;/strong&gt;- Страна номера&lt;br /&gt;&lt;strong&gt;OPERATOR &lt;/strong&gt;- Оператор номера. Если параметр не задан, будет задействован случайный оператор&lt;br /&gt;&lt;br /&gt;Ну и ответ от сервиса после сделанного запроса в формате json (позже к нему перейдём)&lt;br /&gt;&lt;strong&gt;&lt;code&gt;{&amp;quot;vk_0&amp;quot;:890,&amp;quot;ok_0&amp;quot;:192,&amp;quot;wa_0&amp;quot;:146,&amp;quot;vi_0&amp;quot;:199,&amp;quot;tg_0&amp;quot;:101,&amp;quot;wb_0&amp;quot;:103,&amp;quot;go_0&amp;quot;:467,&amp;quot;av_0&amp;quot;:177,&amp;quot;fb_0&amp;quot;:132,&amp;quot;tw_0&amp;quot;:479}&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
    &lt;li id=&quot;mNXV&quot;&gt;&lt;strong&gt;Запрос баланса getBalance&lt;/strong&gt; - Получаем текущий баланс аккаунта на сайте&lt;/li&gt;
    &lt;li id=&quot;Lprv&quot;&gt;&lt;strong&gt;Заказ номера getNumber&lt;/strong&gt; - с помощью этого метода будем запрашивать номер&lt;/li&gt;
    &lt;li id=&quot;tl2F&quot;&gt;&lt;strong&gt;Изменить статус setStatus&lt;/strong&gt; - этот метод нам позволит менять статус номера&lt;br /&gt;Статусы:&lt;/li&gt;
    &lt;ol id=&quot;zbuc&quot;&gt;
      &lt;li id=&quot;XxZV&quot;&gt;&lt;em&gt;3&lt;/em&gt; - &lt;strong&gt;необходимо повторно смс&lt;/strong&gt;&lt;/li&gt;
      &lt;li id=&quot;V2ds&quot;&gt;&lt;em&gt;6&lt;/em&gt; - &lt;strong&gt;активация успешно завершена&lt;/strong&gt;&lt;/li&gt;
      &lt;li id=&quot;MAbf&quot;&gt;&lt;em&gt;8&lt;/em&gt; - &lt;strong&gt;отменить активацию&lt;/strong&gt;&lt;/li&gt;
    &lt;/ol&gt;
    &lt;li id=&quot;sxuJ&quot;&gt;&lt;strong&gt;Получить статус getStatus&lt;/strong&gt; - с помощью данного метода мы получим статус номера (Статусы описаны выше)&lt;/li&gt;
    &lt;li id=&quot;uNI7&quot;&gt;&lt;strong&gt;Запросить все цены getPrices&lt;/strong&gt; - этот метод вернёт нам json объект со всеми ценами сервисов по ID страны&lt;br /&gt;&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;NLFI&quot;&gt;Давайте перейдём к методам запросов модуля requests&lt;/p&gt;
  &lt;p id=&quot;FbSy&quot;&gt;Метод &lt;strong&gt;POST&lt;/strong&gt;:&lt;/p&gt;
  &lt;blockquote id=&quot;5FNH&quot;&gt;&lt;em&gt;Используется для отправки данных на сервер&lt;/em&gt;&lt;/blockquote&gt;
  &lt;p id=&quot;eFHP&quot;&gt;Метод &lt;strong&gt;GET&lt;/strong&gt;:&lt;/p&gt;
  &lt;blockquote id=&quot;Z52D&quot;&gt;&lt;em&gt;Используется для получения данных с сервера&lt;/em&gt;&lt;/blockquote&gt;
  &lt;p id=&quot;pzgr&quot;&gt;&lt;strong&gt;Использовать будем метод &lt;em&gt;GET&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;hY92&quot;&gt;Создаём папку bot_requests_365&lt;/p&gt;
  &lt;p id=&quot;XfR2&quot;&gt;В папке создаём файлы:&lt;/p&gt;
  &lt;ol id=&quot;NTt9&quot;&gt;
    &lt;li id=&quot;g6R0&quot;&gt;main.py - В нём будем писать весь код бота&lt;/li&gt;
    &lt;li id=&quot;2SUL&quot;&gt;class_db.py - Скопируем в него модуль из предыдущих уроков&lt;/li&gt;
    &lt;li id=&quot;pwja&quot;&gt;test.py - В нём будут клавиатуры&lt;/li&gt;
    &lt;li id=&quot;uWnw&quot;&gt;config.py - В него будем записывать все данные (токены, id админов и т.п.)&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;Rann&quot;&gt;И так у нас получилась папка с содержанием:&lt;/p&gt;
  &lt;figure id=&quot;BQK8&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c6/ef/c6efb7e8-eee2-4136-8a41-df664ceefcbb.png&quot; width=&quot;657&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;TXlG&quot;&gt;Код для файла class_db.py:&lt;/p&gt;
  &lt;pre id=&quot;lReH&quot; data-lang=&quot;python&quot;&gt;import pymysql #Импортируем модуль pymysql который установили в первом уроке

class work_db:
	def __init__(self, host, port, user, password, database): #Функция для иницилизирования переменных в класс, запускать её не надо
		self.host = host
		self.port = port
		self.user = user
		self.password = password
		self.database = database

	def connect_db(self): #Функция для конекта к базе данных
		try:
			connection = pymysql.connect(
				host = self.host,
				port = self.port,
				user = self.user,
				password = self.password,
				database = self.database,
				cursorclass = pymysql.cursors.DictCursor
			)
			return connection #Если конект прошёл успешно, возвращаем переменную connection, для дальнейшей работы
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def connect_close(self, connection): #Передаём переменную connection если в коде подключились, после каждого подключения к базе данных и выполнения какого-либо когда, нужно закрывать подключение
		try:
			connection.close() #Закрываем подключение к базе данных
			return True #Если успешно закрыли подключение к базе, возвращаем True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def create_table(self, connection, creat): #Функция для создания таблице в базе данных, в creat будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(creat)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def edit_table(self, connection, zapros, values):
		try:
			with connection.cursor() as cursor:
				cursor.execute(zapros, values)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def info_table(self, connection, info, values): #Функция для получения данных из таблицы, в info будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(info, values)
			return cursor.fetchall() #Возвращаем всё что нашли
		except Exception as eror:
			print(str(eror)+&amp;#x27;\n\n&amp;#x27;) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def insert_table(self, connection, zapros, values):
		try:
			with connection.cursor() as cursor:
				a = cursor.execute(zapros, values)
			connection.commit()
			return a
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def delete_from_table(self, connection, delete_, values): #Функция для редактирования данных в таблице, в delete_ будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(delete_, values)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False&lt;/pre&gt;
  &lt;p id=&quot;3PRv&quot;&gt;И так создадим ещё 1 файл для удобно работы с api сайта &lt;a href=&quot;https://365sms.ru/&quot; target=&quot;_blank&quot;&gt;365sms.ru&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;t2XI&quot;&gt;Название файла: module_sms.py&lt;/p&gt;
  &lt;p id=&quot;L2vb&quot;&gt;Напишем для этого файла следующий код:&lt;/p&gt;
  &lt;pre id=&quot;vInI&quot; data-lang=&quot;python&quot;&gt;import requests

class main_sms:
	def __init__(self, token):
		self.token = token #Токен будем передавать в класс
		self.link = &amp;#x27;https://365sms.ru/stubs/handler_api.php&amp;#x27; #Ссылка для работы с api берём с сайта


	def get_balanse(self): #Функция для получения текущего баланса на сайте
		balans = requests.get(f&amp;#x27;{self.link}?api_key={self.token}&amp;amp;action=getBalance&amp;#x27;) #Делаем get апрос для получения данных
		if &amp;#x27;ACCESS_BALANCE&amp;#x27; in balans.text: #если мы успешно получили баланс то возращаем его
			spisok = balans.text.split(&amp;#x27;:&amp;#x27;) #Сплитуем(разделяем) текст по : который получили в ответе от сайта
			return spisok[1] #Возращаем баланс
		else:
			return balans.text #В ином случае возращаем весь текст который получили, для дальнейшей обработки


	def new_number(self, servis, strana, operator=None): #Функия для получения номера телефона
		if operator == None: #Если мы не передали оператор, то сайт нам выдаст рандомного оператора
			number = requests.get(f&amp;#x27;{self.link}?api_key={self.token}&amp;amp;action=getNumber&amp;amp;service={servis}&amp;amp;country={strana}&amp;#x27;) #Делаем гет запрос без учёта оператора
		else: #В ином случае мы передаём в запрос ещё и оператора
			number = requests.get(f&amp;#x27;{self.link}?api_key={self.token}&amp;amp;action=getNumber&amp;amp;service={servis}&amp;amp;operator={operator}&amp;amp;country={strana}&amp;#x27;)#Делаем гет запрос с учётом оператора
		return number.text #Возращаем всё что получили в ответ от сайта

	def new_status(self, idi, status): #Функция для изменения статуса номера
		stat = requests.get(f&amp;#x27;{self.link}?api_key={self.token}&amp;amp;action=setStatus&amp;amp;status={status}&amp;amp;id={idi}&amp;#x27;) #Делаем гет запрос
		return stat.text #Возращаем всё что получили в ответ от сайта

	def get_status(self, idi): #Получаем статус номера по его id
		stat = requests.get(f&amp;#x27;{self.link}?api_key={self.token}&amp;amp;action=getStatus&amp;amp;id={idi}&amp;#x27;) #Делаем гет запрос
		return stat.text #Возращаем всё что получили в ответ от сайта

	def get_all_price(self, strana, servis=None):
		if servis == None: #Если не передали сервис
			spisok = requests.get(f&amp;#x27;{self.link}?api_key={self.token}&amp;amp;action=getPrices&amp;amp;country={strana}&amp;#x27;) #Делаем гет запрос без учёта сервиса
		else: #В ином случае при передаче сервиса
			spisok = requests.get(f&amp;#x27;{self.link}?api_key={self.token}&amp;amp;action=getPrices&amp;amp;service={servis}&amp;amp;country={strana}&amp;#x27;) #Делаем гет запрос с учётом сервиса
		return spisok.json() #Возращаем всё что получили в ответ от сайта в формате json&lt;/pre&gt;
  &lt;p id=&quot;Cl8G&quot;&gt;Давайте перейдём к файлу test.py:&lt;/p&gt;
  &lt;p id=&quot;glC9&quot;&gt;И напишем в него код с клавиатурой (для начала напишем 1 текстовую кнопку):&lt;/p&gt;
  &lt;pre id=&quot;XjHI&quot; data-lang=&quot;python&quot;&gt;from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, KeyboardButton, ReplyKeyboardMarkup


mainy = [[&amp;#x27;Получить баланс&amp;#x27;]]
mark_menu = ReplyKeyboardMarkup(mainy, resize_keyboard=True)&lt;/pre&gt;
  &lt;p id=&quot;au2E&quot;&gt;Клавиатура создана, перейдём к файлу config.py:&lt;/p&gt;
  &lt;pre id=&quot;nO2O&quot; data-lang=&quot;python&quot;&gt;token_bot = &amp;#x27;Токен вашего бота&amp;#x27;
admin = Ваш id телеграма в формате 123
token_sms = &amp;#x27;Токен с сайта 365sms.ru/account&amp;#x27;
#Данные для подключения к базе данных
host = &amp;#x27;localhost&amp;#x27;
port = 8080
user = &amp;#x27;root&amp;#x27;
password = &amp;#x27;password&amp;#x27;
database = &amp;#x27;database_sms&amp;#x27;&lt;/pre&gt;
  &lt;p id=&quot;2YSa&quot;&gt;Токен бота берём в &lt;a href=&quot;https://t.me/BotFather&quot; target=&quot;_blank&quot;&gt;@BotFather&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;qqSG&quot;&gt;ID берём из &lt;a href=&quot;https://t.me/Bsc_Black_Secret_Club_bot&quot; target=&quot;_blank&quot;&gt;@Bsc_Black_Secret_Club_bot&lt;/a&gt; -&amp;gt; Профиль&lt;/p&gt;
  &lt;p id=&quot;AaZJ&quot;&gt;Токен смс берём с &lt;a href=&quot;https://365sms.ru/account&quot; target=&quot;_blank&quot;&gt;365sms.ru/account&lt;/a&gt;&lt;/p&gt;
  &lt;figure id=&quot;0hnX&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/46/6e/466e21d0-f465-48ff-83a3-37bf28324e96.png&quot; width=&quot;1059&quot; /&gt;
    &lt;figcaption&gt;Берём из этого поля&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;WgFW&quot;&gt;Перейдём к самому интересному, к файлу main.py:&lt;/p&gt;
  &lt;p id=&quot;WBoM&quot;&gt;Импортируем нужные нам модули:&lt;/p&gt;
  &lt;pre id=&quot;8IF7&quot; data-lang=&quot;python&quot;&gt;from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, KeyboardButton, ReplyKeyboardMarkup, BotCommand, WebAppInfo
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
import config as c
import test as bb
import asyncio
import pymysql
from class_db import work_db
from module_sms import main_sms&lt;/pre&gt;
  &lt;p id=&quot;HhAL&quot;&gt;Давайте напишем все экземпляры классов которые нам понадобятся:&lt;/p&gt;
  &lt;pre id=&quot;7tJr&quot; data-lang=&quot;python&quot;&gt;bot = Bot(token=c.token_bot, parse_mode=types.ParseMode.HTML) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot, storage=MemoryStorage())
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига
work_sms = main_sms(c.token_sms) #Создаём экземпляр класса для работы с сервисом смс&lt;/pre&gt;
  &lt;p id=&quot;8Act&quot;&gt;Напишем обработчик всего текста, в который напишем обработку команды /start и текстовой кнопки &amp;quot;Получить баланс&amp;quot;:&lt;/p&gt;
  &lt;pre id=&quot;jvRP&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;])
async def text(message: types.Message):
    id_user = message.from_user.id #Записываем id пользователя (Ранее писали message.chat.id)
    if message.text == &amp;#x27;/start&amp;#x27;:
    	await bot.send_message(id_user, &amp;#x27;Хай, вы попали в смс бота для работы с сайтом 365sms.ru&amp;#x27;, reply_markup=bb.mark_menu) #При команде старт отправляем приветственное сообщение и рассказываем о себе, и выводим клавиатуру
    elif message.text == &amp;#x27;Получить баланс&amp;#x27;:
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	await bot.send_message(id_user, f&amp;#x27;Текущий баланс: {balanse_sms}₽&amp;#x27;) #Пока выводим то что получили от сайта&lt;/pre&gt;
  &lt;p id=&quot;ox9K&quot;&gt;У нас получился такой код:&lt;/p&gt;
  &lt;pre id=&quot;0gvA&quot; data-lang=&quot;python&quot;&gt;from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, KeyboardButton, ReplyKeyboardMarkup, BotCommand, WebAppInfo
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
import config as c
import test as bb
import asyncio
import pymysql
from class_db import work_db
from module_sms import main_sms



bot = Bot(token=c.token_bot, parse_mode=types.ParseMode.HTML) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot, storage=MemoryStorage())
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига
work_sms = main_sms(c.token_sms) #Создаём экземпляр класса для работы с сервисом смс



@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;])
async def text(message: types.Message):
    id_user = message.from_user.id #Записываем id пользователя (Ранее писали message.chat.id)
    if message.text == &amp;#x27;/start&amp;#x27;:
    	await bot.send_message(id_user, &amp;#x27;Хай, вы попали в смс бота для работы с сайтом 365sms.ru&amp;#x27;, reply_markup=bb.mark_menu) #При команде старт отправляем приветственное сообщение и рассказываем о себе, и выводим клавиатуру
    elif message.text == &amp;#x27;Получить баланс&amp;#x27;:
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	await bot.send_message(id_user, f&amp;#x27;Текущий баланс: {balanse_sms}₽&amp;#x27;) #Пока выводим то что получили от сайта



if __name__ == &amp;quot;__main__&amp;quot;:
    executor.start_polling(dp, skip_updates=True)&lt;/pre&gt;
  &lt;p id=&quot;D7in&quot;&gt;Запускаем и проверяем работоспособность:&lt;/p&gt;
  &lt;figure id=&quot;TKFT&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b4/aa/b4aada72-23fe-4aa4-95c9-d9c1e7b24657.png&quot; width=&quot;511&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;vLAT&quot;&gt;Работает, отлично, теперь давайте сделаем обработчик ошибок:&lt;/p&gt;
  &lt;p id=&quot;liGG&quot;&gt;Возможные ошибки у метода гет баланс:&lt;/p&gt;
  &lt;figure id=&quot;JhnF&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/84/4d/844d37fa-ef6b-4e8a-8dd7-32c0249a9236.png&quot; width=&quot;402&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;m12r&quot;&gt;И так у нас получился такой код:&lt;/p&gt;
  &lt;pre id=&quot;QPE6&quot; data-lang=&quot;python&quot;&gt;elif message.text == &amp;#x27;Получить баланс&amp;#x27;:
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	try:
    		await bot.send_message(id_user, f&amp;#x27;Текущий баланс: {float(balanse_sms):.2f}₽&amp;#x27;) #Пока выводим то что получили от сайта
    	except:
    		if &amp;#x27;BAD_KEY&amp;#x27; in balanse_sms:
    			await bot.send_message(id_user, &amp;#x27;Не правильный токен для запроса, проверьте и обновите его!&amp;#x27;) #Если указали не верный токен
    		elif &amp;#x27;ERROR_SQL&amp;#x27; in balanse_sms:
    			await bot.send_message(id_user, &amp;#x27;Ошибка на стороне сайта поопробуйте позже!&amp;#x27;) #Если на сайте произошла ошибка
    		else:
    			await bot.send_message(id_user, &amp;#x27;Ваш запрос был составлен не правильно!&amp;#x27;) #Если мы не правильно составили запрос (в уроке такого не будет)&lt;/pre&gt;
  &lt;p id=&quot;4maR&quot;&gt;Давайте впишем не правильный токен в конфиг -&amp;gt; токен смс&lt;/p&gt;
  &lt;figure id=&quot;14Le&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7f/97/7f97e6b3-efab-406c-bbc6-8d279045d255.png&quot; width=&quot;174&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ruuf&quot;&gt;Запускаем и проверяем обработку ошибок:&lt;/p&gt;
  &lt;p id=&quot;M0oh&quot;&gt;Всё работает, мы молодцы!&lt;/p&gt;
  &lt;figure id=&quot;Lw84&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/54/9a/549a1583-b6e9-4a27-a9e0-773174d9e133.png&quot; width=&quot;497&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;XGIv&quot;&gt;Давайте добавим инлайн кнопку к сообщению с балансом (обновить)&lt;/p&gt;
  &lt;p id=&quot;dcTQ&quot;&gt;Сделаем интересную систему и добавим время к сообщению:&lt;/p&gt;
  &lt;p id=&quot;EuSF&quot;&gt;Добавим импорты модулей для работы со временем:&lt;/p&gt;
  &lt;pre id=&quot;CsFO&quot; data-lang=&quot;python&quot;&gt;from datetime import datetime
import pytz&lt;/pre&gt;
  &lt;p id=&quot;0GTC&quot;&gt;Создадим функцию которая поможет нам получать время в Москве (в формате Часы:Минуты:Секунды):&lt;/p&gt;
  &lt;pre id=&quot;BiEs&quot; data-lang=&quot;python&quot;&gt;def time_Moscow():
	# Устанавливаем часовой пояс Москвы
	moscow_tz = pytz.timezone(&amp;#x27;Europe/Moscow&amp;#x27;)

	# Получаем текущее время в часовом поясе Москвы
	moscow_time = datetime.now(moscow_tz)

	# Форматируем время в часы:минуты:секунды
	formatted_time = moscow_time.strftime(&amp;#x27;%H:%M:%S&amp;#x27;)
	return str(formatted_time) #Возвращаем строку с временем&lt;/pre&gt;
  &lt;p id=&quot;2B65&quot;&gt;Обновим обработчик кнопки получить баланс:&lt;/p&gt;
  &lt;pre id=&quot;koZd&quot; data-lang=&quot;python&quot;&gt;elif message.text == &amp;#x27;Получить баланс&amp;#x27;:
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	time_msk = time_Moscow() #Получаем время мск
    	try:
    		await bot.send_message(id_user, f&amp;#x27;&amp;lt;b&amp;gt;[{time_msk}]&amp;lt;/b&amp;gt; Текущий баланс: {float(balanse_sms):.2f}₽&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    		InlineKeyboardButton(text=&amp;#x27;Обновить&amp;#x27;, callback_data=&amp;#x27;new_balance&amp;#x27;))) #Пока выводим то что получили от сайта
    	except:
    		if &amp;#x27;BAD_KEY&amp;#x27; in balanse_sms:
    			await bot.send_message(id_user, &amp;#x27;Не правильный токен для запроса, проверьте и обновите его!&amp;#x27;) #Если указали не верный токен
    		elif &amp;#x27;ERROR_SQL&amp;#x27; in balanse_sms:
    			await bot.send_message(id_user, &amp;#x27;Ошибка на стороне сайта поопробуйте позже!&amp;#x27;) #Если на сайте произошла ошибка
    		else:
    			await bot.send_message(id_user, &amp;#x27;Ваш запрос был составлен не правильно!&amp;#x27;) #Если мы не правильно составили запрос (в уроке такого не будет)&lt;/pre&gt;
  &lt;p id=&quot;epFT&quot;&gt;Добавлено:&lt;/p&gt;
  &lt;ol id=&quot;yUpx&quot;&gt;
    &lt;li id=&quot;7oqW&quot;&gt;Получение времени в Москве&lt;/li&gt;
    &lt;li id=&quot;jbsG&quot;&gt;Вывод времени и баланса c кнопкой обновить&lt;/li&gt;
  &lt;/ol&gt;
  &lt;pre id=&quot;QgRm&quot; data-lang=&quot;python&quot;&gt;await bot.send_message(id_user, f&amp;#x27;&amp;lt;b&amp;gt;[{time_msk}]&amp;lt;/b&amp;gt; Текущий баланс: {float(balanse_sms):.2f}₽&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    		InlineKeyboardButton(text=&amp;#x27;Обновить&amp;#x27;, callback_data=&amp;#x27;new_balance&amp;#x27;))) #Пока выводим то что получили от сайта&lt;/pre&gt;
  &lt;p id=&quot;3K8O&quot;&gt;Давайте напишем обработчик инлайн кнопок и напишем обработку нажатия кнопки обновить:&lt;/p&gt;
  &lt;pre id=&quot;MTJc&quot; data-lang=&quot;python&quot;&gt;@dp.callback_query_handler(lambda call: True, state=&amp;#x27;*&amp;#x27;)
async def callback_inline(call, state: FSMContext):
    id_user = call.from_user.id
    if call.data == &amp;#x27;new_balance&amp;#x27;:
    	time_msk = time_Moscow() #Получаем время мск
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=f&amp;#x27;{call.message.html_text}\n&amp;lt;b&amp;gt;[{time_msk}]&amp;lt;/b&amp;gt; Текущий баланс: {float(balanse_sms):.2f}₽&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    		InlineKeyboardButton(text=&amp;#x27;Обновить&amp;#x27;, callback_data=&amp;#x27;new_balance&amp;#x27;)))&lt;/pre&gt;
  &lt;ol id=&quot;Zq3h&quot;&gt;
    &lt;li id=&quot;fTcZ&quot;&gt;edit_message_text - с помощью этого метода у бота, мы будем редактировать сообщение&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;bPoA&quot;&gt;Давайте проверим как это работает:&lt;/p&gt;
  &lt;figure id=&quot;bLJS&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/87/ba/87ba4794-0153-4e7d-9232-72ed4ab92eaa.png&quot; width=&quot;326&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;eQDO&quot;&gt;Время работает, а что на счёт кнопки обновить?&lt;/p&gt;
  &lt;figure id=&quot;mvEa&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/67/a5/67a5570e-5b6b-4ef0-b3a7-4cc928197b3c.png&quot; width=&quot;332&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;BIaB&quot;&gt;Тоже работает, отлично!&lt;/p&gt;
  &lt;p id=&quot;zwPZ&quot;&gt;Давайте добавим кнопку получить номер?&lt;/p&gt;
  &lt;p id=&quot;qq21&quot;&gt;Конечно давайте, я вас не буду спрашивать а просто напишу)&lt;/p&gt;
  &lt;blockquote id=&quot;sVEw&quot;&gt;Признайся, улыбнулся?)&lt;/blockquote&gt;
  &lt;p id=&quot;vOxh&quot;&gt;В файл test.py меняем код на:&lt;/p&gt;
  &lt;pre id=&quot;jLGm&quot; data-lang=&quot;python&quot;&gt;mainy = [[&amp;#x27;Получить баланс&amp;#x27;, &amp;#x27;Получить номер&amp;#x27;]]
mark_menu = ReplyKeyboardMarkup(mainy, resize_keyboard=True)&lt;/pre&gt;
  &lt;p id=&quot;1k8p&quot;&gt;Напишем обработчик новой кнопки:&lt;/p&gt;
  &lt;pre id=&quot;o5UF&quot; data-lang=&quot;python&quot;&gt;elif message.text == &amp;#x27;Получить номер&amp;#x27;:
    	#Будем получать номер для вк без оператора и регистрироваться через бота (Страну возьмём индонезию потому что дёшево ID: 6)
    	number = work_sms.new_number(servis=&amp;#x27;vk&amp;#x27;, strana=6)
    	#Обработаем ошибки:
    	if number == &amp;#x27;NO_NUMBERS&amp;#x27;: #Если пришёл ответ что нет номеров
    		await bot.send_message(id_user, &amp;#x27;Нет номеров с заданными параметрами, попробуйте позже, или поменяйте оператора, страну&amp;#x27;, reply_markup=bb.mark_menu)
    	elif number == &amp;#x27;NO_BALANCE&amp;#x27;: #Если на балансе не хватает денег на номер телефона
    		await bot.send_message(id_user, &amp;#x27;Закончились деньги на аккаунте&amp;#x27;, reply_markup=bb.mark_menu)
    	elif number == &amp;#x27;WRONG_SERVICE&amp;#x27;: #Если не правильно указали &amp;quot;servis&amp;quot;
    		await bot.send_message(id_user, &amp;#x27;Неверный идентификатор сервиса&amp;#x27;, reply_markup=bb.mark_menu)
    	else: #Если номер упешно получен
    		#В ответе будет такой формат: ACCESS_NUMBER:ID:NUMBER - Пример: ACCESS_NUMBER:234242:79123456789
    		#Делим ответ на список:
    		info_number = number.split(&amp;#x27;:&amp;#x27;)
    		#Итоговый список будет выглядеть так: [&amp;#x27;ACCESS_NUMBER&amp;#x27;, &amp;#x27;ID&amp;#x27;, &amp;#x27;NUMBER&amp;#x27;] - Пример: [&amp;#x27;ACCESS_NUMBER&amp;#x27;, &amp;#x27;234242&amp;#x27;, &amp;#x27;79123456789&amp;#x27;]
    		#Индексы списка начинаються с 0
    		#т.е с индексом 0 - &amp;#x27;ACCESS_NUMBER&amp;#x27;, c индексом 1 - &amp;#x27;ID&amp;#x27;, c индексом 2 - &amp;#x27;NUMBER&amp;#x27;
    		#Отправляем данные пользователю:
    		await bot.send_message(id_user, f&amp;#x27;ID номера: {info_number[1]}\nНомер: &amp;lt;code&amp;gt;{info_number[2]}&amp;lt;/code&amp;gt;&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    			InlineKeyboardButton(text=&amp;#x27;Изменить статус&amp;#x27;, callback_data=f&amp;#x27;new_status_{info_number[1]}&amp;#x27;))) #Передаём id номера в callback_data&lt;/pre&gt;
  &lt;p id=&quot;QkNR&quot;&gt;Давайте добавим кнопки к последнему сообщению для работы с номером, например сделаем кнопку для &lt;a href=&quot;#tl2F&quot;&gt;обновления статуса:&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;7JiO&quot; data-lang=&quot;python&quot;&gt;await bot.send_message(f&amp;#x27;ID номера: {info_number[1]}\nНомер: &amp;lt;code&amp;gt;{info_number[2]}&amp;lt;/code&amp;gt;&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    			InlineKeyboardButton(text=&amp;#x27;Изменить статус&amp;#x27;, callback_data=f&amp;#x27;new_status_{info_number[1]}&amp;#x27;))) #Передаём id номера в callback_data&lt;/pre&gt;
  &lt;p id=&quot;UEWm&quot;&gt;Давайте напишем обработчик нажатия этой кнопки:&lt;/p&gt;
  &lt;pre id=&quot;l1cl&quot; data-lang=&quot;python&quot;&gt;elif &amp;#x27;new_status_&amp;#x27; in call.data: #В call.data содержиться callback_data
    	id_number = int(call.data.replace(&amp;#x27;new_status_&amp;#x27;, &amp;#x27;&amp;#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
		#Грубыми словами с помощью replace мы заменяем new_status_ на ничего
		#Отправим клавиатуру с дальнейшими статусами, перед этим проверив текущий статус номера&lt;/pre&gt;
  &lt;p id=&quot;XmX4&quot;&gt;Сейчас нам нужно проверить текущий статус номера:&lt;/p&gt;
  &lt;pre id=&quot;CIe0&quot; data-lang=&quot;python&quot;&gt;elif &amp;#x27;new_status_&amp;#x27; in call.data: #В call.data содержиться callback_data
    	id_number = int(call.data.replace(&amp;#x27;new_status_&amp;#x27;, &amp;#x27;&amp;#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
    	#Грубыми словами с помощью replace мы заменяем new_status_ на ничего
    	#Отправим клавиатуру с дальнейшими статусами, перед этим проверив текущий статус номера
    	status_number = work_sms.get_status(idi=id_number)
    	#Давайте в зависимости от статуса выведем клавиатуру:
    	if status_number == &amp;#x27;STATUS_WAIT_CODE&amp;#x27;: #Данный статус будет после получения номера он означает &amp;quot;Ожидание смс&amp;quot;
    		await call.answer(&amp;#x27;Текущий статус: Ожидает смс&amp;#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &amp;quot;ОК&amp;quot;)
    	elif status_number == &amp;#x27;STATUS_CANCEL&amp;#x27;: #Данный статус будет после отмены номера он означает &amp;quot;Активация отменена&amp;quot;
    		await call.answer(&amp;#x27;Текущий статус: Активация отменена&amp;#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &amp;quot;ОК&amp;quot;)
    	else: #Т.к. больше статусов которые может вернуть сайт нет, будем обабатывать успешное получение смс
    		#Делим полученное сообение на список с помощью split
    		kode_aktivate = status_number.split(&amp;#x27;:&amp;#x27;) #Получили список [&amp;quot;STATUS_OK&amp;quot;, &amp;quot;CODE&amp;quot;]
    		await call.answer(f&amp;#x27;Текущий статус: Смс получено\nКод: {kode_aktivate[1]}&amp;#x27;, show_alert=True)&lt;/pre&gt;
  &lt;p id=&quot;l2qK&quot;&gt;Давайте обозначим каждый статус своей цифрой:&lt;/p&gt;
  &lt;pre id=&quot;KA0Q&quot; data-lang=&quot;python&quot;&gt;elif &amp;#x27;new_status_&amp;#x27; in call.data: #В call.data содержиться callback_data
    	id_number = int(call.data.replace(&amp;#x27;new_status_&amp;#x27;, &amp;#x27;&amp;#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
    	#Грубыми словами с помощью replace мы заменяем new_status_ на ничего
    	#Отправим клавиатуру с дальнейшими статусами, перед этим проверив текущий статус номера
    	status_number = work_sms.get_status(idi=id_number)
    	#Давайте в зависимости от статуса выведем клавиатуру:
    	if status_number == &amp;#x27;STATUS_WAIT_CODE&amp;#x27;: #Данный статус будет после получения номера он означает &amp;quot;Ожидание смс&amp;quot;
    		int_status = 0 #Поставим 0 будет означать что номер только что получен
    		await call.answer(&amp;#x27;Текущий статус: Ожидает смс&amp;#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &amp;quot;ОК&amp;quot;)
    	elif status_number == &amp;#x27;STATUS_CANCEL&amp;#x27;: #Данный статус будет после отмены номера он означает &amp;quot;Активация отменена&amp;quot;
    		int_status = 1 #Поставим 1 будет означать что номер больше не активен (отменён)
    		await call.answer(&amp;#x27;Текущий статус: Активация отменена&amp;#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &amp;quot;ОК&amp;quot;)
    	else: #Т.к. больше статусов которые может вернуть сайт нет, будем обабатывать успешное получение смс
    		#Делим полученное сообение на список с помощью split
    		kode_aktivate = status_number.split(&amp;#x27;:&amp;#x27;) #Получили список [&amp;quot;STATUS_OK&amp;quot;, &amp;quot;CODE&amp;quot;]
    		int_status = 2 #Поставим 2 будет означать что смс получен
    		await call.answer(f&amp;#x27;Текущий статус: Смс получено\nКод: {kode_aktivate[1]}&amp;#x27;, show_alert=True)&lt;/pre&gt;
  &lt;p id=&quot;mt3q&quot;&gt;Статусы обозначили, теперь давайте под каждый статус сделаем свою клавиатуру:&lt;/p&gt;
  &lt;pre id=&quot;c2Yh&quot; data-lang=&quot;python&quot;&gt;elif &amp;#x27;new_status_&amp;#x27; in call.data: #В call.data содержиться callback_data
    	id_number = int(call.data.replace(&amp;#x27;new_status_&amp;#x27;, &amp;#x27;&amp;#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
    	#Грубыми словами с помощью replace мы заменяем new_status_ на ничего
    	#Отправим клавиатуру с дальнейшими статусами, перед этим проверив текущий статус номера
    	status_number = work_sms.get_status(idi=id_number)
    	#Давайте в зависимости от статуса выведем клавиатуру:
    	if status_number == &amp;#x27;STATUS_WAIT_CODE&amp;#x27;: #Данный статус будет после получения номера он означает &amp;quot;Ожидание смс&amp;quot;
    		int_status = 0 #Поставим 0 будет означать что номер только что получен
    		await call.answer(&amp;#x27;Текущий статус: Ожидает смс&amp;#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &amp;quot;ОК&amp;quot;)
    	elif status_number == &amp;#x27;STATUS_CANCEL&amp;#x27;: #Данный статус будет после отмены номера он означает &amp;quot;Активация отменена&amp;quot;
    		int_status = 1 #Поставим 1 будет означать что номер больше не активен (отменён)
    		await call.answer(&amp;#x27;Текущий статус: Активация отменена&amp;#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &amp;quot;ОК&amp;quot;)
    	else: #Т.к. больше статусов которые может вернуть сайт нет, будем обабатывать успешное получение смс
    		#Делим полученное сообение на список с помощью split
    		kode_aktivate = status_number.split(&amp;#x27;:&amp;#x27;) #Получили список [&amp;quot;STATUS_OK&amp;quot;, &amp;quot;CODE&amp;quot;]
    		int_status = 2 #Поставим 2 будет означать что смс получен
    		await call.answer(f&amp;#x27;Текущий статус: Смс получено\nКод: {kode_aktivate[1]}&amp;#x27;, show_alert=True)
    	#Сделаем стандартную клавиатуру с дефолтной нопкой:
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&amp;#x27;Узнать статус&amp;#x27;, callback_data=f&amp;#x27;new_status_{id_number}&amp;#x27;))
    	if int_status == 0:
    		klawa.add(InlineKeyboardButton(text=&amp;#x27;Отменить активацию&amp;#x27;, callback_data=f&amp;#x27;cancel_akt_{id_number}&amp;#x27;))
    	elif int_status == 1:
    		klawa.add(InlineKeyboardButton(text=&amp;#x27;Получить новый номер&amp;#x27;, callback_data=&amp;#x27;new_number&amp;#x27;))
    	else:
    		klawa.add(InlineKeyboardButton(text=&amp;#x27;Подтвердить SMS-код и завершить активацию&amp;#x27;, callback_data=f&amp;#x27;true_aktiv_{id_number}&amp;#x27;),
    			InlineKeyboardButton(text=&amp;#x27;Запросить еще одну смс&amp;#x27;, callback_data=f&amp;#x27;dop_sms_{id_number}&amp;#x27;))
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=call.message.html_text, reply_markup=klawa)&lt;/pre&gt;
  &lt;p id=&quot;b6Ra&quot;&gt;Создали и отредактировали сообщение, теперь сделаем проверку try except, т.к. aiogram не позволяет редактировать сообщение на тот же самый текст что и был (что и с кнопками):&lt;/p&gt;
  &lt;pre id=&quot;4T9z&quot; data-lang=&quot;python&quot;&gt;elif &amp;#x27;new_status_&amp;#x27; in call.data: #В call.data содержиться callback_data
    	id_number = int(call.data.replace(&amp;#x27;new_status_&amp;#x27;, &amp;#x27;&amp;#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
    	#Грубыми словами с помощью replace мы заменяем new_status_ на ничего
    	#Отправим клавиатуру с дальнейшими статусами, перед этим проверив текущий статус номера
    	status_number = work_sms.get_status(idi=id_number)
    	#Давайте в зависимости от статуса выведем клавиатуру:
    	if status_number == &amp;#x27;STATUS_WAIT_CODE&amp;#x27;: #Данный статус будет после получения номера он означает &amp;quot;Ожидание смс&amp;quot;
    		int_status = 0 #Поставим 0 будет означать что номер только что получен
    		await call.answer(&amp;#x27;Текущий статус: Ожидает смс&amp;#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &amp;quot;ОК&amp;quot;)
    	elif status_number == &amp;#x27;STATUS_CANCEL&amp;#x27;: #Данный статус будет после отмены номера он означает &amp;quot;Активация отменена&amp;quot;
    		int_status = 1 #Поставим 1 будет означать что номер больше не активен (отменён)
    		await call.answer(&amp;#x27;Текущий статус: Активация отменена&amp;#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &amp;quot;ОК&amp;quot;)
    	else: #Т.к. больше статусов которые может вернуть сайт нет, будем обабатывать успешное получение смс
    		#Делим полученное сообение на список с помощью split
    		kode_aktivate = status_number.split(&amp;#x27;:&amp;#x27;) #Получили список [&amp;quot;STATUS_OK&amp;quot;, &amp;quot;CODE&amp;quot;]
    		int_status = 2 #Поставим 2 будет означать что смс получен
    		await call.answer(f&amp;#x27;Текущий статус: Смс получено\nКод: {kode_aktivate[1]}&amp;#x27;, show_alert=True)
    	#Сделаем стандартную клавиатуру с дефолтной нопкой:
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&amp;#x27;Узнать статус&amp;#x27;, callback_data=f&amp;#x27;new_status_{id_number}&amp;#x27;))
    	if int_status == 0:
    		klawa.add(InlineKeyboardButton(text=&amp;#x27;Отменить активацию&amp;#x27;, callback_data=f&amp;#x27;cancel_akt_{id_number}&amp;#x27;))
    	elif int_status == 1:
    		klawa.add(InlineKeyboardButton(text=&amp;#x27;Получить новый номер&amp;#x27;, callback_data=&amp;#x27;new_number&amp;#x27;))
    	else:
    		klawa.add(InlineKeyboardButton(text=&amp;#x27;Подтвердить SMS-код и завершить активацию&amp;#x27;, callback_data=f&amp;#x27;true_aktiv_{id_number}&amp;#x27;),
    			InlineKeyboardButton(text=&amp;#x27;Запросить еще одну смс&amp;#x27;, callback_data=f&amp;#x27;dop_sms_{id_number}&amp;#x27;))
    	try: #Если смогли отредактировать сообщение
    		await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=call.message.html_text, reply_markup=klawa)
    	except: #Если произошла любая ошибка
    		pass&lt;/pre&gt;
  &lt;p id=&quot;HO9U&quot;&gt;Давайте проверим что мы с вами написали:&lt;/p&gt;
  &lt;figure id=&quot;4AS1&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f7/da/f7daced0-9818-4c56-baa5-12bcedb6460e.png&quot; width=&quot;707&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;IhJ6&quot;&gt;Всё работает, а что на счёт кнопки?&lt;br /&gt;Давайте проверять:&lt;/p&gt;
  &lt;figure id=&quot;ydBz&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/05/7e/057eb163-f8c2-4015-aefe-f3d280af62c4.png&quot; width=&quot;682&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;DSgb&quot;&gt;Работает и даже кнопки поменялись)&lt;/p&gt;
  &lt;p id=&quot;CpKP&quot;&gt;Дальше проверим получение статуса путём нажатия на кнопку:&lt;/p&gt;
  &lt;figure id=&quot;kLdQ&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/28/49/28498069-7f93-4b26-9493-92ded992caeb.png&quot; width=&quot;401&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;9WrE&quot;&gt;И она работает, давайте начнём регистрировать аккаунт в вк на этот номер&lt;/p&gt;
  &lt;p id=&quot;6yp9&quot;&gt;И так я отправил смс на номер, давайте проверим статус&lt;/p&gt;
  &lt;figure id=&quot;AgOr&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1d/0b/1d0b535d-57e6-4f4f-a303-5bc985a8275c.png&quot; width=&quot;691&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;9nDw&quot;&gt;Зарегать вк не получилось, смс на номер индонезии не приходит (отменил номер на сайте), решил поменять на рф озон, меняем код:&lt;/p&gt;
  &lt;pre id=&quot;XMnQ&quot; data-lang=&quot;python&quot;&gt;elif message.text == &amp;#x27;Получить номер&amp;#x27;:
    	#Будем получать номер для вк без оператора и регистрироваться через бота (Страну возьмём индонезию потому что дёшево ID: 6)
    	number = work_sms.new_number(servis=&amp;#x27;sg&amp;#x27;, strana=0)&lt;/pre&gt;
  &lt;p id=&quot;lSxn&quot;&gt;У рф код страны 0&lt;br /&gt;У озона код sg&lt;/p&gt;
  &lt;p id=&quot;LPND&quot;&gt;Получаем новый номер через бота:&lt;/p&gt;
  &lt;figure id=&quot;157m&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/65/87/65876724-c3f8-4e24-8128-6e0f896b5bde.png&quot; width=&quot;712&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;SDsX&quot;&gt;Нажимаем на кнопку изменить статус&lt;/p&gt;
  &lt;p id=&quot;n3o4&quot;&gt;Далее отправляем смс с озона:&lt;/p&gt;
  &lt;figure id=&quot;vaws&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/e4/86/e486b6b6-ced6-4b0f-86f4-fc60b441c52c.png&quot; width=&quot;520&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ZRVT&quot;&gt;Ждём, нажимаем на кнопку получить смс код&lt;/p&gt;
  &lt;p id=&quot;y4k9&quot;&gt;Смс опять не приходит...&lt;/p&gt;
  &lt;p id=&quot;LLdO&quot;&gt;Решил попробовать Qiwi, и наконец то получилось, ну ладно не суть&lt;/p&gt;
  &lt;pre id=&quot;IiOy&quot; data-lang=&quot;python&quot;&gt;number = work_sms.new_number(servis=&amp;#x27;qw&amp;#x27;, strana=0)&lt;/pre&gt;
  &lt;p id=&quot;Catl&quot;&gt;На сайте есть код из смс:&lt;/p&gt;
  &lt;figure id=&quot;FS7n&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b1/fb/b1fbec26-bb41-4ba8-b4b6-1bfde85b95f0.png&quot; width=&quot;1020&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;MvNv&quot;&gt;Проверим статус через бота:&lt;/p&gt;
  &lt;figure id=&quot;aI7t&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/61/9e/619ed30a-9217-4b05-9372-951deda18743.png&quot; width=&quot;362&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;21Vz&quot;&gt;Работает, и опять же кнопки поменялись&lt;/p&gt;
  &lt;p id=&quot;0b8L&quot;&gt;Давайте напишем обработчик кнопки &amp;quot;Запросить ещё одну смс&amp;quot;&lt;/p&gt;
  &lt;pre id=&quot;HGEs&quot; data-lang=&quot;python&quot;&gt;elif &amp;#x27;dop_sms_&amp;#x27; in call.data:
    	id_number = call.data.replace(&amp;#x27;dop_sms_&amp;#x27;, &amp;#x27;&amp;#x27;)
    	await call.answer(&amp;#x27;Новый статус установлен&amp;#x27;, show_alert=True)
    	work_sms.new_status(idi=id_number, status=3) #Устанавливаем статус 3 - нужна повторная смс
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&amp;#x27;Узнать статус&amp;#x27;, callback_data=f&amp;#x27;new_status_{id_number}&amp;#x27;),
    		InlineKeyboardButton(text=&amp;#x27;Подтвердить SMS-код и завершить активацию&amp;#x27;, callback_data=f&amp;#x27;true_aktiv_{id_number}&amp;#x27;))
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=call.message.html_text, reply_markup=klawa)&lt;/pre&gt;
  &lt;p id=&quot;YmHR&quot;&gt;Теперь проверим как она работает&lt;/p&gt;
  &lt;figure id=&quot;4pRk&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/99/e5/99e56484-d8d1-4558-8695-2e52d553643c.png&quot; width=&quot;988&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;BYL8&quot;&gt;Запросил код для отключения смс оповещений:&lt;/p&gt;
  &lt;figure id=&quot;squZ&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/2d/29/2d295c0e-c967-4101-800c-88445a7c710e.png&quot; width=&quot;347&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;jtyU&quot;&gt;Ждём...&lt;br /&gt;Пришёл&lt;/p&gt;
  &lt;figure id=&quot;XvQm&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ac/79/ac791d2d-8183-458f-b6c9-1ef00bbf766e.png&quot; width=&quot;970&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;njUO&quot;&gt;Проверяем в боте&lt;/p&gt;
  &lt;figure id=&quot;6LiD&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/51/04/51040966-7321-4993-9ecb-ca28a2f39e31.png&quot; width=&quot;349&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;1rRb&quot;&gt;Хорошо, работает)&lt;/p&gt;
  &lt;p id=&quot;Y9nc&quot;&gt;Напишем обработчик кнопки &amp;quot;Подтвердить SMS-код и завершить активацию&amp;quot;:&lt;/p&gt;
  &lt;pre id=&quot;L6bD&quot; data-lang=&quot;python&quot;&gt;elif &amp;#x27;true_aktiv_&amp;#x27; in call.data:
    	id_number = call.data.replace(&amp;#x27;true_aktiv_&amp;#x27;, &amp;#x27;&amp;#x27;)
    	await call.answer(&amp;#x27;Новый статус установлен&amp;#x27;, show_alert=True)
    	work_sms.new_status(idi=id_number, status=6) #Устанавливаем статус 6 - Подтвердить SMS-код и завершить активацию
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&amp;#x27;Получить новый номер&amp;#x27;, callback_data=&amp;#x27;new_number&amp;#x27;))
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=f&amp;#x27;{call.message.html_text}\nАктивация завершена&amp;#x27;, reply_markup=klawa)&lt;/pre&gt;
  &lt;p id=&quot;MZHa&quot;&gt;Проверяем в боте&lt;/p&gt;
  &lt;figure id=&quot;rwDZ&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ee/6a/ee6a3cb6-9b52-4c8d-b61a-d9502dc0e0e1.png&quot; width=&quot;350&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;w5Xp&quot;&gt;Теперь напишем обработчик кнопки &amp;quot;Отменить активацию&amp;quot;:&lt;/p&gt;
  &lt;pre id=&quot;8dba&quot; data-lang=&quot;python&quot;&gt;elif &amp;#x27;cancel_akt_&amp;#x27; in call.data:
    	id_number = call.data.replace(&amp;#x27;cancel_akt_&amp;#x27;, &amp;#x27;&amp;#x27;)
    	status_number = work_sms.new_status(idi=id_number, status=8) #Устанавливаем статус 8 - Отменить активацию
    	await call.answer(&amp;#x27;Активация отменена&amp;#x27;, show_alert=True)
    	await bot.send_message(id_user, &amp;#x27;Хай, вы попали в смс бота для работы с сайтом 365sms.ru&amp;#x27;, reply_markup=bb.mark_menu)&lt;/pre&gt;
  &lt;p id=&quot;V0UE&quot;&gt;Проверить не могу, поэтому в дз будет проверить на сколько это работает, в &lt;a href=&quot;https://t.me/Xacker_Name_new&quot; target=&quot;_blank&quot;&gt;лс&lt;/a&gt; пришлёте отчёт)&lt;/p&gt;
  &lt;p id=&quot;fOMc&quot;&gt;Давайте напишем ещё обработчик кнопки &amp;quot;Получить новый номер&amp;quot;:&lt;/p&gt;
  &lt;p id=&quot;fYyr&quot;&gt;Кароч решил просто скопировать код из текстовой кнопки &amp;quot;Получить номер&amp;quot;, а собственно почему нет?&lt;/p&gt;
  &lt;pre id=&quot;EHZJ&quot; data-lang=&quot;python&quot;&gt;elif call.data == &amp;#x27;new_number&amp;#x27;:
    	await bot.delete_message(id_user, call.message.message_id) #Удаляем сообщение
    	#Будем получать номер для вк без оператора и регистрироваться через бота (Страну возьмём индонезию потому что дёшево ID: 6)
    	number = work_sms.new_number(servis=&amp;#x27;qw&amp;#x27;, strana=0)
    	#Обработаем ошибки:
    	if number == &amp;#x27;NO_NUMBERS&amp;#x27;: #Если пришёл ответ что нет номеров
    		await bot.send_message(id_user, &amp;#x27;Нет номеров с заданными параметрами, попробуйте позже, или поменяйте оператора, страну&amp;#x27;, reply_markup=bb.mark_menu)
    	elif number == &amp;#x27;NO_BALANCE&amp;#x27;: #Если на балансе не хватает денег на номер телефона
    		await bot.send_message(id_user, &amp;#x27;Закончились деньги на аккаунте&amp;#x27;, reply_markup=bb.mark_menu)
    	elif number == &amp;#x27;WRONG_SERVICE&amp;#x27;: #Если не правильно указали &amp;quot;servis&amp;quot;
    		await bot.send_message(id_user, &amp;#x27;Неверный идентификатор сервиса&amp;#x27;, reply_markup=bb.mark_menu)
    	else: #Если номер упешно получен
    		#В ответе будет такой формат: ACCESS_NUMBER:ID:NUMBER - Пример: ACCESS_NUMBER:234242:79123456789
    		#Делим ответ на список:
    		info_number = number.split(&amp;#x27;:&amp;#x27;)
    		#Итоговый список будет выглядеть так: [&amp;#x27;ACCESS_NUMBER&amp;#x27;, &amp;#x27;ID&amp;#x27;, &amp;#x27;NUMBER&amp;#x27;] - Пример: [&amp;#x27;ACCESS_NUMBER&amp;#x27;, &amp;#x27;234242&amp;#x27;, &amp;#x27;79123456789&amp;#x27;]
    		#Индексы списка начинаються с 0
    		#т.е с индексом 0 - &amp;#x27;ACCESS_NUMBER&amp;#x27;, c индексом 1 - &amp;#x27;ID&amp;#x27;, c индексом 2 - &amp;#x27;NUMBER&amp;#x27;
    		#Отправляем данные пользователю:
    		await bot.send_message(id_user, f&amp;#x27;ID номера: {info_number[1]}\nНомер: &amp;lt;code&amp;gt;{info_number[2]}&amp;lt;/code&amp;gt;&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    			InlineKeyboardButton(text=&amp;#x27;Изменить статус&amp;#x27;, callback_data=f&amp;#x27;new_status_{info_number[1]}&amp;#x27;))) #Передаём id номера в callback_data&lt;/pre&gt;
  &lt;p id=&quot;Y0eI&quot;&gt;Основные методы я с вами разобрал, сможете ли вы написать текстовую кнопку которая будет красиво выводить данные из метода &lt;a href=&quot;https://365sms.ru/api365#:~:text=%D0%97%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%B8%D1%82%D1%8C%20%D0%B2%D1%81%D0%B5%20%D1%86%D0%B5%D0%BD%D1%8B-,getPrices,-%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%20%D1%81%D1%82%D1%80%D0%B0%D0%BD&quot; target=&quot;_blank&quot;&gt;getPrices&lt;/a&gt;?&lt;/p&gt;
  &lt;p id=&quot;p26i&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;nfLT&quot;&gt;Итоговый код:&lt;/p&gt;
  &lt;pre id=&quot;b5mo&quot; data-lang=&quot;python&quot;&gt;from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, KeyboardButton, ReplyKeyboardMarkup, BotCommand, WebAppInfo
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
import config as c
import test as bb
import asyncio
import pymysql
from class_db import work_db
from module_sms import main_sms
from datetime import datetime
import pytz


bot = Bot(token=c.token_bot, parse_mode=types.ParseMode.HTML) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot, storage=MemoryStorage())
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига
work_sms = main_sms(c.token_sms) #Создаём экземпляр класса для работы с сервисом смс


def time_Moscow():
	# Устанавливаем часовой пояс Москвы
	moscow_tz = pytz.timezone(&amp;#x27;Europe/Moscow&amp;#x27;)

	# Получаем текущее время в часовом поясе Москвы
	moscow_time = datetime.now(moscow_tz)

	# Форматируем время в часы:минуты:секунды
	formatted_time = moscow_time.strftime(&amp;#x27;%H:%M:%S&amp;#x27;)
	return str(formatted_time) #Возвращаем строку с временем


@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;])
async def text(message: types.Message):
    id_user = message.from_user.id #Записываем id пользователя (Ранее писали message.chat.id)
    if message.text == &amp;#x27;/start&amp;#x27;:
    	await bot.send_message(id_user, &amp;#x27;Хай, вы попали в смс бота для работы с сайтом 365sms.ru&amp;#x27;, reply_markup=bb.mark_menu) #При команде старт отправляем приветственное сообщение и рассказываем о себе, и выводим клавиатуру
    elif message.text == &amp;#x27;Получить баланс&amp;#x27;:
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	time_msk = time_Moscow() #Получаем время мск
    	try:
    		await bot.send_message(id_user, f&amp;#x27;&amp;lt;b&amp;gt;[{time_msk}]&amp;lt;/b&amp;gt; Текущий баланс: {float(balanse_sms):.2f}₽&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    		InlineKeyboardButton(text=&amp;#x27;Обновить&amp;#x27;, callback_data=&amp;#x27;new_balance&amp;#x27;))) #Пока выводим то что получили от сайта
    	except:
    		if &amp;#x27;BAD_KEY&amp;#x27; in balanse_sms:
    			await bot.send_message(id_user, &amp;#x27;Не правильный токен для запроса, проверьте и обновите его!&amp;#x27;) #Если указали не верный токен
    		elif &amp;#x27;ERROR_SQL&amp;#x27; in balanse_sms:
    			await bot.send_message(id_user, &amp;#x27;Ошибка на стороне сайта поопробуйте позже!&amp;#x27;) #Если на сайте произошла ошибка
    		else:
    			await bot.send_message(id_user, &amp;#x27;Ваш запрос был составлен не правильно!&amp;#x27;) #Если мы не правильно составили запрос (в уроке такого не будет)
    elif message.text == &amp;#x27;Получить номер&amp;#x27;:
    	#Будем получать номер для вк без оператора и регистрироваться через бота (Страну возьмём индонезию потому что дёшево ID: 6)
    	number = work_sms.new_number(servis=&amp;#x27;qw&amp;#x27;, strana=0)
    	#Обработаем ошибки:
    	if number == &amp;#x27;NO_NUMBERS&amp;#x27;: #Если пришёл ответ что нет номеров
    		await bot.send_message(id_user, &amp;#x27;Нет номеров с заданными параметрами, попробуйте позже, или поменяйте оператора, страну&amp;#x27;, reply_markup=bb.mark_menu)
    	elif number == &amp;#x27;NO_BALANCE&amp;#x27;: #Если на балансе не хватает денег на номер телефона
    		await bot.send_message(id_user, &amp;#x27;Закончились деньги на аккаунте&amp;#x27;, reply_markup=bb.mark_menu)
    	elif number == &amp;#x27;WRONG_SERVICE&amp;#x27;: #Если не правильно указали &amp;quot;servis&amp;quot;
    		await bot.send_message(id_user, &amp;#x27;Неверный идентификатор сервиса&amp;#x27;, reply_markup=bb.mark_menu)
    	else: #Если номер упешно получен
    		#В ответе будет такой формат: ACCESS_NUMBER:ID:NUMBER - Пример: ACCESS_NUMBER:234242:79123456789
    		#Делим ответ на список:
    		info_number = number.split(&amp;#x27;:&amp;#x27;)
    		#Итоговый список будет выглядеть так: [&amp;#x27;ACCESS_NUMBER&amp;#x27;, &amp;#x27;ID&amp;#x27;, &amp;#x27;NUMBER&amp;#x27;] - Пример: [&amp;#x27;ACCESS_NUMBER&amp;#x27;, &amp;#x27;234242&amp;#x27;, &amp;#x27;79123456789&amp;#x27;]
    		#Индексы списка начинаються с 0
    		#т.е с индексом 0 - &amp;#x27;ACCESS_NUMBER&amp;#x27;, c индексом 1 - &amp;#x27;ID&amp;#x27;, c индексом 2 - &amp;#x27;NUMBER&amp;#x27;
    		#Отправляем данные пользователю:
    		await bot.send_message(id_user, f&amp;#x27;ID номера: {info_number[1]}\nНомер: &amp;lt;code&amp;gt;{info_number[2]}&amp;lt;/code&amp;gt;&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    			InlineKeyboardButton(text=&amp;#x27;Изменить статус&amp;#x27;, callback_data=f&amp;#x27;new_status_{info_number[1]}&amp;#x27;))) #Передаём id номера в callback_data


@dp.callback_query_handler(lambda call: True, state=&amp;#x27;*&amp;#x27;)
async def callback_inline(call, state: FSMContext):
    id_user = call.from_user.id
    if call.data == &amp;#x27;new_balance&amp;#x27;:
    	time_msk = time_Moscow() #Получаем время мск
    	balanse_sms = work_sms.get_balanse() #Запрашиваем баланс с сайта по api
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=f&amp;#x27;{call.message.html_text}\n&amp;lt;b&amp;gt;[{time_msk}]&amp;lt;/b&amp;gt; Текущий баланс: {float(balanse_sms):.2f}₽&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    		InlineKeyboardButton(text=&amp;#x27;Обновить&amp;#x27;, callback_data=&amp;#x27;new_balance&amp;#x27;)))
    elif &amp;#x27;new_status_&amp;#x27; in call.data: #В call.data содержиться callback_data
    	id_number = int(call.data.replace(&amp;#x27;new_status_&amp;#x27;, &amp;#x27;&amp;#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
    	#Грубыми словами с помощью replace мы заменяем new_status_ на ничего
    	#Отправим клавиатуру с дальнейшими статусами, перед этим проверив текущий статус номера
    	status_number = work_sms.get_status(idi=id_number)
    	#Давайте в зависимости от статуса выведем клавиатуру:
    	if status_number == &amp;#x27;STATUS_WAIT_CODE&amp;#x27;: #Данный статус будет после получения номера он означает &amp;quot;Ожидание смс&amp;quot;
    		int_status = 0 #Поставим 0 будет означать что номер только что получен
    		await call.answer(&amp;#x27;Текущий статус: Ожидает смс&amp;#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &amp;quot;ОК&amp;quot;)
    	elif status_number == &amp;#x27;STATUS_CANCEL&amp;#x27;: #Данный статус будет после отмены номера он означает &amp;quot;Активация отменена&amp;quot;
    		int_status = 1 #Поставим 1 будет означать что номер больше не активен (отменён)
    		await call.answer(&amp;#x27;Текущий статус: Активация отменена&amp;#x27;, show_alert=True) #Выводим табличку с текущим статусом (show_alert позваляет вывести табличку с кнопко &amp;quot;ОК&amp;quot;)
    	else: #Т.к. больше статусов которые может вернуть сайт нет, будем обабатывать успешное получение смс
    		#Делим полученное сообение на список с помощью split
    		kode_aktivate = status_number.split(&amp;#x27;:&amp;#x27;) #Получили список [&amp;quot;STATUS_OK&amp;quot;, &amp;quot;CODE&amp;quot;]
    		int_status = 2 #Поставим 2 будет означать что смс получен
    		await call.answer(f&amp;#x27;Текущий статус: Смс получено\nКод: {kode_aktivate[1]}&amp;#x27;, show_alert=True)
    	#Сделаем стандартную клавиатуру с дефолтной нопкой:
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&amp;#x27;Узнать статус&amp;#x27;, callback_data=f&amp;#x27;new_status_{id_number}&amp;#x27;))
    	if int_status == 0:
    		klawa.add(InlineKeyboardButton(text=&amp;#x27;Отменить активацию&amp;#x27;, callback_data=f&amp;#x27;cancel_akt_{id_number}&amp;#x27;))
    	elif int_status == 1:
    		klawa.add(InlineKeyboardButton(text=&amp;#x27;Получить новый номер&amp;#x27;, callback_data=&amp;#x27;new_number&amp;#x27;))
    	else:
    		klawa.add(InlineKeyboardButton(text=&amp;#x27;Подтвердить SMS-код и завершить активацию&amp;#x27;, callback_data=f&amp;#x27;true_aktiv_{id_number}&amp;#x27;),
    			InlineKeyboardButton(text=&amp;#x27;Запросить еще одну смс&amp;#x27;, callback_data=f&amp;#x27;dop_sms_{id_number}&amp;#x27;))
    	try: #Если смогли отредактировать сообщение
    		await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=call.message.html_text, reply_markup=klawa)
    	except: #Если произошла любая ошибка
    		pass
    elif &amp;#x27;dop_sms_&amp;#x27; in call.data:
    	id_number = call.data.replace(&amp;#x27;dop_sms_&amp;#x27;, &amp;#x27;&amp;#x27;)
    	await call.answer(&amp;#x27;Новый статус установлен&amp;#x27;, show_alert=True)
    	work_sms.new_status(idi=id_number, status=3) #Устанавливаем статус 3 - нужна повторная смс
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&amp;#x27;Узнать статус&amp;#x27;, callback_data=f&amp;#x27;new_status_{id_number}&amp;#x27;),
    		InlineKeyboardButton(text=&amp;#x27;Подтвердить SMS-код и завершить активацию&amp;#x27;, callback_data=f&amp;#x27;true_aktiv_{id_number}&amp;#x27;))
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=call.message.html_text, reply_markup=klawa)
    elif &amp;#x27;true_aktiv_&amp;#x27; in call.data:
    	id_number = call.data.replace(&amp;#x27;true_aktiv_&amp;#x27;, &amp;#x27;&amp;#x27;)
    	await call.answer(&amp;#x27;Новый статус установлен&amp;#x27;, show_alert=True)
    	work_sms.new_status(idi=id_number, status=6) #Устанавливаем статус 6 - Подтвердить SMS-код и завершить активацию
    	klawa = InlineKeyboardMarkup(row_width=1).add(InlineKeyboardButton(text=&amp;#x27;Получить новый номер&amp;#x27;, callback_data=&amp;#x27;new_number&amp;#x27;))
    	await bot.edit_message_text(chat_id=id_user, message_id=call.message.message_id, text=f&amp;#x27;{call.message.html_text}\nАктивация завершена&amp;#x27;, reply_markup=klawa)
    elif &amp;#x27;cancel_akt_&amp;#x27; in call.data:
    	id_number = call.data.replace(&amp;#x27;cancel_akt_&amp;#x27;, &amp;#x27;&amp;#x27;)
    	status_number = work_sms.new_status(idi=id_number, status=8) #Устанавливаем статус 8 - Отменить активацию
    	await call.answer(&amp;#x27;Активация отменена&amp;#x27;, show_alert=True)
    	await bot.send_message(id_user, &amp;#x27;Хай, вы попали в смс бота для работы с сайтом 365sms.ru&amp;#x27;, reply_markup=bb.mark_menu)
    elif call.data == &amp;#x27;new_number&amp;#x27;:
    	await bot.delete_message(id_user, call.message.message_id) #Удаляем сообщение
    	#Будем получать номер для вк без оператора и регистрироваться через бота (Страну возьмём индонезию потому что дёшево ID: 6)
    	number = work_sms.new_number(servis=&amp;#x27;qw&amp;#x27;, strana=0)
    	#Обработаем ошибки:
    	if number == &amp;#x27;NO_NUMBERS&amp;#x27;: #Если пришёл ответ что нет номеров
    		await bot.send_message(id_user, &amp;#x27;Нет номеров с заданными параметрами, попробуйте позже, или поменяйте оператора, страну&amp;#x27;, reply_markup=bb.mark_menu)
    	elif number == &amp;#x27;NO_BALANCE&amp;#x27;: #Если на балансе не хватает денег на номер телефона
    		await bot.send_message(id_user, &amp;#x27;Закончились деньги на аккаунте&amp;#x27;, reply_markup=bb.mark_menu)
    	elif number == &amp;#x27;WRONG_SERVICE&amp;#x27;: #Если не правильно указали &amp;quot;servis&amp;quot;
    		await bot.send_message(id_user, &amp;#x27;Неверный идентификатор сервиса&amp;#x27;, reply_markup=bb.mark_menu)
    	else: #Если номер упешно получен
    		#В ответе будет такой формат: ACCESS_NUMBER:ID:NUMBER - Пример: ACCESS_NUMBER:234242:79123456789
    		#Делим ответ на список:
    		info_number = number.split(&amp;#x27;:&amp;#x27;)
    		#Итоговый список будет выглядеть так: [&amp;#x27;ACCESS_NUMBER&amp;#x27;, &amp;#x27;ID&amp;#x27;, &amp;#x27;NUMBER&amp;#x27;] - Пример: [&amp;#x27;ACCESS_NUMBER&amp;#x27;, &amp;#x27;234242&amp;#x27;, &amp;#x27;79123456789&amp;#x27;]
    		#Индексы списка начинаються с 0
    		#т.е с индексом 0 - &amp;#x27;ACCESS_NUMBER&amp;#x27;, c индексом 1 - &amp;#x27;ID&amp;#x27;, c индексом 2 - &amp;#x27;NUMBER&amp;#x27;
    		#Отправляем данные пользователю:
    		await bot.send_message(id_user, f&amp;#x27;ID номера: {info_number[1]}\nНомер: &amp;lt;code&amp;gt;{info_number[2]}&amp;lt;/code&amp;gt;&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=1).add(
    			InlineKeyboardButton(text=&amp;#x27;Изменить статус&amp;#x27;, callback_data=f&amp;#x27;new_status_{info_number[1]}&amp;#x27;))) #Передаём id номера в callback_data

if __name__ == &amp;quot;__main__&amp;quot;:
    executor.start_polling(dp, skip_updates=True)&lt;/pre&gt;
  &lt;p id=&quot;ylIo&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;D66M&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;x51L&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;hvl5&quot;&gt;&lt;strong&gt;Вот и дз сформировалось:&lt;/strong&gt;&lt;/p&gt;
  &lt;ol id=&quot;TrQ1&quot;&gt;
    &lt;li id=&quot;dDx1&quot;&gt;&lt;strong&gt;Проверить работу &lt;a href=&quot;#w5Xp&quot;&gt;кода&lt;/a&gt; (если есть ошибки исправить)&lt;/strong&gt;&lt;/li&gt;
    &lt;li id=&quot;2Bog&quot;&gt;&lt;strong&gt;Написать текстовую кнопку которая будет красиво выводить данные метода &lt;a href=&quot;https://365sms.ru/api365#:~:text=%D0%97%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%B8%D1%82%D1%8C%20%D0%B2%D1%81%D0%B5%20%D1%86%D0%B5%D0%BD%D1%8B-,getPrices,-%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA%20%D1%81%D1%82%D1%80%D0%B0%D0%BD&quot; target=&quot;_blank&quot;&gt;getPrices&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
    &lt;li id=&quot;VwIA&quot;&gt;&lt;strong&gt;Подключить базу данных&lt;/strong&gt;&lt;/li&gt;
  &lt;/ol&gt;
  &lt;ol id=&quot;ruiV&quot;&gt;
    &lt;ol id=&quot;ZUXL&quot;&gt;
      &lt;li id=&quot;cbVz&quot;&gt;&lt;strong&gt;Регистрировать пользователей&lt;/strong&gt;&lt;/li&gt;
      &lt;li id=&quot;uexW&quot;&gt;&lt;strong&gt;Считать номера которые они взяли в аренду&lt;/strong&gt;&lt;/li&gt;
      &lt;li id=&quot;WXes&quot;&gt;&lt;strong&gt;Считать номера которые успешно завершили&lt;/strong&gt;&lt;/li&gt;
      &lt;li id=&quot;fiSC&quot;&gt;&lt;strong&gt;Записывать номера в отдельную таблицу&lt;/strong&gt;&lt;/li&gt;
      &lt;ol id=&quot;xH2Q&quot;&gt;
        &lt;li id=&quot;S5Ob&quot;&gt;&lt;strong&gt;ID номера&lt;/strong&gt;&lt;/li&gt;
        &lt;li id=&quot;bfsv&quot;&gt;&lt;strong&gt;Сам номер&lt;/strong&gt;&lt;/li&gt;
        &lt;li id=&quot;xa57&quot;&gt;&lt;strong&gt;Пользователь который взял этот номер&lt;/strong&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/ol&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;KB13&quot;&gt;&lt;strong&gt;ДЗ выполнить в течении 4х дней, так же в канале проходит голосование, что будем изучать дальше!&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;9Fi1&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;N8Mx&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;Vqle&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;XBgD&quot;&gt;Спасибо за внимание&lt;/h2&gt;
  &lt;p id=&quot;nXCL&quot;&gt;С вами был &lt;a href=&quot;https://t.me/Xacker_Name_new&quot; target=&quot;_blank&quot;&gt;@Xacker_Name_new&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;eyUE&quot;&gt;Поддержка: &lt;a href=&quot;https://t.me/Bsc_Black_Secret_Club_bot&quot; target=&quot;_blank&quot;&gt;@Bsc_Black_Secret_Club_bot&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;1piM&quot;&gt;Канал: &lt;a href=&quot;https://t.me/education_python_aiogram&quot; target=&quot;_blank&quot;&gt;@education_python_aiogram&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>xacker_name_new:PqqQ-NNhOfB</id><link rel="alternate" type="text/html" href="https://teletype.in/@xacker_name_new/PqqQ-NNhOfB?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=xacker_name_new"></link><title>Обучение #4</title><published>2023-09-29T06:38:05.083Z</published><updated>2023-09-29T11:59:19.439Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/50/e3/50e31141-824f-4f69-8473-ed3aa0599887.png"></media:thumbnail><category term="obuchenie-python-aiogram-my-sql" label="Обучение Python+aiogram+MySQL"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/3a/72/3a720c74-3487-46cc-ac94-4ec752d144cc.png&quot;&gt;Обучение #4</summary><content type="html">
  &lt;p id=&quot;V4tv&quot;&gt;Хай, как и говорил начнём с удаления данных с базы данных&lt;/p&gt;
  &lt;p id=&quot;kqtM&quot;&gt;Давайте возьмём готовый код из &lt;a href=&quot;https://teletype.in/@xacker_name_new/1ehent_u3EK&quot; target=&quot;_blank&quot;&gt;предыдущего урока&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;QLcn&quot; data-lang=&quot;python&quot;&gt;from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
from aiogram.types import ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton
from class_db import work_db #Импорируем класс для работы с базой данных из файла class_db.py
import test as bb #Импортируем файл test.py в переменную bb (мне так удобнее работать с ним)
import config as c #Импортируем файл config.py в переменную с (опять же мне так удобнее)



#Создаём класс бота и дистпетчера
bot = Bot(token=c.token, parse_mode=types.ParseMode.HTML) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot, storage=MemoryStorage())
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига


class anketa(StatesGroup):
	name = State()
	floor = State()
	age = State()


class new_values(StatesGroup):
	new_value = State()


def creat_table(): #Данную функцию будем запускать при каждом запуске кода, параметры функция не принимает
	#Для начала конектимся к базе данных:
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		creat_table_request = &amp;#x27;CREATE TABLE IF NOT EXISTS &amp;#x60;ankets&amp;#x60;(id int AUTO_INCREMENT, name varchar(32), floor varchar(10), age int, PRIMARY KEY (id));&amp;#x27; #И так мы написали запрос, но для чего он нам?
		#Он нам для того что-бы создать таблицу для анкет где будут следующие данные: id - это будет id анкеты (число), оно будет прописываться само (из-за AUTO_INCREMENT)
		#name типа сроки длинной не более 32 символов, floor типа строки не более 10 символов и age типа числа без ограничения
		#Первичный ключ (PRIMARY KEY) — особенное поле в таблице, которое позволяет однозначно идентифицировать каждую запись в ней
		#Запрос написан, давайте его выполним:
		status = db_work.create_table(connection, creat_table_request) #Предаём необходимые данные (Конект и сам запрос)
		#Проверяем статус создания базы данных:
		if status: #Если вернуло True значит всё хорошо (выведем в консоль что запрос выполнен)
			print(&amp;#x27;Таблица успешно создана&amp;#x27;)
			#Закрываем конект
			if db_work.connect_close(connection):
				print(&amp;#x27;Конект закрыт!&amp;#x27;)
			else: #Если нам вернуло False, значит произошла ошибка, в вспомогательном классе мы прописали вывод ошибки
				print(&amp;#x27;Ошибка указана выше&amp;#x27;)
		else: #Если вернуло False, значит не удалось создать таблицу, ошибку мы так же вывели в классе
			print(&amp;#x27;Ошибка указана выше&amp;#x27;)
	else: #Если мы не смогли подключиться к базе данных, то опять же ошибка была выведена в классе
		print(&amp;#x27;Ошибка указана выше&amp;#x27;)


def insert_table(name_, floor_, age_): #Данная функция принимает имя таблицы в которую надо записать данные (Сразу скажу т.к. мы записывать будет в ankets ропишем получение данных)
	#Для начала конектимся к базе данных:
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		insert_table_request = &amp;#x27;INSERT INTO ankets (name, floor, age) VALUES (%s, %s, %s);&amp;#x27; #И так в этом запросе мы создаём запись данных
		with connection.cursor() as cursor:
			cursor.execute(insert_table_request, (name_, floor_, age_)) #Записываем данные полученные в функцию
		connection.commit() #Сохраняем изменения
		print(&amp;#x27;Данные записаны!&amp;#x27;)
		if db_work.connect_close(connection):
			print(&amp;#x27;Конект закрыт!&amp;#x27;)
		else: #Если нам вернуло False, значит произошла ошибка, в вспомогательном классе мы прописали вывод ошибки
			print(&amp;#x27;Ошибка указана выше&amp;#x27;)
	else: #Если мы не смогли подключиться к базе данных, то опять же ошибка была выведена в классе
		print(&amp;#x27;Ошибка указана выше&amp;#x27;)


@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &amp;quot;text&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &amp;#x27;/start&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Привет, заполни анкету, или посмотри информацйию о мне&amp;#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &amp;#x27;Информация&amp;#x27;:
		await bot.send_message(message.chat.id, f&amp;#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&amp;#x27;)
	elif message.text == &amp;#x27;Заполнить анкету&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите своё имя:&amp;#x27;)
		await anketa.name.set()
	elif message.text == &amp;#x27;/info_table&amp;#x27;:
		info_request = &amp;#x27;SELECT * FROM ankets WHERE id = %s&amp;#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&amp;#x27;Полученные данные:\nID: {info[&amp;quot;id&amp;quot;]}\nИмя: {info[&amp;quot;name&amp;quot;]}\nПол: {info[&amp;quot;floor&amp;quot;]}\nВозраст: {info[&amp;quot;age&amp;quot;]}&amp;#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &amp;#x27;Не удалось получить данные&amp;#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &amp;#x27;Не удалось подключиться к базе данных&amp;#x27;)
	elif message.text == &amp;#x27;/new_value&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите ID для изменения возраста:&amp;#x27;)
		await new_values.new_value.set()


@dp.message_handler(state=new_values.new_value)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем ID в кеш
	await state.update_data(id_value=message.text)
	#Выводим инлайн кнопки с числами
	#Пока напишу прямо тут, в следующих уроках будем создавать функции
	await bot.send_message(message.chat.id, &amp;#x27;Выберите новое значение:&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=3).add(
		InlineKeyboardButton(text=&amp;#x27;1&amp;#x27;, callback_data=&amp;#x27;new_value_1&amp;#x27;),InlineKeyboardButton(text=&amp;#x27;2&amp;#x27;, callback_data=&amp;#x27;new_value_2&amp;#x27;), InlineKeyboardButton(text=&amp;#x27;10&amp;#x27;, callback_data=&amp;#x27;new_value_10&amp;#x27;),
		InlineKeyboardButton(text=&amp;#x27;25&amp;#x27;, callback_data=&amp;#x27;new_value_25&amp;#x27;)))
	#Этого достаточно



@dp.message_handler(state=anketa.name)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем имя в кеш
	await state.update_data(name=message.text)
	#Далее просим ввести пол, с выбором пола из кнопок
	await bot.send_message(message.chat.id, &amp;#x27;Выберите свой пол:&amp;#x27;, reply_markup=bb.menu_floor) #добавляем вывод кнопок с выбором пола
	await anketa.floor.set()


@dp.message_handler(state=anketa.floor)
async def anketa_name(message: types.Message, state: FSMContext):
	#Записываем пол в кеш
	await state.update_data(floor=message.text)
	#Далее просим ввести свой возраст
	await bot.send_message(message.chat.id, &amp;#x27;Введите свой возраст:&amp;#x27;, reply_markup=ReplyKeyboardRemove()) #убираем текстовую клавиатуру
	await anketa.age.set()


@dp.message_handler(state=anketa.age)
async def anketa_name(message: types.Message, state: FSMContext):
	#Получим все данные записанные в кеш
	data = await state.get_data()
	#Сортируем их по переменным
	name = data[&amp;#x27;name&amp;#x27;] #В ковычках пишем name, потому что сами записывали в такую переменную, там может быть любая другая
	floor = data[&amp;#x27;floor&amp;#x27;] #В ковычках пишем floor, потому что сами записывали в такую переменную, там может быть любая другая
	age = message.text #записываем ввод пользователя в переменную age
	await state.finish() #Завершаем работу с машиной состояний
	#Выведем анкету пользователю
	await bot.send_message(message.chat.id, f&amp;#x27;Ваша анкета:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}\n\nСпасибо за уделение времени&amp;#x27;, reply_markup=bb.mark_menu) #Отправляем анкету, благодарим, и выдаём ему текстовоем меню
	#Отправим анкету администратору по его ID из config.py
	#Так же выведем ID пользователя и его юзернейм
	await bot.send_message(c.admin, f&amp;#x27;Пользователь: {message.chat.id}\n@{message.from_user.username} заполнил анкету\nЕго данные:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}&amp;#x27;)
	insert_table(name, floor, age) #Передаём необходимые данные



@dp.callback_query_handler(lambda call: True, state=&amp;#x27;*&amp;#x27;) #Обрабатываем нажатия всех инлайн кнопок, даже когда активно ожидание ввода от пользователя
async def callback_inline(call, state: FSMContext): #В переменную call принимаем данные о нажатой кнопке
	try: #Обрабатываем ошибки, если всё успешно то мы получим переменную id_value на всю функцию
		data = await state.get_data()
		id_value = data[&amp;#x27;id_value&amp;#x27;]
		await state.finish()
	except Exception as eror: #Если будут ошибки мы их пришлём пользователю
		await bot.send_message(call.message.chat.id, f&amp;#x27;Произошла ошибка: {eror}&amp;#x27;)
		return #Останавливаем выполнение функции
	#Приступим к обработке нажатия кнопок, т.к. у нас записано новое чило в callback_data, но начало одно и тоже
	#Нам нужно проверять есть ли в нажатой кнопке начало:
	if &amp;#x27;new_value_&amp;#x27; in call.data: #В call.data содержиться callback_data
		new_value = int(call.data.replace(&amp;#x27;new_value_&amp;#x27;, &amp;#x27;&amp;#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
		#Грубыми словами с помощью replace мы заменяем new_value_ на ничего
		#Теперь давайте заменим значение в таблице по ID которое вписали изначально
		#Конектимся к базе данных:
		connection = db_work.connect_db()
		if connection: #Если конект успешен
			#Возпользуемся функцией edit_table из вспомогательного класса:
			new_value_request = &amp;#x27;UPDATE ankets SET age = %s WHERE id = %s&amp;#x27;
			values = (new_value, int(id_value))
			status = db_work.edit_table(connection, new_value_request, values)
			if status: #Если успешно обновили данные
				await bot.send_message(call.message.chat.id, f&amp;#x27;Данные для строки с ID: {id_value}\nУспешно обновлены на: {new_value}&amp;#x27;)
			else: #Если произошла ошибка
				await bot.send_message(call.message.chat.id, &amp;#x27;Произошла ошибка, она отобразилась в консоли!&amp;#x27;)
		else: #Если не удалось подключиться к базе данных
			await bot.send_message(call.message.chat.id, &amp;#x27;Не удалось подключиться к базе данных!&amp;#x27;)


if __name__ == &amp;quot;__main__&amp;quot;: #Если скрипт запущен с этого файла, запускаем executor
	creat_table() #Запускаем функцию создания таблицы
	executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен&lt;/pre&gt;
  &lt;p id=&quot;MaVi&quot;&gt;Добавим обработку команды &amp;quot;/delete_strok_table&amp;quot;:&lt;/p&gt;
  &lt;pre id=&quot;PZXn&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &amp;quot;text&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &amp;#x27;/start&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Привет, заполни анкету, или посмотри информацйию о мне&amp;#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &amp;#x27;Информация&amp;#x27;:
		await bot.send_message(message.chat.id, f&amp;#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&amp;#x27;)
	elif message.text == &amp;#x27;Заполнить анкету&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите своё имя:&amp;#x27;)
		await anketa.name.set()
	elif message.text == &amp;#x27;/info_table&amp;#x27;:
		info_request = &amp;#x27;SELECT * FROM ankets WHERE id = %s&amp;#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&amp;#x27;Полученные данные:\nID: {info[&amp;quot;id&amp;quot;]}\nИмя: {info[&amp;quot;name&amp;quot;]}\nПол: {info[&amp;quot;floor&amp;quot;]}\nВозраст: {info[&amp;quot;age&amp;quot;]}&amp;#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &amp;#x27;Не удалось получить данные&amp;#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &amp;#x27;Не удалось подключиться к базе данных&amp;#x27;)
	elif message.text == &amp;#x27;/new_value&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите ID для изменения возраста:&amp;#x27;)
		await new_values.new_value.set()
	elif message.text == &amp;#x27;/delete_strok_table&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите ID для удаления:&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;XdNI&quot;&gt;Создадим класс для ожидания ответа от пользователя:&lt;/p&gt;
  &lt;pre id=&quot;u7Ma&quot; data-lang=&quot;python&quot;&gt;class delete_strok_table(StatesGroup):
	id_strok = State()


@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &amp;quot;text&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &amp;#x27;/start&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Привет, заполни анкету, или посмотри информацйию о мне&amp;#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &amp;#x27;Информация&amp;#x27;:
		await bot.send_message(message.chat.id, f&amp;#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&amp;#x27;)
	elif message.text == &amp;#x27;Заполнить анкету&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите своё имя:&amp;#x27;)
		await anketa.name.set()
	elif message.text == &amp;#x27;/info_table&amp;#x27;:
		info_request = &amp;#x27;SELECT * FROM ankets WHERE id = %s&amp;#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&amp;#x27;Полученные данные:\nID: {info[&amp;quot;id&amp;quot;]}\nИмя: {info[&amp;quot;name&amp;quot;]}\nПол: {info[&amp;quot;floor&amp;quot;]}\nВозраст: {info[&amp;quot;age&amp;quot;]}&amp;#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &amp;#x27;Не удалось получить данные&amp;#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &amp;#x27;Не удалось подключиться к базе данных&amp;#x27;)
	elif message.text == &amp;#x27;/new_value&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите ID для изменения возраста:&amp;#x27;)
		await new_values.new_value.set()
	elif message.text == &amp;#x27;/delete_strok_table&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите ID для удаления:&amp;#x27;)
		await delete_strok_table.id_strok.set()&lt;/pre&gt;
  &lt;p id=&quot;I1zS&quot;&gt;Добавим обработчик ввода пользователя:&lt;/p&gt;
  &lt;pre id=&quot;eMxj&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(state=delete_strok_table.id_strok)
async def anketa_name(message: types.Message, state: FSMContext):
	await state.finish() #Завершаем работу с машиной состояний
	id_strok = message.text
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		delete_table = &amp;#x27;DELETE FROM ankets WHERE id = %s&amp;#x27;
		values = (id_strok,)
		status = db_work.delete_from_table(connection, delete_table, values)
		if status: #Если успешно обновили данные
			await bot.send_message(message.chat.id, f&amp;#x27;Данные строки с ID: {id_strok} - Удалены!&amp;#x27;)
		else: #Если произошла ошибка
			await bot.send_message(message.chat.id, &amp;#x27;Произошла ошибка, она отобразилась в консоли!&amp;#x27;)
	else:
		await bot.send_message(message.chat.id, &amp;#x27;Не удалось подключиться к базе данных!&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;8qo1&quot;&gt;Так же давайте перепишем функцию &amp;quot;delete_from_table&amp;quot;:&lt;/p&gt;
  &lt;pre id=&quot;KIhL&quot; data-lang=&quot;python&quot;&gt;	def delete_from_table(self, connection, delete_, values): #Функция для редактирования данных в таблице, в delete_ будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(delete_, values)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False&lt;/pre&gt;
  &lt;p id=&quot;v8GS&quot;&gt;У нас в базе есть запись с ID: 1&lt;/p&gt;
  &lt;figure id=&quot;8LXZ&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/02/06/0206f519-d0f9-4b78-9c42-fc71822811b9.png&quot; width=&quot;292&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;aGjr&quot;&gt;Давайте запустим бота, и удалим её:&lt;/p&gt;
  &lt;figure id=&quot;j3G5&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d8/55/d855de0b-e863-4560-be3d-11b286b9961e.png&quot; width=&quot;698&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;gGuX&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/30/fa/30fa48bd-0b9a-47ab-bf6a-e28b1ba15db6.png&quot; width=&quot;365&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;xUDs&quot;&gt;У нас всё работает, мы молодцы, так держать!&lt;/p&gt;
  &lt;p id=&quot;mzlL&quot;&gt;&lt;s&gt;———————————————————————————————&lt;/s&gt;&lt;/p&gt;
  &lt;p id=&quot;SwyH&quot;&gt;По итогам опроса на &lt;a href=&quot;https://t.me/education_python_aiogram&quot; target=&quot;_blank&quot;&gt;канале&lt;/a&gt;, я понял что вам интересна работа с файлами .txt&lt;/p&gt;
  &lt;p id=&quot;ZOZI&quot;&gt;Давайте немного изучим циклы:&lt;/p&gt;
  &lt;p id=&quot;MFd5&quot;&gt;Цикл while True&lt;br /&gt;Данный цикл позволяет выполнять код пока мы не завершим цикл, пример:&lt;/p&gt;
  &lt;pre id=&quot;8CDZ&quot; data-lang=&quot;python&quot;&gt;#обозначим переменную a = 0
a = 0
#Создадим цикл, и заставим его завешиться толькко после того как переменна a будет равна 5
while True:
   print(a)
   if a == 5:
      print(&amp;#x27;Цикл завершён&amp;#x27;)
      break
   a += 1 #После каждого круга добавляем к переменной a 1
   # &amp;quot;a +=1 &amp;quot; сокращение кода: a = a + 1
#Вывод в консоль будет:
#1
#2
#3
#4
#5
#Цикл завершён&lt;/pre&gt;
  &lt;p id=&quot;ldqJ&quot;&gt;Следующий цикл for i in spisok&lt;br /&gt;Данный цикл перебирает все данные из переменной spisok в переменную i, после чего завершается, пример:&lt;/p&gt;
  &lt;pre id=&quot;ncmH&quot; data-lang=&quot;python&quot;&gt;spisok = [1, 2, 3, 4, 5]
for i in spisok:
    print(i)
print(&amp;#x27;Цикл завершён&amp;#x27;)
#Вывод в консоль:
#1
#2
#3
#4
#5
#Цикл завершён&lt;/pre&gt;
  &lt;p id=&quot;bOjQ&quot;&gt;И так мы изучили базовые циклы, на простых примерах, перейдём к файлам .txt:&lt;/p&gt;
  &lt;p id=&quot;PZX6&quot;&gt;Давайте напишем код который создаст файл index.txt, затем запишем в него данные из списка:&lt;/p&gt;
  &lt;pre id=&quot;t8sx&quot; data-lang=&quot;python&quot;&gt;spisok = [1, 2, 3, 4, 5, 6]

my_file = open(&amp;quot;index.txt&amp;quot;, &amp;quot;w+&amp;quot;) #Создали файл
for i in spisok:
   my_file.write(str(i)) #Записываем данные, меняя тип данных на строку (str)
my_file.close() #После записи, закрываем его&lt;/pre&gt;
  &lt;p id=&quot;Qy3z&quot;&gt;После чего у нас появился файл &amp;quot;index.txt&amp;quot;&lt;/p&gt;
  &lt;figure id=&quot;BAkW&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/3e/74/3e74cf10-1ba4-45e7-b4ed-4f04b5a3557d.png&quot; width=&quot;655&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;ebgQ&quot;&gt;Открываем его:&lt;/p&gt;
  &lt;figure id=&quot;S9B0&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/36/1a/361ac064-81f0-4708-8c81-ac37e6416d17.png&quot; width=&quot;281&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;MieJ&quot;&gt;Данные записались в 1 строку, давайте это исправим, и запишем каждую цифру из списка в новой строке:&lt;/p&gt;
  &lt;pre id=&quot;M25q&quot; data-lang=&quot;python&quot;&gt;spisok = [1, 2, 3, 4, 5, 6]

my_file = open(&amp;quot;index.txt&amp;quot;, &amp;quot;w+&amp;quot;) #Создали файл
for i in spisok:
   my_file.write(f&amp;#x27;{i}\n&amp;#x27;) #Записываем данные, меняя тип данных на строку (str)
my_file.close() #После записи, закрываем его&lt;/pre&gt;
  &lt;p id=&quot;r0ts&quot;&gt;Удаляем файл index.txt, и снова запускаем файл с кодом:&lt;/p&gt;
  &lt;p id=&quot;xcvr&quot;&gt;У нас всё так же появился файл index.txt, открываем его:&lt;/p&gt;
  &lt;figure id=&quot;SEOb&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/76/96/7696bf40-3a45-47bf-a86b-75a7be56a3dd.png&quot; width=&quot;350&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;tceG&quot;&gt;Успешно записали, теперь давайте прочитаем данные и выведем в консоль:&lt;/p&gt;
  &lt;pre id=&quot;iRDK&quot; data-lang=&quot;python&quot;&gt;my_file = open(&amp;quot;index.txt&amp;quot;, &amp;quot;r&amp;quot;) #Открываем файл на чтение
for line in my_file:
   print(line)
my_file.close()&lt;/pre&gt;
  &lt;p id=&quot;MY5B&quot;&gt;Вывод в консоль:&lt;/p&gt;
  &lt;figure id=&quot;Z1JC&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/58/d2/58d2f9c2-1808-4b65-b345-7ca31a36ff63.png&quot; width=&quot;47&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;HK0c&quot;&gt;Он так же выводит нам пустые строки (\n), давайте удалим их:&lt;/p&gt;
  &lt;pre id=&quot;Mv1S&quot; data-lang=&quot;python&quot;&gt;my_file = open(&amp;quot;index.txt&amp;quot;, &amp;quot;r&amp;quot;) #Создали файл
for line in my_file:
   print(line.replace(&amp;#x27;\n&amp;#x27;, &amp;#x27;&amp;#x27;))
my_file.close()&lt;/pre&gt;
  &lt;p id=&quot;YFed&quot;&gt;Вывод в консоль:&lt;/p&gt;
  &lt;figure id=&quot;vUvP&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/bd/a5/bda5d26d-5eb4-4016-bb4b-beb0c1710609.png&quot; width=&quot;39&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;wMYz&quot;&gt;Давайте разберём ещё 1 цикл, для удобства:&lt;/p&gt;
  &lt;pre id=&quot;59LE&quot; data-lang=&quot;python&quot;&gt;with open(&amp;#x27;index.txt&amp;#x27;, &amp;#x27;r&amp;#x27;) as file: #Открываем файл на чтение, в переменную file
   #После открытия файла через этот цикл нам не нужно будет его закрывать каждый раз&lt;/pre&gt;
  &lt;p id=&quot;10kh&quot;&gt;Напишем код который прочитает первые 3 строки файла:&lt;/p&gt;
  &lt;pre id=&quot;jzr7&quot; data-lang=&quot;python&quot;&gt;# Открываем файл для чтения
with open(&amp;#x27;index.txt&amp;#x27;, &amp;#x27;r&amp;#x27;) as file:
    # Читаем все строки из файла
    all_lines = file.readlines()

# Выбираем первые три строки
first_three_lines = all_lines[:3]

# Выводим прочитанные строки
for line in first_three_lines:
    print(line.replace(&amp;#x27;\n&amp;#x27;, &amp;#x27;&amp;#x27;)) #Удаляя \n&lt;/pre&gt;
  &lt;p id=&quot;3U13&quot;&gt;Вывод в консоль:&lt;/p&gt;
  &lt;figure id=&quot;cHTi&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/00/8a/008a3730-4f37-4402-9dd2-c82d03cd6e04.png&quot; width=&quot;32&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;kP1S&quot;&gt;А теперь давайте выведем последние 3 строки:&lt;/p&gt;
  &lt;p id=&quot;1HdL&quot;&gt;Пишем тот же код но меняем 1 участок:&lt;/p&gt;
  &lt;pre id=&quot;LL8e&quot; data-lang=&quot;python&quot;&gt;# Открываем файл для чтения
with open(&amp;#x27;index.txt&amp;#x27;, &amp;#x27;r&amp;#x27;) as file:
    # Читаем все строки из файла
    all_lines = file.readlines()

# Выбираем последние три строки
first_three_lines = all_lines[-3:]

# Выводим прочитанные строки
for line in first_three_lines:
    print(line.replace(&amp;#x27;\n&amp;#x27;, &amp;#x27;&amp;#x27;)) #Удаляя \n&lt;/pre&gt;
  &lt;p id=&quot;ZQvC&quot;&gt;Вывод в консоль:&lt;/p&gt;
  &lt;figure id=&quot;NucX&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b0/14/b0149d99-7fd6-431d-8b38-bb6c54283658.png&quot; width=&quot;22&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;6JLp&quot;&gt;Подробнее с работой с файлами .txt вы можете ознакомиться на сайте: &lt;a href=&quot;https://pythonworld.ru/tipy-dannyx-v-python/fajly-rabota-s-fajlami.html&quot; target=&quot;_blank&quot;&gt;*КЛИКАБЕЛЬНО*&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;nVIM&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;peuk&quot;&gt;В канале в комментариях напишите что вам было бы ещё интересно...&lt;/p&gt;
  &lt;p id=&quot;xD3e&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;XBgD&quot;&gt;Спасибо за внимание&lt;/h2&gt;
  &lt;p id=&quot;nXCL&quot;&gt;С вами был &lt;a href=&quot;https://t.me/Xacker_Name_new&quot; target=&quot;_blank&quot;&gt;@Xacker_Name_new&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;eyUE&quot;&gt;Поддержка: &lt;a href=&quot;https://t.me/Bsc_Black_Secret_Club_bot&quot; target=&quot;_blank&quot;&gt;@Bsc_Black_Secret_Club_bot&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;1piM&quot;&gt;Канал: &lt;a href=&quot;https://t.me/education_python_aiogram&quot; target=&quot;_blank&quot;&gt;@education_python_aiogram&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>xacker_name_new:1ehent_u3EK</id><link rel="alternate" type="text/html" href="https://teletype.in/@xacker_name_new/1ehent_u3EK?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=xacker_name_new"></link><title>Обучение #3</title><published>2023-09-26T12:21:19.073Z</published><updated>2023-09-29T11:59:34.466Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/50/e3/50e31141-824f-4f69-8473-ed3aa0599887.png"></media:thumbnail><category term="obuchenie-python-aiogram-my-sql" label="Обучение Python+aiogram+MySQL"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/3a/72/3a720c74-3487-46cc-ac94-4ec752d144cc.png&quot;&gt;Обучение #3</summary><content type="html">
  &lt;p id=&quot;zTlV&quot;&gt;Хай, я получил от людей проблему с установкой программы для базы данных, из 1 урока, так вот, если у вас после установки нет программы как на скриншоте:&lt;/p&gt;
  &lt;figure id=&quot;Gaj7&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/49/8a/498a686e-3e46-4222-b7f1-801116283edc.png&quot; width=&quot;290&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Mgqp&quot;&gt;Её можно скачать по ссылке - &lt;a href=&quot;https://dev.mysql.com/get/Downloads/MySQLGUITools/mysql-workbench-community-8.0.34-winx64.msi&quot; target=&quot;_blank&quot;&gt;*КЛИКАБЕЛЬНО*&lt;/a&gt;&lt;/p&gt;
  &lt;blockquote id=&quot;eKq3&quot;&gt;При установке, выбираем Modify&lt;/blockquote&gt;
  &lt;figure id=&quot;5NUk&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/5e/7a/5e7a05c8-3632-412e-bcde-072aa8d6e8b2.png&quot; width=&quot;401&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;9Hnd&quot;&gt;Далее нажимаем везде &amp;quot;Next&amp;quot;&lt;/p&gt;
  &lt;p id=&quot;cOih&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;X41L&quot;&gt;Вроде разобрались (если не помогло прошу написать мне в личные сообщения: &lt;a href=&quot;https://t.me/Xacker_Name_new&quot; target=&quot;_blank&quot;&gt;@Xacker_Name_new&lt;/a&gt;&lt;/p&gt;
  &lt;h3 id=&quot;7A0h&quot;&gt;&lt;strong&gt;&lt;s&gt;-------------------------------------------------------------------------&lt;/s&gt;&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;Mqb6&quot;&gt;Давайте начнём работать с базой данных, с помощью вспомогательного класса work_db из файла &lt;a href=&quot;/@xacker_name_new/SK-nC-byGW-#nPwS&quot;&gt;class_db.py&lt;/a&gt; мы будем записывать все анкеты в базу данных.&lt;/p&gt;
  &lt;p id=&quot;ToXf&quot;&gt;Возьмём код бота из &lt;a href=&quot;https://teletype.in/@xacker_name_new/SK-nC-byGW-&quot; target=&quot;_blank&quot;&gt;Урока #2&lt;/a&gt;&lt;/p&gt;
  &lt;pre id=&quot;Yt2G&quot; data-lang=&quot;python&quot;&gt;from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
from aiogram.types import ReplyKeyboardRemove
from class_db import work_db #Импорируем класс для работы с базой данных из файла class_db.py
import test as bb #Импортируем файл test.py в переменную bb (мне так удобнее работать с ним)
import config as c #Импортируем файл config.py в переменную с (опять же мне так удобнее)



#Создаём класс бота и дистпетчера
bot = Bot(token=c.token) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot)
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига


class anketa(StatesGroup):
	name = State()
	floor = State()
	age = State()




@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &amp;quot;text&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &amp;#x27;/start&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Привет, заполни анкету, или посмотри информацйию о мне&amp;#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &amp;#x27;Информация&amp;#x27;:
		await bot.send_message(message.chat.id, f&amp;#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&amp;#x27;)
	elif message.text == &amp;#x27;Заполнить анкету&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите своё имя:&amp;#x27;)
		await anketa.name.set()


@dp.message_handler(state=anketa.name)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем имя в кеш
	await state.update_data(name=name)
	#Далее просим ввести пол, с выбором пола из кнопок
	await bot.send_message(message.chat.id, &amp;#x27;Выберите свой пол:&amp;#x27;, reply_markup=bb.main_floor) #добавляем вывод кнопок с выбором пола
	await anketa.floor.set()


@dp.message_handler(state=anketa.floor)
async def anketa_name(message: types.Message, state: FSMContext):
	#Записываем пол в кеш
	await state.update_data(floor=floor)
	#Далее просим ввести свой возраст
	await bot.send_message(message.chat.id, &amp;#x27;Выберите свой пол:&amp;#x27;, reply_markup=ReplyKeyboardRemove()) #убираем текстовую клавиатуру
	await anketa.age.set()


@dp.message_handler(state=anketa.age)
async def anketa_name(message: types.Message, state: FSMContext):
	#Получим все данные записанные в кеш
	data = await state.get_data()
	#Сортируем их по переменным
	name = data[&amp;#x27;name&amp;#x27;] #В ковычках пишем name, потому что сами записывали в такую переменную, там может быть любая другая
	floor = data[&amp;#x27;floor&amp;#x27;] #В ковычках пишем floor, потому что сами записывали в такую переменную, там может быть любая другая
	age = message.text #записываем ввод пользователя в переменную age
	await state.finish() #Завершаем работу с машиной состояний
	#Выведем анкету пользователю
	await bot.send_message(message.chat.id, f&amp;#x27;Ваша анкета:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}\n\nСпасибо за уделение времени&amp;#x27;, reply_markup=bb.mark_menu) #Отправляем анкету, благодарим, и выдаём ему текстовоем меню
	#Отправим анкету администратору по его ID из config.py
	#Так же выведем ID пользователя и его юзернейм
	await bot.send_message(c.admin, f&amp;#x27;Пользователь: {message.chat.id}\n@{message.from_user.username} заполнил анкету\nЕго данные:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}&amp;#x27;)




if __name__ == &amp;quot;__main__&amp;quot;: #Если скрипт запущен с этого файла, запускаем executor
    executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен&lt;/pre&gt;
  &lt;p id=&quot;Xngr&quot;&gt;Для начала давайте создадим функцию которая будет создавать таблицы:&lt;/p&gt;
  &lt;pre id=&quot;JiLc&quot; data-lang=&quot;python&quot;&gt;def creat_table(): #Данную функцию будем запускать при каждом запуске кода, параметры функция не принимает
	#Для начала конектимся к базе данных:
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		creat_table_request = &amp;#x27;CREATE TABLE IF NOT EXISTS &amp;#x60;ankets&amp;#x60;(id int AUTO_INCREMENT, name varchar(32), floor varchar(10), age int, PRIMARY KEY (id));&amp;#x27; #И так мы написали запрос, но для чего он нам?
		#Он нам для того что-бы создать таблицу для анкет где будут следующие данные: id - это будет id анкеты (число), оно будет прописываться само (из-за AUTO_INCREMENT)
		#name типа сроки длинной не более 32 символов, floor типа строки не более 10 символов и age типа числа без ограничения
		#Первичный ключ (PRIMARY KEY) — особенное поле в таблице, которое позволяет однозначно идентифицировать каждую запись в ней
		#Запрос написан, давайте его выполним:
		status = db_work.create_table(connection, creat_table_request) #Предаём необходимые данные (Конект и сам запрос)
		#Проверяем статус создания базы данных:
		if status: #Если вернуло True значит всё хорошо (выведем в консоль что запрос выполнен)
			print(&amp;#x27;Таблица успешно создана&amp;#x27;)
			#Закрываем конект
			if db_work.connect_close(connection):
				print(&amp;#x27;Конект закрыт!&amp;#x27;)
			else: #Если нам вернуло False, значит произошла ошибка, в вспомогательном классе мы прописали вывод ошибки
				print(&amp;#x27;Ошибка указана выше&amp;#x27;)
		else: #Если вернуло False, значит не удалось создать таблицу, ошибку мы так же вывели в классе
			print(&amp;#x27;Ошибка указана выше&amp;#x27;)
	else: #Если мы не смогли подключиться к базе данных, то опять же ошибка была выведена в классе
		print(&amp;#x27;Ошибка указана выше&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;z3rn&quot;&gt;И так давайте допишем запуск этой функции:&lt;/p&gt;
  &lt;pre id=&quot;yL9T&quot; data-lang=&quot;python&quot;&gt;if __name__ == &amp;quot;__main__&amp;quot;: #Если скрипт запущен с этого файла, запускаем executor
	creat_table() #Запускаем функцию создания таблицы
	executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен&lt;/pre&gt;
  &lt;p id=&quot;WHQg&quot;&gt;Запускаем:&lt;/p&gt;
  &lt;p id=&quot;qG2Z&quot;&gt;У меня возникла ошибка с вспомогательным классом для работы с базой данных, текст ошибки:&lt;/p&gt;
  &lt;pre id=&quot;dLg7&quot;&gt;Traceback (most recent call last):
  File &amp;quot;C:\Users\ffff1\OneDrive\Рабочий стол\bot_ankets\main.py&amp;quot;, line 14, in &amp;lt;module&amp;gt;
    db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: work_db.__init__() takes 1 positional argument but 6 were given&lt;/pre&gt;
  &lt;p id=&quot;ulEG&quot;&gt;Это из-за того что я не написал в функции &amp;quot;__init__&amp;quot; принятие нескольких аргументов, а передаю аж 6, поэтому давайте перепишем функцию &amp;quot;__init__&amp;quot;:&lt;/p&gt;
  &lt;pre id=&quot;mRQG&quot; data-lang=&quot;python&quot;&gt;def __init__(self, host, port, user, password, database): #Функция для иницилизирования переменных в класс, запускать её не надо
		self.host = host
		self.port = port
		self.user = user
		self.password = password
		self.database = database&lt;/pre&gt;
  &lt;p id=&quot;y4Kc&quot;&gt;Запускаем:&lt;/p&gt;
  &lt;p id=&quot;aXZU&quot;&gt;...Пишет что базы нет, в таком случае в программе Workbench 8.0 CE заходим в базу которые создали в &lt;a href=&quot;https://teletype.in/@xacker_name_new/UqnaI47nEzx#ZIiJ&quot; target=&quot;_blank&quot;&gt;первом уроке&lt;/a&gt;&lt;/p&gt;
  &lt;figure id=&quot;3GYI&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/03/8b/038b54f7-0c18-4eb2-9b41-56d574922e03.png&quot; width=&quot;1086&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;BYpk&quot;&gt;В строке (указанной прямоугольником пишем следующие:&lt;/p&gt;
  &lt;p id=&quot;A1Xw&quot;&gt;&lt;code&gt;CREATE DATABASE usersdb;&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;WWQj&quot;&gt;Должно получиться так:&lt;/p&gt;
  &lt;figure id=&quot;WT7X&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/e4/bc/e4bc7f18-b5d5-4e02-a411-06f39cdad8a2.png&quot; width=&quot;1028&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;nuQc&quot;&gt;Далее нажимаем на молнию (указана стрелочкой)&lt;/p&gt;
  &lt;figure id=&quot;Jmfn&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/12/e6/12e68865-5e72-4f8b-af5e-32c08651c389.png&quot; width=&quot;1042.7767857142858&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;gOAb&quot;&gt;Красная стрелочка: нам пишет что база данных создана!&lt;br /&gt;Черная стрелочка: На том месте нажимаем правой кнопкой и Refresh (У нас появляется база данных)&lt;/p&gt;
  &lt;p id=&quot;yHmh&quot;&gt;Далее покажу как смотреть данные из неё...&lt;/p&gt;
  &lt;p id=&quot;1tH7&quot;&gt;Запускаем бота:&lt;/p&gt;
  &lt;figure id=&quot;mSJk&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/d5/7b/d57be762-b134-48a1-8b68-144b8818de77.png&quot; width=&quot;467&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;t8vi&quot;&gt;Таблица успешно создана, и конект успешно закрыт, я считаю это успех)&lt;/p&gt;
  &lt;p id=&quot;U5Ol&quot;&gt;Давайте напишем функцию которая будет записывать данные в таблицу:&lt;/p&gt;
  &lt;pre id=&quot;ZJKS&quot; data-lang=&quot;python&quot;&gt;def insert_table(name_, floor_, age_): #Данная функция принимает имя таблицы в которую надо записать данные (Сразу скажу т.к. мы записывать будет в ankets ропишем получение данных)
	#Для начала конектимся к базе данных:
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		insert_table_request = &amp;#x27;INSERT INTO ankets (name, floor, age) VALUES (%s, %s, %s);&amp;#x27; #И так в этом запросе мы создаём запись данных
		with connection.cursor() as cursor:
			cursor.execute(insert_table_request, (name_, floor_, age_)) #Записываем данные полученные в функцию
		connection.commit() #Сохраняем изменения
		print(&amp;#x27;Данные записаны!&amp;#x27;)
		if db_work.connect_close(connection):
			print(&amp;#x27;Конект закрыт!&amp;#x27;)
		else: #Если нам вернуло False, значит произошла ошибка, в вспомогательном классе мы прописали вывод ошибки
			print(&amp;#x27;Ошибка указана выше&amp;#x27;)
	else: #Если мы не смогли подключиться к базе данных, то опять же ошибка была выведена в классе
		print(&amp;#x27;Ошибка указана выше&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;shkb&quot;&gt;Функция записана, давайте её добавим вызов функции из обработчика возраста:&lt;/p&gt;
  &lt;pre id=&quot;EURO&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(state=anketa.age)
async def anketa_name(message: types.Message, state: FSMContext):
	#Получим все данные записанные в кеш
	data = await state.get_data()
	#Сортируем их по переменным
	name = data[&amp;#x27;name&amp;#x27;] #В ковычках пишем name, потому что сами записывали в такую переменную, там может быть любая другая
	floor = data[&amp;#x27;floor&amp;#x27;] #В ковычках пишем floor, потому что сами записывали в такую переменную, там может быть любая другая
	age = message.text #записываем ввод пользователя в переменную age
	await state.finish() #Завершаем работу с машиной состояний
	#Выведем анкету пользователю
	await bot.send_message(message.chat.id, f&amp;#x27;Ваша анкета:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}\n\nСпасибо за уделение времени&amp;#x27;, reply_markup=bb.mark_menu) #Отправляем анкету, благодарим, и выдаём ему текстовоем меню
	#Отправим анкету администратору по его ID из config.py
	#Так же выведем ID пользователя и его юзернейм
	await bot.send_message(c.admin, f&amp;#x27;Пользователь: {message.chat.id}\n@{message.from_user.username} заполнил анкету\nЕго данные:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}&amp;#x27;)
	insert_table(name, floor, age) #Передаём необходимые данные&lt;/pre&gt;
  &lt;p id=&quot;4l3i&quot;&gt;Перезапускаем бота, и заполняем анкету:&lt;/p&gt;
  &lt;p id=&quot;rGfk&quot;&gt;Выдало ошибку:&lt;/p&gt;
  &lt;pre id=&quot;YSRU&quot;&gt;FSMStorageWarning: You haven’t set any storage yet so no states and no data will be saved.
You can connect MemoryStorage for debug purposes or non-essential data.&lt;/pre&gt;
  &lt;p id=&quot;cUMn&quot;&gt;Нужно добавить ещё 1 импорт в файл &lt;a href=&quot;https://teletype.in/@xacker_name_new/SK-nC-byGW-#nPwS&quot; target=&quot;_blank&quot;&gt;main.py&lt;/a&gt;:&lt;/p&gt;
  &lt;pre id=&quot;Aufj&quot; data-lang=&quot;python&quot;&gt;from aiogram.contrib.fsm_storage.memory import MemoryStorage&lt;/pre&gt;
  &lt;p id=&quot;pMlj&quot;&gt;Так же поменяем класс бота и диспетчера:&lt;/p&gt;
  &lt;pre id=&quot;Mj7s&quot; data-lang=&quot;python&quot;&gt;bot = Bot(token=c.token, parse_mode=types.ParseMode.HTML)
dp = Dispatcher(bot, storage=MemoryStorage())&lt;/pre&gt;
  &lt;p id=&quot;ZMhx&quot;&gt;Ещё я допустил ошибку в 2х обработчиках:&lt;/p&gt;
  &lt;pre id=&quot;4hc7&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(state=anketa.name)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем имя в кеш
	await state.update_data(name=message.text)
	#Далее просим ввести пол, с выбором пола из кнопок
	await bot.send_message(message.chat.id, &amp;#x27;Выберите свой пол:&amp;#x27;, reply_markup=bb.main_floor) #добавляем вывод кнопок с выбором пола
	await anketa.floor.set()


@dp.message_handler(state=anketa.floor)
async def anketa_name(message: types.Message, state: FSMContext):
	#Записываем пол в кеш
	await state.update_data(floor=message.text)
	#Далее просим ввести свой возраст
	await bot.send_message(message.chat.id, &amp;#x27;Выберите свой пол:&amp;#x27;, reply_markup=ReplyKeyboardRemove()) #убираем текстовую клавиатуру
	await anketa.age.set()&lt;/pre&gt;
  &lt;p id=&quot;6t5u&quot;&gt;Не думайте что я не мастер своего дела, по мимо уроков я ещё и работаю, учусь, и иногда бывают такие ошибки...&lt;/p&gt;
  &lt;p id=&quot;2erX&quot;&gt;Давайте продолжим, запускаем бота и заполняем анкету:&lt;/p&gt;
  &lt;figure id=&quot;7Ekx&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/3d/a5/3da507c4-83e8-4c09-a586-da5d44634679.png&quot; width=&quot;701&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;FBZB&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/41/3b/413b8596-521f-4f8e-a5d5-8631881fb11f.png&quot; width=&quot;457&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;NKC3&quot;&gt;И так мы успешно записали данные, давайте посмотрим их&lt;/p&gt;
  &lt;p id=&quot;knlV&quot;&gt;Открываем программу (скрин)&lt;/p&gt;
  &lt;figure id=&quot;2Pt1&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/bd/7d/bd7df69c-1043-42b8-8d6d-d2d30c217bbe.png&quot; width=&quot;215&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;th3e&quot;&gt;Заходим двойным щелчком ЛКМ по базе &amp;quot;test_basa&amp;quot;&lt;/p&gt;
  &lt;p id=&quot;xkKC&quot;&gt;Раскрываем базу:&lt;/p&gt;
  &lt;figure id=&quot;Q2R8&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/df/b0/dfb08950-f611-46d1-8013-6b2900aa8d32.png&quot; width=&quot;1055.652818991098&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;APZ7&quot;&gt;Разворачиваем таблицы&lt;/p&gt;
  &lt;figure id=&quot;eV5L&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/c5/05/c505f468-447a-4933-9e91-1d34b759a069.png&quot; width=&quot;194&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;63JA&quot;&gt;При наведении на таблице ankets у нас появляются кнопочки, нам нужна эта:&lt;/p&gt;
  &lt;figure id=&quot;juzL&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6f/65/6f652464-05a1-4ac5-8b28-00cd17977768.png&quot; width=&quot;221&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;qAMJ&quot;&gt;Нажимаем и снизу у нас есть все данные записанные в таблицу:&lt;/p&gt;
  &lt;figure id=&quot;sjVR&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/3a/da/3ada070c-d92e-4db7-955c-3d1270e539a2.png&quot; width=&quot;1088.0623762376238&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;1S1n&quot;&gt;Молодцы, теперь давайте по команду в бота &amp;quot;/info_table&amp;quot;&lt;/p&gt;
  &lt;p id=&quot;1R6m&quot;&gt;Давайте перепишем функцию в вспомогательном классе:&lt;/p&gt;
  &lt;pre id=&quot;QKVk&quot; data-lang=&quot;python&quot;&gt;	def info_table(self, connection, info, values): #Функция для получения данных из таблицы, в info будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(info, values)
			return cursor.fetchall()[0] #Возвращаем всё что нашли
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False&lt;/pre&gt;
  &lt;p id=&quot;31Hk&quot;&gt;Выведем все данные по ID 1&lt;br /&gt;Напишем обработчик команды &amp;quot;/info_table&amp;quot;:&lt;/p&gt;
  &lt;pre id=&quot;qtTZ&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &amp;quot;text&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &amp;#x27;/start&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Привет, заполни анкету, или посмотри информацйию о мне&amp;#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &amp;#x27;Информация&amp;#x27;:
		await bot.send_message(message.chat.id, f&amp;#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&amp;#x27;)
	elif message.text == &amp;#x27;Заполнить анкету&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите своё имя:&amp;#x27;)
		await anketa.name.set()
	elif message.text == &amp;#x27;/info_table&amp;#x27;:
		info_request = &amp;#x27;SELECT * FROM ankets WHERE id = %s&amp;#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&amp;#x27;Полученные данные: {info}&amp;#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &amp;#x27;Не удалось получить данные&amp;#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &amp;#x27;Не удалось подключиться к базе данных&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;9FDS&quot;&gt;У нас получился такой код, перезапускаем бота, и проверяем работоспособность команды:&lt;/p&gt;
  &lt;figure id=&quot;huLJ&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f3/fd/f3fde4ef-58c0-4f57-8f29-46f0df60f97f.png&quot; width=&quot;695&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;BC9k&quot;&gt;Работает отлично, но выводит данные не особо красиво, давайте исправим:&lt;/p&gt;
  &lt;pre id=&quot;OuCG&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &amp;quot;text&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &amp;#x27;/start&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Привет, заполни анкету, или посмотри информацйию о мне&amp;#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &amp;#x27;Информация&amp;#x27;:
		await bot.send_message(message.chat.id, f&amp;#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&amp;#x27;)
	elif message.text == &amp;#x27;Заполнить анкету&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите своё имя:&amp;#x27;)
		await anketa.name.set()
	elif message.text == &amp;#x27;/info_table&amp;#x27;:
		info_request = &amp;#x27;SELECT * FROM ankets WHERE id = %s&amp;#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&amp;#x27;Полученные данные:\nID: {info[&amp;quot;id&amp;quot;]}\nИмя: {info[&amp;quot;name&amp;quot;]}\nПол: {info[&amp;quot;floor&amp;quot;]}\nВозраст: {info[&amp;quot;age&amp;quot;]}&amp;#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &amp;#x27;Не удалось получить данные&amp;#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &amp;#x27;Не удалось подключиться к базе данных&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;ee46&quot;&gt;Проверяем вывод, и наслаждаемся красотой:&lt;/p&gt;
  &lt;figure id=&quot;go19&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6c/a4/6ca45101-296d-4a2b-afe8-3e3379c2def9.png&quot; width=&quot;697&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;BZ8N&quot;&gt;Так то лучше не так ли?&lt;/p&gt;
  &lt;p id=&quot;mF5I&quot;&gt;Давайте обновим возраст с помощью инлайн кнопок?&lt;/p&gt;
  &lt;p id=&quot;OWs6&quot;&gt;Создаём обработчик команды &amp;quot;/new_value&amp;quot;&lt;/p&gt;
  &lt;p id=&quot;H4ND&quot;&gt;Но перед этим напишем класс для ввода ID записи в базе данных:&lt;/p&gt;
  &lt;pre id=&quot;Fbr4&quot; data-lang=&quot;python&quot;&gt;class new_values(StatesGroup):
	new_value = State()&lt;/pre&gt;
  &lt;p id=&quot;Sz1Q&quot;&gt;И так продолжим писать обработчик:&lt;/p&gt;
  &lt;pre id=&quot;Y9Q9&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &amp;quot;text&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &amp;#x27;/start&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Привет, заполни анкету, или посмотри информацйию о мне&amp;#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &amp;#x27;Информация&amp;#x27;:
		await bot.send_message(message.chat.id, f&amp;#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&amp;#x27;)
	elif message.text == &amp;#x27;Заполнить анкету&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите своё имя:&amp;#x27;)
		await anketa.name.set()
	elif message.text == &amp;#x27;/info_table&amp;#x27;:
		info_request = &amp;#x27;SELECT * FROM ankets WHERE id = %s&amp;#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&amp;#x27;Полученные данные:\nID: {info[&amp;quot;id&amp;quot;]}\nИмя: {info[&amp;quot;name&amp;quot;]}\nПол: {info[&amp;quot;floor&amp;quot;]}\nВозраст: {info[&amp;quot;age&amp;quot;]}&amp;#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &amp;#x27;Не удалось получить данные&amp;#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &amp;#x27;Не удалось подключиться к базе данных&amp;#x27;)
	elif message.text == &amp;#x27;/new_value&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите ID для изменения возраста:&amp;#x27;)
		await new_values.new_value.set()&lt;/pre&gt;
  &lt;p id=&quot;d0Tf&quot;&gt;Пишем обработчик ввода пользователя:&lt;/p&gt;
  &lt;pre id=&quot;nKEe&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(state=new_values.new_value)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем ID в кеш
	await state.update_data(id_value=message.text)
	#Выводим инлайн кнопки с числами
	#Пока напишу прямо тут, в следующих уроках будем создавать функции
	await bot.send_message(message.chat.id, &amp;#x27;Выберите новое значение:&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=3).add(
		InlineKeyboardButton(text=&amp;#x27;1&amp;#x27;, callback_data=&amp;#x27;new_value_1&amp;#x27;),InlineKeyboardButton(text=&amp;#x27;2&amp;#x27;, callback_data=&amp;#x27;new_value_2&amp;#x27;), InlineKeyboardButton(text=&amp;#x27;10&amp;#x27;, callback_data=&amp;#x27;new_value_10&amp;#x27;),
		InlineKeyboardButton(text=&amp;#x27;25&amp;#x27;, callback_data=&amp;#x27;new_value_25&amp;#x27;)))
	#Этого достаточно&lt;/pre&gt;
  &lt;p id=&quot;E54J&quot;&gt;Давайте допишем ипорт:&lt;/p&gt;
  &lt;pre id=&quot;EOcf&quot; data-lang=&quot;python&quot;&gt;from aiogram.types import ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton&lt;/pre&gt;
  &lt;p id=&quot;3PJD&quot;&gt;Давайте ещё перепишем функцию в вспомогательном классе:&lt;/p&gt;
  &lt;pre id=&quot;2zGO&quot; data-lang=&quot;python&quot;&gt;	def edit_table(self, connection, edit, values): #Функция для редактирования данных в таблице, в edit будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(edit, values)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False&lt;/pre&gt;
  &lt;p id=&quot;a4Yl&quot;&gt;Теперь перейдём к обработчику нажатий на инлайн кнопки:&lt;/p&gt;
  &lt;pre id=&quot;rLKi&quot; data-lang=&quot;python&quot;&gt;@dp.callback_query_handler(lambda call: True, state=&amp;#x27;*&amp;#x27;) #Обрабатываем нажатия всех инлайн кнопок, даже когда активно ожидание ввода от пользователя
async def callback_inline(call, state: FSMContext): #В переменную call принимаем данные о нажатой кнопке
	try: #Обрабатываем ошибки, если всё успешно то мы получим переменную id_value на всю функцию
		data = await state.get_data()
		id_value = data[&amp;#x27;id_value&amp;#x27;]
		await state.finish()
	except Exception as eror: #Если будут ошибки мы их пришлём пользователю
		await bot.send_message(call.message.chat.id, f&amp;#x27;Произошла ошибка: {eror}&amp;#x27;)
		return #Останавливаем выполнение функции
	#Приступим к обработке нажатия кнопок, т.к. у нас записано новое чило в callback_data, но начало одно и тоже
	#Нам нужно проверять есть ли в нажатой кнопке начало:
	if &amp;#x27;new_value_&amp;#x27; in call.data: #В call.data содержиться callback_data
		new_value = int(call.data.replace(&amp;#x27;new_value_&amp;#x27;, &amp;#x27;&amp;#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
		#Грубыми словами с помощью replace мы заменяем new_value_ на ничего
		#Теперь давайте заменим значение в таблице по ID которое вписали изначально
		#Конектимся к базе данных:
		connection = db_work.connect_db()
		if connection: #Если конект успешен
			#Возпользуемся функцией edit_table из вспомогательного класса:
			new_value_request = &amp;#x27;UPDATE ankets SET age = %s WHERE id = %s&amp;#x27;
			values = (new_value, int(id_value))
			status = db_work.edit_table(connection, new_value_request, values)
			if status: #Если успешно обновили данные
				await bot.send_message(call.message.chat.id, f&amp;#x27;Данные для строки с ID: {id_value}\nУспешно обновлены на: {new_value}&amp;#x27;)
			else: #Если произошла ошибка
				await bot.send_message(call.message.chat.id, &amp;#x27;Произошла ошибка, она отобразилась в консоли!&amp;#x27;)
		else: #Если не удалось подключиться к базе данных
			await bot.send_message(call.message.chat.id, &amp;#x27;Не удалось подключиться к базе данных!&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;1X40&quot;&gt;Запустим бота и проверим работоспособность:&lt;/p&gt;
  &lt;figure id=&quot;K49R&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ea/dc/eadcd1da-3510-4f64-b57b-1fd8e4eb0d2a.png&quot; width=&quot;702&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;3Sni&quot;&gt;Всё работает, кайф, давайте проверим данные через программу &lt;/p&gt;
  &lt;figure id=&quot;DZyg&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/07/8b/078b2c8d-f946-4101-8e7b-8e295e9a1741.png&quot; width=&quot;215&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;wwp3&quot;&gt;Для обновления, нажимаем на кнопку:&lt;/p&gt;
  &lt;figure id=&quot;51EK&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ef/42/ef424232-8a6b-4c72-99fa-299ab4eb1dd0.png&quot; width=&quot;1065.580198019802&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;c8Wj&quot;&gt;И так, данные успешно обновлены:&lt;/p&gt;
  &lt;figure id=&quot;PVtU&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f2/de/f2dea586-d57c-469a-a8e1-8b4be2684357.png&quot; width=&quot;1081&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;QBLF&quot;&gt;На этом я предлагаю закончить наш урок)&lt;/p&gt;
  &lt;p id=&quot;5LHC&quot;&gt;Итоговый код который у нас полчиться:&lt;/p&gt;
  &lt;pre id=&quot;9H7V&quot; data-lang=&quot;python&quot;&gt;from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
from aiogram.types import ReplyKeyboardRemove, InlineKeyboardMarkup, InlineKeyboardButton
from class_db import work_db #Импорируем класс для работы с базой данных из файла class_db.py
import test as bb #Импортируем файл test.py в переменную bb (мне так удобнее работать с ним)
import config as c #Импортируем файл config.py в переменную с (опять же мне так удобнее)



#Создаём класс бота и дистпетчера
bot = Bot(token=c.token, parse_mode=types.ParseMode.HTML) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot, storage=MemoryStorage())
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига


class anketa(StatesGroup):
	name = State()
	floor = State()
	age = State()


class new_values(StatesGroup):
	new_value = State()


def creat_table(): #Данную функцию будем запускать при каждом запуске кода, параметры функция не принимает
	#Для начала конектимся к базе данных:
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		creat_table_request = &amp;#x27;CREATE TABLE IF NOT EXISTS &amp;#x60;ankets&amp;#x60;(id int AUTO_INCREMENT, name varchar(32), floor varchar(10), age int, PRIMARY KEY (id));&amp;#x27; #И так мы написали запрос, но для чего он нам?
		#Он нам для того что-бы создать таблицу для анкет где будут следующие данные: id - это будет id анкеты (число), оно будет прописываться само (из-за AUTO_INCREMENT)
		#name типа сроки длинной не более 32 символов, floor типа строки не более 10 символов и age типа числа без ограничения
		#Первичный ключ (PRIMARY KEY) — особенное поле в таблице, которое позволяет однозначно идентифицировать каждую запись в ней
		#Запрос написан, давайте его выполним:
		status = db_work.create_table(connection, creat_table_request) #Предаём необходимые данные (Конект и сам запрос)
		#Проверяем статус создания базы данных:
		if status: #Если вернуло True значит всё хорошо (выведем в консоль что запрос выполнен)
			print(&amp;#x27;Таблица успешно создана&amp;#x27;)
			#Закрываем конект
			if db_work.connect_close(connection):
				print(&amp;#x27;Конект закрыт!&amp;#x27;)
			else: #Если нам вернуло False, значит произошла ошибка, в вспомогательном классе мы прописали вывод ошибки
				print(&amp;#x27;Ошибка указана выше&amp;#x27;)
		else: #Если вернуло False, значит не удалось создать таблицу, ошибку мы так же вывели в классе
			print(&amp;#x27;Ошибка указана выше&amp;#x27;)
	else: #Если мы не смогли подключиться к базе данных, то опять же ошибка была выведена в классе
		print(&amp;#x27;Ошибка указана выше&amp;#x27;)


def insert_table(name_, floor_, age_): #Данная функция принимает имя таблицы в которую надо записать данные (Сразу скажу т.к. мы записывать будет в ankets ропишем получение данных)
	#Для начала конектимся к базе данных:
	connection = db_work.connect_db()
	if connection: #Если класс вернул конект, а не False
		#Напишем сам запрос
		insert_table_request = &amp;#x27;INSERT INTO ankets (name, floor, age) VALUES (%s, %s, %s);&amp;#x27; #И так в этом запросе мы создаём запись данных
		with connection.cursor() as cursor:
			cursor.execute(insert_table_request, (name_, floor_, age_)) #Записываем данные полученные в функцию
		connection.commit() #Сохраняем изменения
		print(&amp;#x27;Данные записаны!&amp;#x27;)
		if db_work.connect_close(connection):
			print(&amp;#x27;Конект закрыт!&amp;#x27;)
		else: #Если нам вернуло False, значит произошла ошибка, в вспомогательном классе мы прописали вывод ошибки
			print(&amp;#x27;Ошибка указана выше&amp;#x27;)
	else: #Если мы не смогли подключиться к базе данных, то опять же ошибка была выведена в классе
		print(&amp;#x27;Ошибка указана выше&amp;#x27;)


@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &amp;quot;text&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &amp;#x27;/start&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Привет, заполни анкету, или посмотри информацйию о мне&amp;#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &amp;#x27;Информация&amp;#x27;:
		await bot.send_message(message.chat.id, f&amp;#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&amp;#x27;)
	elif message.text == &amp;#x27;Заполнить анкету&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите своё имя:&amp;#x27;)
		await anketa.name.set()
	elif message.text == &amp;#x27;/info_table&amp;#x27;:
		info_request = &amp;#x27;SELECT * FROM ankets WHERE id = %s&amp;#x27;
		values = (1,)
		connection = db_work.connect_db() #Конектимся к базе данных
		if connection: #Если конект успешный
			info = db_work.info_table(connection, info_request, values)
			if info: #Если получили данные по id = 1
				await bot.send_message(message.chat.id, f&amp;#x27;Полученные данные:\nID: {info[&amp;quot;id&amp;quot;]}\nИмя: {info[&amp;quot;name&amp;quot;]}\nПол: {info[&amp;quot;floor&amp;quot;]}\nВозраст: {info[&amp;quot;age&amp;quot;]}&amp;#x27;)
			else: #Если не смогли получить данные
				await bot.send_message(message.chat.id, &amp;#x27;Не удалось получить данные&amp;#x27;)
		else: #Если конект не удался
			await bot.send_message(message.chat.id, &amp;#x27;Не удалось подключиться к базе данных&amp;#x27;)
	elif message.text == &amp;#x27;/new_value&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите ID для изменения возраста:&amp;#x27;)
		await new_values.new_value.set()


@dp.message_handler(state=new_values.new_value)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем ID в кеш
	await state.update_data(id_value=message.text)
	#Выводим инлайн кнопки с числами
	#Пока напишу прямо тут, в следующих уроках будем создавать функции
	await bot.send_message(message.chat.id, &amp;#x27;Выберите новое значение:&amp;#x27;, reply_markup=InlineKeyboardMarkup(row_width=3).add(
		InlineKeyboardButton(text=&amp;#x27;1&amp;#x27;, callback_data=&amp;#x27;new_value_1&amp;#x27;),InlineKeyboardButton(text=&amp;#x27;2&amp;#x27;, callback_data=&amp;#x27;new_value_2&amp;#x27;), InlineKeyboardButton(text=&amp;#x27;10&amp;#x27;, callback_data=&amp;#x27;new_value_10&amp;#x27;),
		InlineKeyboardButton(text=&amp;#x27;25&amp;#x27;, callback_data=&amp;#x27;new_value_25&amp;#x27;)))
	#Этого достаточно



@dp.message_handler(state=anketa.name)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем имя в кеш
	await state.update_data(name=message.text)
	#Далее просим ввести пол, с выбором пола из кнопок
	await bot.send_message(message.chat.id, &amp;#x27;Выберите свой пол:&amp;#x27;, reply_markup=bb.menu_floor) #добавляем вывод кнопок с выбором пола
	await anketa.floor.set()


@dp.message_handler(state=anketa.floor)
async def anketa_name(message: types.Message, state: FSMContext):
	#Записываем пол в кеш
	await state.update_data(floor=message.text)
	#Далее просим ввести свой возраст
	await bot.send_message(message.chat.id, &amp;#x27;Введите свой возраст:&amp;#x27;, reply_markup=ReplyKeyboardRemove()) #убираем текстовую клавиатуру
	await anketa.age.set()


@dp.message_handler(state=anketa.age)
async def anketa_name(message: types.Message, state: FSMContext):
	#Получим все данные записанные в кеш
	data = await state.get_data()
	#Сортируем их по переменным
	name = data[&amp;#x27;name&amp;#x27;] #В ковычках пишем name, потому что сами записывали в такую переменную, там может быть любая другая
	floor = data[&amp;#x27;floor&amp;#x27;] #В ковычках пишем floor, потому что сами записывали в такую переменную, там может быть любая другая
	age = message.text #записываем ввод пользователя в переменную age
	await state.finish() #Завершаем работу с машиной состояний
	#Выведем анкету пользователю
	await bot.send_message(message.chat.id, f&amp;#x27;Ваша анкета:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}\n\nСпасибо за уделение времени&amp;#x27;, reply_markup=bb.mark_menu) #Отправляем анкету, благодарим, и выдаём ему текстовоем меню
	#Отправим анкету администратору по его ID из config.py
	#Так же выведем ID пользователя и его юзернейм
	await bot.send_message(c.admin, f&amp;#x27;Пользователь: {message.chat.id}\n@{message.from_user.username} заполнил анкету\nЕго данные:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}&amp;#x27;)
	insert_table(name, floor, age) #Передаём необходимые данные



@dp.callback_query_handler(lambda call: True, state=&amp;#x27;*&amp;#x27;) #Обрабатываем нажатия всех инлайн кнопок, даже когда активно ожидание ввода от пользователя
async def callback_inline(call, state: FSMContext): #В переменную call принимаем данные о нажатой кнопке
	try: #Обрабатываем ошибки, если всё успешно то мы получим переменную id_value на всю функцию
		data = await state.get_data()
		id_value = data[&amp;#x27;id_value&amp;#x27;]
		await state.finish()
	except Exception as eror: #Если будут ошибки мы их пришлём пользователю
		await bot.send_message(call.message.chat.id, f&amp;#x27;Произошла ошибка: {eror}&amp;#x27;)
		return #Останавливаем выполнение функции
	#Приступим к обработке нажатия кнопок, т.к. у нас записано новое чило в callback_data, но начало одно и тоже
	#Нам нужно проверять есть ли в нажатой кнопке начало:
	if &amp;#x27;new_value_&amp;#x27; in call.data: #В call.data содержиться callback_data
		new_value = int(call.data.replace(&amp;#x27;new_value_&amp;#x27;, &amp;#x27;&amp;#x27;)) #С момощью этого кода мы получим число типа int, удалив из call.data не нужное нам
		#Грубыми словами с помощью replace мы заменяем new_value_ на ничего
		#Теперь давайте заменим значение в таблице по ID которое вписали изначально
		#Конектимся к базе данных:
		connection = db_work.connect_db()
		if connection: #Если конект успешен
			#Возпользуемся функцией edit_table из вспомогательного класса:
			new_value_request = &amp;#x27;UPDATE ankets SET age = %s WHERE id = %s&amp;#x27;
			values = (new_value, int(id_value))
			status = db_work.edit_table(connection, new_value_request, values)
			if status: #Если успешно обновили данные
				await bot.send_message(call.message.chat.id, f&amp;#x27;Данные для строки с ID: {id_value}\nУспешно обновлены на: {new_value}&amp;#x27;)
			else: #Если произошла ошибка
				await bot.send_message(call.message.chat.id, &amp;#x27;Произошла ошибка, она отобразилась в консоли!&amp;#x27;)
		else: #Если не удалось подключиться к базе данных
			await bot.send_message(call.message.chat.id, &amp;#x27;Не удалось подключиться к базе данных!&amp;#x27;)


if __name__ == &amp;quot;__main__&amp;quot;: #Если скрипт запущен с этого файла, запускаем executor
	creat_table() #Запускаем функцию создания таблицы
	executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен&lt;/pre&gt;
  &lt;p id=&quot;P2QT&quot;&gt;Я помню что не научил удалять данные с базы данных, но давайте будем честны, вы уже устали делать всё что выше, в следующем задании начнём с удаления данных!&lt;/p&gt;
  &lt;p id=&quot;Q8Eo&quot; data-align=&quot;center&quot;&gt;Домашнее задание:&lt;br /&gt;1. Добавить больше кнопок для изменения возраста&lt;br /&gt;2. Создать функцию &amp;quot;creat_table_2&amp;quot; и создать в ней таблицу &amp;quot;users&amp;quot; в которую добавить столбцы: &lt;br /&gt;1. id - как в функции &amp;quot;creat_table&amp;quot;&lt;br /&gt;2. name - типа varchar длинной не более 32 символов&lt;br /&gt;3. password - типа varchar длинной не более 20 символов&lt;br /&gt;4. Возраст - типа int&lt;br /&gt;Записывать в таблицу ничего не надо, просто создать её при запуске бота, как мы это сделали с &amp;quot;creat_table&amp;quot;&lt;br /&gt;&lt;br /&gt;В обратной связи жду:&lt;br /&gt;1. Скриншот кода с больший кол-вом кнопок&lt;br /&gt;2. Скриншот кода функции &amp;quot;creat_table_2&amp;quot;&lt;br /&gt;3. Скриншот с программы где видна новая таблица &amp;quot;users&amp;quot; и все столбца в ней&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Выполнить ДЗ до 28.09.2023&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;EeFE&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;V6ma&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;3VEi&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;XBgD&quot;&gt;Спасибо за внимание&lt;/h2&gt;
  &lt;p id=&quot;nXCL&quot;&gt;С вами был &lt;a href=&quot;https://t.me/Xacker_Name_new&quot; target=&quot;_blank&quot;&gt;@Xacker_Name_new&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;eyUE&quot;&gt;Поддержка: &lt;a href=&quot;https://t.me/Bsc_Black_Secret_Club_bot&quot; target=&quot;_blank&quot;&gt;@Bsc_Black_Secret_Club_bot&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>xacker_name_new:SK-nC-byGW-</id><link rel="alternate" type="text/html" href="https://teletype.in/@xacker_name_new/SK-nC-byGW-?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=xacker_name_new"></link><title>Обучение #2</title><published>2023-09-25T03:22:49.150Z</published><updated>2023-09-29T11:59:25.906Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/50/e3/50e31141-824f-4f69-8473-ed3aa0599887.png"></media:thumbnail><category term="obuchenie-python-aiogram-my-sql" label="Обучение Python+aiogram+MySQL"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/3a/72/3a720c74-3487-46cc-ac94-4ec752d144cc.png&quot;&gt;Обучение #2</summary><content type="html">
  &lt;section style=&quot;background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;h3 id=&quot;OSVb&quot;&gt;Язык программирования - Далее ЯП&lt;/h3&gt;
    &lt;h3 id=&quot;ZWeD&quot;&gt;Операционная система - Далее ОС&lt;/h3&gt;
    &lt;h3 id=&quot;nmNE&quot;&gt;Редактор кода - Далее IDE&lt;/h3&gt;
    &lt;h3 id=&quot;FbKl&quot;&gt;CMD - Далее консоль&lt;/h3&gt;
  &lt;/section&gt;
  &lt;h3 id=&quot;OmB3&quot;&gt;Первый урок - &lt;a href=&quot;https://teletype.in/@xacker_name_new/UqnaI47nEzx&quot; target=&quot;_blank&quot;&gt;*Кликабельно*&lt;/a&gt;&lt;/h3&gt;
  &lt;h2 id=&quot;ldF8&quot;&gt;В этом уроке мы научимся:&lt;/h2&gt;
  &lt;p id=&quot;WhUl&quot;&gt;&lt;a href=&quot;#YxLb&quot;&gt;Начало&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;FOfV&quot;&gt;Работой с базой данных&lt;/p&gt;
  &lt;ol id=&quot;KQH9&quot;&gt;
    &lt;li id=&quot;rxbk&quot;&gt;Научимся записывать данные в базу&lt;/li&gt;
    &lt;li id=&quot;DjNQ&quot;&gt;Научимся читать данные из базы&lt;/li&gt;
    &lt;li id=&quot;ihIt&quot;&gt;Научимся удалять данные с базы&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;Smrh&quot;&gt;Напишем telegram бота с логикой анкетирования&lt;/p&gt;
  &lt;ol id=&quot;VITV&quot;&gt;
    &lt;li id=&quot;8DDD&quot;&gt;Сможем получить имя&lt;/li&gt;
    &lt;li id=&quot;6FiA&quot;&gt;Сможем получить пол&lt;/li&gt;
    &lt;li id=&quot;3Tq0&quot;&gt;Сможем получить возраст&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;jStA&quot;&gt;Работой с кнопками&lt;/p&gt;
  &lt;ol id=&quot;ieoi&quot;&gt;
    &lt;li id=&quot;ksCt&quot;&gt;Сделаем 2 кнопки (Заполнить анкету\Информация)&lt;/li&gt;
    &lt;li id=&quot;5AcW&quot;&gt;Сделаем текстовое меню&lt;/li&gt;
    &lt;li id=&quot;j2zg&quot;&gt;Сделаем выбор пола через текстовое меню&lt;/li&gt;
  &lt;/ol&gt;
  &lt;h2 id=&quot;YxLb&quot; data-align=&quot;center&quot;&gt;Начало&lt;/h2&gt;
  &lt;p id=&quot;nPwS&quot;&gt;Для начала давайте создадим новый проект, создаём папку &amp;quot;bot_ankets&amp;quot;&lt;br /&gt;В папке создадим 4 файла:&lt;br /&gt;    1. main.py - в него будем писать основной код бота&lt;br /&gt;    2. config.py - в него запишем токен бота, id админа, данные для подключения к базе данных&lt;br /&gt;    3. class_db.py - в него напишем вспомогательный класс для работы с базой данных&lt;br /&gt;    4. test.py - в нём я записываю все клавиатуры, если такое название вам не нравиться, вы можете назвать файл &amp;quot;keyboards.py&amp;quot;, от названия ничего не зависит&lt;/p&gt;
  &lt;p id=&quot;4lQR&quot;&gt;Давайте заполним файл &lt;a href=&quot;#nPwS&quot;&gt;config.py&lt;/a&gt;:&lt;/p&gt;
  &lt;pre id=&quot;uYXs&quot; data-lang=&quot;python&quot;&gt;token = &amp;#x27;Токен телеграм бота&amp;#x27;
admin = 132 #ID админа (позже научу его получать)
host = &amp;#x27;localhost&amp;#x27; #IP для подключения к базе данных (Ничего не менять, это локальный хостинг)
port = 8080 #Порт для подключения к базе данных (Ничего не меняем, мы его меняли при создании из первого урока)
user = &amp;#x27;root&amp;#x27; #Пользователь для подключения к базе данных (Стандартный - root)
password = &amp;#x27;Password&amp;#x27; #Пароль для подключения к базе данных (Замените на свой который вписывали на первом уроке)
database = &amp;#x27;test_basa&amp;#x27; #Имя базы данных которую мы создали в первом уроке&lt;/pre&gt;
  &lt;p id=&quot;Ajus&quot;&gt;И так мы заполнили конфиг, нажимаем сочетание клавиш ctrl+s для сохранения изменений&lt;/p&gt;
  &lt;p id=&quot;OhId&quot;&gt;Далее давайте напишем вспомогательный класс для работы с базой данных в файл &lt;a href=&quot;#nPwS&quot;&gt;class_db.py&lt;/a&gt;:&lt;/p&gt;
  &lt;pre id=&quot;LuFO&quot; data-lang=&quot;python&quot;&gt;import pymysql #Импортируем модуль pymysql который установили в первом уроке
from config import host, port, user, password, database #Импортируем из файла config.py данные для подключения к базе данных

class work_db:
	def __init__(self): #Функция для иницилизирования переменных в класс, запускать её не надо
		self.host = host
		self.port = port
		self.user = user
		self.password = password
		self.database = database

	def connect_db(self): #Функция для конекта к базе данных
		try:
			connection = pymysql.connect(
				host = self.host,
				port = self.port,
				user = self.user,
				password = self.password,
				database = self.database,
				cursorclass = pymysql.cursors.DictCursor
			)
			return connection #Если конект прошёл успешно, возвращаем переменную connection, для дальнейшей работы
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def connect_close(self, connection): #Передаём переменную connection если в коде подключились, после каждого подключения к базе данных и выполнения какого-либо когда, нужно закрывать подключение
		try:
			connection.close() #Закрываем подключение к базе данных
			return True #Если успешно закрыли подключение к базе, возвращаем True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def create_table(self, connection, creat): #Функция для создания таблице в базе данных, в creat будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(creat)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def edit_table(self, connection, edit): #Функция для редактирования данных в таблице, в edit будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(edit)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def info_table(self, connection, info): #Функция для получения данных из таблицы, в info будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(info)
			return cursor.fetchall()[0] #Возвращаем всё что нашли
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False

	def delete_from_table(self, connection, delete_): #Функция для редактирования данных в таблице, в delete_ будем передавать текст запроса
		try:
			with connection.cursor() as cursor:
				cursor.execute(delete_)
			connection.commit()
			return True
		except Exception as eror:
			print(eror) #Если произошла ошибка, выводим её в консоль
			return False #Если произошла ошибка, возвращаем False&lt;/pre&gt;
  &lt;p id=&quot;uVTZ&quot;&gt;И так класс для работы с базой данных написан, опять же сохраняем данные (нажимаем сочетание клавиш ctrl+s)&lt;/p&gt;
  &lt;p id=&quot;ZHGH&quot;&gt;Давайте заполним файл &lt;a href=&quot;#nPwS&quot;&gt;test.py&lt;/a&gt; записав в него клавиатуру:&lt;/p&gt;
  &lt;pre id=&quot;F0SL&quot; data-lang=&quot;python&quot;&gt;from aiogram.types import KeyboardButton, ReplyKeyboardMarkup #Импортируем классы для работы с текстовым меню\текстовыми кнопками

mainy = [[&amp;#x27;Заполнить анкету&amp;#x27;], [&amp;#x27;Информация&amp;#x27;]] #Создайм список кнопок для текстового меню в данном примере кнопки расположены в 2 строки
#Можно использовать такой список: [[&amp;#x27;Заполнить анкету&amp;#x27;, &amp;#x27;Информация&amp;#x27;]] Кнопки будут расположены в 1 строку

mark_menu = ReplyKeyboardMarkup(mainy, resize_keyboard=True) #Создаём клавиатуру, передав список представленный выше
#resize_keyboard=True нужен для того что-бы кнопки были маленькие, вы можете его на вписывать и посмотреть как это будет выглядеть&lt;/pre&gt;
  &lt;p id=&quot;yQjT&quot;&gt;И так клавиатура создана, приступим к основному коду telegram бота, писать будем в файле &lt;a href=&quot;#nPwS&quot;&gt;main.py&lt;/a&gt;:&lt;/p&gt;
  &lt;p id=&quot;oE0Y&quot;&gt;Запишем нужные нам импорты:&lt;/p&gt;
  &lt;pre id=&quot;WT7Y&quot; data-lang=&quot;python&quot;&gt;from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
from aiogram.types import ReplyKeyboardRemove
from class_db import work_db #Импорируем класс для работы с базой данных из файла class_db.py
import test as bb #Импортируем файл test.py в переменную bb (мне так удобнее работать с ним)
import config as c #Импортируем файл config.py в переменную с (опять же мне так удобнее)&lt;/pre&gt;
  &lt;p id=&quot;CrWf&quot;&gt;Создадим нужные нам экземпляры классов для работы:&lt;/p&gt;
  &lt;pre id=&quot;TQN9&quot; data-lang=&quot;python&quot;&gt;bot = Bot(token=c.token) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot)
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига&lt;/pre&gt;
  &lt;p id=&quot;L2bb&quot;&gt;Пишем обработчик текстовых сообщений:&lt;/p&gt;
  &lt;pre id=&quot;8bJm&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &amp;quot;text&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	pass&lt;/pre&gt;
  &lt;p id=&quot;PKTS&quot;&gt;Давайте напишем логику обработки сообщений, начнём с кнопки &amp;quot;информация&amp;quot; и команду /start:&lt;/p&gt;
  &lt;pre id=&quot;NyNi&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &amp;quot;text&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &amp;#x27;/start&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Привет, заполни анкету, или посмотри информацйию о мне&amp;#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &amp;#x27;Информация&amp;#x27;:
		await bot.send_message(message.chat.id, f&amp;#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;0ejW&quot;&gt;А теперь давайте напишем логику самого анкетирования&lt;/p&gt;
  &lt;p id=&quot;gZBA&quot;&gt;Перед началом объясню как работает if, elif, else&lt;/p&gt;
  &lt;blockquote id=&quot;OjgK&quot;&gt;Допустим нам нужно проверить какое число пришло в функцию&lt;br /&gt;И в зависимости от числа вернуть какой то текст&lt;/blockquote&gt;
  &lt;p id=&quot;A5if&quot;&gt;Для этого мы пишем саму функцию и запуск её с каким либо числом:&lt;/p&gt;
  &lt;pre id=&quot;m0GJ&quot; data-lang=&quot;python&quot;&gt;def info_number(number): #Данная функция принимает число в переменную number
    if number == 1: #Если полученное число равно одному, то возращаем слово Один
       return &amp;#x27;Один&amp;#x27;
    elif number == 2: #Если же число равно двум, то возращаем слово Два
       return &amp;#x27;Два&amp;#x27;
    else: #В ином случае говорим что такие числа мы не принимаем
       return &amp;#x27;Я не принимаю такие числа&amp;#x27;&lt;/pre&gt;
  &lt;p id=&quot;NMrf&quot;&gt;Ещё нам понадобиться такая вещь как машина состояний, мы её уже импортировали в &lt;a href=&quot;#oE0Y&quot;&gt;начале&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;88c7&quot;&gt;Давайте расскажу для чего нам машина состояний...&lt;/p&gt;
  &lt;p id=&quot;CwA3&quot;&gt;Она нам нужна для того что-бы работать с определённым пользователем, и определённой логикой&lt;br /&gt;Это всё что нам требуется на этом этапе да и в принципе в программировании&lt;/p&gt;
  &lt;p id=&quot;zy8O&quot;&gt;Продолжим писать логику&lt;br /&gt;Создаём класс для работы с машиной состояний:&lt;/p&gt;
  &lt;pre id=&quot;vjPE&quot; data-lang=&quot;python&quot;&gt;class anketa(StatesGroup):
	name = State()
	floor = State()
	age = State()&lt;/pre&gt;
  &lt;p id=&quot;xMTm&quot;&gt;Далее дописываем ожидание именно имени, у нас получился код:&lt;/p&gt;
  &lt;pre id=&quot;5OYI&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &amp;quot;text&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &amp;#x27;/start&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Привет, заполни анкету, или посмотри информацйию о мне&amp;#x27;, reply_markup=bb.mark_menu) #Обрабатываем текст /start и выводим клавиатуру из файлы test.py
	elif message.text == &amp;#x27;Информация&amp;#x27;:
		await bot.send_message(message.chat.id, f&amp;#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&amp;#x27;)
	elif message.text == &amp;#x27;Заполнить анкету&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите своё имя:&amp;#x27;)
		await anketa.name.set()&lt;/pre&gt;
  &lt;p id=&quot;CW5s&quot;&gt;В файле &lt;a href=&quot;#nPwS&quot;&gt;test.py&lt;/a&gt; добавляем клавиатуру с выбором пола:&lt;/p&gt;
  &lt;pre id=&quot;cboo&quot; data-lang=&quot;python&quot;&gt;main_floor = [[&amp;#x27;Мужской&amp;#x27;, &amp;#x27;Женский&amp;#x27;]]
menu_floor = ReplyKeyboardMarkup(main_floor, resize_keyboard=True)&lt;/pre&gt;
  &lt;p id=&quot;jKhu&quot;&gt;Далее нам нужен сам обработчик ввода пользователя:&lt;/p&gt;
  &lt;pre id=&quot;fWqg&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(state=anketa.name)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем имя в кеш
	await state.update_data(name=name)
	#Далее просим ввести пол, с выбором пола из кнопок
	await bot.send_message(message.chat.id, &amp;#x27;Выберите свой пол:&amp;#x27;, reply_markup=bb.main_floor) #добавляем вывод кнопок с выбором пола&lt;/pre&gt;
  &lt;p id=&quot;bD4F&quot;&gt;Пишем обработчик ввода пола:&lt;/p&gt;
  &lt;pre id=&quot;QFPv&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(state=anketa.floor)
async def anketa_name(message: types.Message, state: FSMContext):
	#Записываем пол в кеш
	await state.update_data(floor=floor)
	#Далее просим ввести свой возраст
	await bot.send_message(message.chat.id, &amp;#x27;Выберите свой пол:&amp;#x27;, reply_markup=ReplyKeyboardRemove()) #убираем текстовую клавиатуру
	await anketa.age.set()&lt;/pre&gt;
  &lt;p id=&quot;vFiD&quot;&gt;И наконец давайте обработаем возраст, и выведем данные которые ввёл пользователь, сначала пользователю, а затем админу по его ID из &lt;a href=&quot;#nPwS&quot;&gt;config.py&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;Uhmg&quot;&gt;У нас получился такой код:&lt;/p&gt;
  &lt;pre id=&quot;UkNq&quot; data-lang=&quot;python&quot;&gt;@dp.message_handler(state=anketa.age)
async def anketa_name(message: types.Message, state: FSMContext):
	#Получим все данные записанные в кеш
	data = await state.get_data()
	#Сортируем их по переменным
	name = data[&amp;#x27;name&amp;#x27;] #В ковычках пишем name, потому что сами записывали в такую переменную, там может быть любая другая
	floor = data[&amp;#x27;floor&amp;#x27;] #В ковычках пишем floor, потому что сами записывали в такую переменную, там может быть любая другая
	age = message.text #записываем ввод пользователя в переменную age
	await state.finish() #Завершаем работу с машиной состояний
	#Выведем анкету пользователю
	await bot.send_message(message.chat.id, f&amp;#x27;Ваша анкета:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}\n\nСпасибо за уделение времени&amp;#x27;, reply_markup=bb.mark_menu) #Отправляем анкету, благодарим, и выдаём ему текстовоем меню
	#Отправим анкету администратору по его ID из config.py
	#Так же выведем ID пользователя и его юзернейм
	await bot.send_message(c.admin, f&amp;#x27;Пользователь: {message.chat.id}\n@{message.from_user.username} заполнил анкету\nЕго данные:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}&amp;#x27;)


if __name__ == &amp;quot;__main__&amp;quot;: #Если скрипт запущен с этого файла, запускаем executor
    executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен&lt;/pre&gt;
  &lt;p id=&quot;0B6c&quot;&gt;Возможно у вас возникнет вопрос зачем я использую &amp;quot;\n&amp;quot; это для того что-бы перенести текст на 1 или более строк.&lt;/p&gt;
  &lt;p id=&quot;GdpB&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;37Je&quot;&gt;В итоге у нас получился такой код:&lt;/p&gt;
  &lt;pre id=&quot;tSsc&quot; data-lang=&quot;python&quot;&gt;from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher import FSMContext
from aiogram.types import ReplyKeyboardRemove
from class_db import work_db #Импорируем класс для работы с базой данных из файла class_db.py
import test as bb #Импортируем файл test.py в переменную bb (мне так удобнее работать с ним)
import config as c #Импортируем файл config.py в переменную с (опять же мне так удобнее)



#Создаём класс бота и дистпетчера
bot = Bot(token=c.token) #Берём токен бота из файла config.py который импортировали ранее в переменную c
dp = Dispatcher(bot)
db_work = work_db(c.host, c.port, c.user, c.password, c.database) #Создаём экземпляр класса для работы с базой данных, передав все нужные параметры из конфига


class anketa(StatesGroup):
	name = State()
	floor = State()
	age = State()

	
@dp.message_handler(content_types=[&amp;#x27;text&amp;#x27;]) #Обрабатываем каждое сообщение от пользователей, добавляем content_types для обработки текста, в будущих уроках будет фото и видео
async def text(message: types.Message): #Асинхронная функция с название &amp;quot;text&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
	if message.text == &amp;#x27;/start&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Привет, заполни анкету, или посмотри информацйию о мне&amp;#x27;, reply_markup=bb.mark_menu) #Обрабатываем команду /start и выводим клавиатуру из файлы test.py
	elif message.text == &amp;#x27;Информация&amp;#x27;:
		await bot.send_message(message.chat.id, f&amp;#x27;Сюда пишем какую либо информацию, например я хочу вывести ID пользователя\nТвой ID: {message.chat.id}&amp;#x27;)
	elif message.text == &amp;#x27;Заполнить анкету&amp;#x27;:
		await bot.send_message(message.chat.id, &amp;#x27;Введите своё имя:&amp;#x27;)
		await anketa.name.set()


@dp.message_handler(state=anketa.name)
async def anketa_name(message: types.Message, state: FSMContext): #Как видите у нас добавился FSMContext, он нам нужен как раз для обработки машины состояния
	#Записываем имя в кеш
	await state.update_data(name=message.text)
	#Далее просим ввести пол, с выбором пола из кнопок
	await bot.send_message(message.chat.id, &amp;#x27;Выберите свой пол:&amp;#x27;, reply_markup=bb.main_floor) #добавляем вывод кнопок с выбором пола
	await anketa.floor.set()


@dp.message_handler(state=anketa.floor)
async def anketa_name(message: types.Message, state: FSMContext):
	#Записываем пол в кеш
	await state.update_data(floor=message.text)
	#Далее просим ввести свой возраст
	await bot.send_message(message.chat.id, &amp;#x27;Выберите свой пол:&amp;#x27;, reply_markup=ReplyKeyboardRemove()) #убираем текстовую клавиатуру
	await anketa.age.set()


@dp.message_handler(state=anketa.age)
async def anketa_name(message: types.Message, state: FSMContext):
	#Получим все данные записанные в кеш
	data = await state.get_data()
	#Сортируем их по переменным
	name = data[&amp;#x27;name&amp;#x27;] #В ковычках пишем name, потому что сами записывали в такую переменную, там может быть любая другая
	floor = data[&amp;#x27;floor&amp;#x27;] #В ковычках пишем floor, потому что сами записывали в такую переменную, там может быть любая другая
	age = message.text #записываем ввод пользователя в переменную age
	await state.finish() #Завершаем работу с машиной состояний
	#Выведем анкету пользователю
	await bot.send_message(message.chat.id, f&amp;#x27;Ваша анкета:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}\n\nСпасибо за уделение времени&amp;#x27;, reply_markup=bb.mark_menu) #Отправляем анкету, благодарим, и выдаём ему текстовоем меню
	#Отправим анкету администратору по его ID из config.py
	#Так же выведем ID пользователя и его юзернейм
	await bot.send_message(c.admin, f&amp;#x27;Пользователь: {message.chat.id}\n@{message.from_user.username} заполнил анкету\nЕго данные:\n\nИмя: {name}\nПол: {floor}\nВозраст: {age}&amp;#x27;)


if __name__ == &amp;quot;__main__&amp;quot;: #Если скрипт запущен с этого файла, запускаем executor
    executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен&lt;/pre&gt;
  &lt;p id=&quot;u3sS&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;YJ8x&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;snBw&quot;&gt;Работу с базой данных я перенёс на третий урок, потому что информация для некоторых новая, и её достаточно много для новичка, поэтому ожидайте третий урок&lt;/p&gt;
  &lt;p id=&quot;uG3C&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;LcHW&quot;&gt;В третьей  части мы научимся работать с:&lt;/h2&gt;
  &lt;ol id=&quot;8Ab2&quot;&gt;
    &lt;li id=&quot;oaDy&quot;&gt;Работой с базой данных&lt;/li&gt;
    &lt;ol id=&quot;X4j3&quot;&gt;
      &lt;li id=&quot;rxbk&quot;&gt;Научимся записывать данные в базу&lt;/li&gt;
      &lt;li id=&quot;DjNQ&quot;&gt;Научимся читать данные из базы&lt;/li&gt;
      &lt;li id=&quot;ihIt&quot;&gt;Научимся удалять данные с базы&lt;/li&gt;
    &lt;/ol&gt;
    &lt;li id=&quot;fPFB&quot;&gt;Работой с кнопками&lt;/li&gt;
    &lt;ol id=&quot;Bayu&quot;&gt;
      &lt;li id=&quot;t0pN&quot;&gt;Сделаем инлайн кнопки (Расскажу и покажу что это и с чем это едят)&lt;/li&gt;
      &lt;li id=&quot;tDgE&quot;&gt;Сделаем обработку таких кнопок, сделаем им не сложную логику&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;hWSC&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;Jsdi&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;5zkc&quot;&gt;Так же советую посмотреть мою статью по форматированию сообщений - &lt;a href=&quot;https://teletype.in/@xacker_name_new/HKkIZf4oyEC&quot; target=&quot;_blank&quot;&gt;*КЛИКАБЕЛЬНО*&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;scgu&quot;&gt;Но для них нам придётся переписать строку &lt;/p&gt;
  &lt;pre id=&quot;y5fm&quot; data-lang=&quot;python&quot;&gt;bot = Bot(token=c.token)&lt;/pre&gt;
  &lt;p id=&quot;2K8U&quot;&gt;На:&lt;/p&gt;
  &lt;pre id=&quot;STSe&quot; data-lang=&quot;python&quot;&gt;bot = Bot(token=c.token, parse_mode=types.ParseMode.HTML)&lt;/pre&gt;
  &lt;p id=&quot;SKwW&quot;&gt;Как видим у нас добавился parse_mode, это как раз для обработки HTML тегов в сообщениях...&lt;/p&gt;
  &lt;p id=&quot;wypF&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;GP4e&quot; data-align=&quot;center&quot;&gt;Домашнее задание:&lt;/h3&gt;
  &lt;p id=&quot;lko4&quot; data-align=&quot;center&quot;&gt;1. Выдели сообщения (запрос имени, пола, возраста) в жирный шрифт &lt;br /&gt;(по желанию можешь добавить наклонный текст)&lt;br /&gt;2. Так же выдели в итоговой анкете, ID пользователя (само число)&lt;br /&gt;в Текст для лёгкого копирования (Моноширинный)&lt;br /&gt;(и у пользователя и у админа)&lt;br /&gt;&lt;br /&gt;В обратной связи жду:&lt;br /&gt;1. Скриншот кода где видно, как реализовано выделение текста&lt;br /&gt;2. Скриншот с telegram бота, где видно заполнение анкеты + выделения текстов&lt;br /&gt;3. Скриншот с telegram бота где видна конечная анкета (у пользователя и админа)&lt;br /&gt;Прислать можно: &lt;a href=&quot;https://t.me/Xacker_Name_new&quot; target=&quot;_blank&quot;&gt;@Xacker_Name_new&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
  &lt;p id=&quot;BNWj&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;sbmR&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;XBgD&quot;&gt;Спасибо за внимание&lt;/h2&gt;
  &lt;p id=&quot;nXCL&quot;&gt;С вами был &lt;a href=&quot;https://t.me/Xacker_Name_new&quot; target=&quot;_blank&quot;&gt;@Xacker_Name_new&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;FthM&quot;&gt;Поддержка: &lt;a href=&quot;https://t.me/Bsc_Black_Secret_Club_bot&quot; target=&quot;_blank&quot;&gt;@Bsc_Black_Secret_Club_bot&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>xacker_name_new:UqnaI47nEzx</id><link rel="alternate" type="text/html" href="https://teletype.in/@xacker_name_new/UqnaI47nEzx?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=xacker_name_new"></link><title>Обучение #1</title><published>2023-09-24T08:53:12.113Z</published><updated>2023-09-29T11:59:06.650Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/50/e3/50e31141-824f-4f69-8473-ed3aa0599887.png"></media:thumbnail><category term="obuchenie-python-aiogram-my-sql" label="Обучение Python+aiogram+MySQL"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/3a/72/3a720c74-3487-46cc-ac94-4ec752d144cc.png&quot;&gt;Обучение #1</summary><content type="html">
  &lt;section style=&quot;background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;h3 id=&quot;OSVb&quot;&gt;Язык программирования - Далее ЯП&lt;/h3&gt;
    &lt;h3 id=&quot;ZWeD&quot;&gt;Операционная система - Далее ОС&lt;/h3&gt;
    &lt;h3 id=&quot;nmNE&quot;&gt;Редактор кода - Далее IDE&lt;/h3&gt;
    &lt;h3 id=&quot;FbKl&quot;&gt;CMD - Далее консоль&lt;/h3&gt;
  &lt;/section&gt;
  &lt;p id=&quot;tiJq&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;E81j&quot;&gt;Использовать будет такую ЯП как Python (советую версию 3.10) — &lt;a href=&quot;https://www.python.org/downloads/release/python-3100/#:~:text=Full%20Changelog-,Files,-Version&quot; target=&quot;_blank&quot;&gt;*КЛИКАБЕЛЬНО*&lt;/a&gt;: Выбирайте свою ОС&lt;/p&gt;
  &lt;p id=&quot;vSMh&quot;&gt;После того как скачали установочный файл, при установке нужно поставить галочку со словом PATH:&lt;/p&gt;
  &lt;figure id=&quot;GNvS&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/99/c5/99c57e37-5008-409f-8ca7-0446a38c3a95.png&quot; width=&quot;556&quot; /&gt;
  &lt;/figure&gt;
  &lt;section style=&quot;background-color:hsl(hsl(323, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;UJYK&quot;&gt;Нажимаем Install Now&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;ucOt&quot;&gt;Открываем консоль комбинация клавиш на клавиатуре: Win+R&lt;/p&gt;
  &lt;p id=&quot;eN7a&quot;&gt;В открывшемся окне пишем &amp;quot;cmd&amp;quot;&lt;/p&gt;
  &lt;p id=&quot;rTNz&quot;&gt;Вводим команды по порядку:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(236, 74%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;ul id=&quot;FW5X&quot;&gt;
      &lt;li id=&quot;NBB9&quot; data-align=&quot;center&quot;&gt;&lt;code&gt;pip install aiogram==2.25.1&lt;/code&gt;&lt;/li&gt;
      &lt;li id=&quot;Txhb&quot; data-align=&quot;center&quot;&gt;&lt;code&gt;pip install asyncio&lt;/code&gt;&lt;/li&gt;
      &lt;li id=&quot;bzFr&quot; data-align=&quot;center&quot;&gt;&lt;code&gt;pip install pymysql&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/section&gt;
  &lt;p id=&quot;zn2u&quot; data-align=&quot;center&quot;&gt;Немножко расскажу про модули которые мы установили:&lt;/p&gt;
  &lt;p id=&quot;J4al&quot; data-align=&quot;center&quot;&gt;&lt;code&gt;aiogram - Он нам нужен для работы с api telegram ботов&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;EDn3&quot; data-align=&quot;center&quot;&gt;&lt;code&gt;asyncio - Он нам нужен для ожидания (подобие модуля time, только time останавливает выполнение остального кода, а asyncio нет)&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;q4dm&quot; data-align=&quot;center&quot;&gt;&lt;code&gt;pymysql - Он нам нужен для работы с базой данных которую мы создадим далее&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;IfG4&quot;&gt;Скачиваем IDE которым пользуюсь я - &lt;a href=&quot;https://www.sublimetext.com/3#:~:text=over%20this%20version.-,Version%253A%20Build%203211,-OS%20X%20(10.7&quot; target=&quot;_blank&quot;&gt;*КЛИКАБЕЛЬНО*&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;ZSL9&quot;&gt;Скачиваем MySQLServer - &lt;a href=&quot;https://dev.mysql.com/downloads/installer/#:~:text=MySQL%20Installer%208.0.34&quot; target=&quot;_blank&quot;&gt;*КЛИКАБЕЛЬНО*&lt;/a&gt;&lt;/p&gt;
  &lt;blockquote id=&quot;Ncrd&quot;&gt;&lt;strong&gt;При установке нажимаем везде далее&lt;/strong&gt;&lt;/blockquote&gt;
  &lt;blockquote id=&quot;Bujx&quot;&gt;Добавлено: Если у вас не появилась программа показанная ниже, установить ей: &lt;a href=&quot;https://dev.mysql.com/get/Downloads/MySQLGUITools/mysql-workbench-community-8.0.34-winx64.msi&quot; target=&quot;_blank&quot;&gt;*КЛИКАБЕЛЬНО*&lt;/a&gt;&lt;/blockquote&gt;
  &lt;section style=&quot;background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;p id=&quot;j9st&quot;&gt;После установки у нас должна быть такая программа:&lt;/p&gt;
    &lt;figure id=&quot;1NTa&quot; class=&quot;m_custom&quot;&gt;
      &lt;img src=&quot;https://img4.teletype.in/files/fc/e0/fce0ad2e-6bfb-43d7-97a0-014452dee9bf.png&quot; width=&quot;201&quot; /&gt;
    &lt;/figure&gt;
    &lt;p id=&quot;JxiY&quot;&gt;После запуска, должно быть что то такое:&lt;/p&gt;
    &lt;figure id=&quot;A4KJ&quot; class=&quot;m_custom&quot;&gt;
      &lt;img src=&quot;https://img4.teletype.in/files/ff/0a/ff0ae251-846f-4d62-9f21-7191b2685a2d.png&quot; width=&quot;875.6824925816023&quot; /&gt;
    &lt;/figure&gt;
    &lt;h3 id=&quot;HAf5&quot;&gt;Нажимаем на плюсик (указан стрелочкой)&lt;/h3&gt;
    &lt;figure id=&quot;qYFV&quot; class=&quot;m_custom&quot;&gt;
      &lt;img src=&quot;https://img2.teletype.in/files/d0/b9/d0b9d3cd-5588-4809-a7aa-c87a8c8b5c2a.png&quot; width=&quot;672&quot; /&gt;
    &lt;/figure&gt;
    &lt;p id=&quot;pdal&quot;&gt;Connection Name - Имя базы данных, по которому будем в будущем подключаться к базе данных &lt;em&gt;(Напишу test_basa)&lt;/em&gt;&lt;/p&gt;
    &lt;p id=&quot;JYo2&quot;&gt;Connection Method - Метод подключения (Не трогаем)&lt;/p&gt;
    &lt;p id=&quot;iTMP&quot;&gt;Hostname - Имя хоста для подключения (Не трогаем потому что нам нужна база данных на локальном хосте) 127.0.0.1 - это и есть локальный хост&lt;/p&gt;
    &lt;p id=&quot;iDmI&quot;&gt;Port - Порт для подключения к базе данных (Меняем на 8080)&lt;/p&gt;
    &lt;p id=&quot;viCa&quot;&gt;Username - Имя пользователя по которому будем подключаться к базе данных&lt;/p&gt;
    &lt;p id=&quot;TGBV&quot;&gt;Password - Пароль для подключения, если вы его не знаете сначала нажимаете на кнопку &amp;quot;Clear&amp;quot; -&amp;gt; &amp;quot;Store in Vault&amp;quot;&lt;/p&gt;
    &lt;figure id=&quot;dhZ9&quot; class=&quot;m_custom&quot;&gt;
      &lt;img src=&quot;https://img3.teletype.in/files/27/60/27607c7b-b7c6-4892-a577-107208ba79b4.png&quot; width=&quot;334&quot; /&gt;
    &lt;/figure&gt;
    &lt;p id=&quot;yMCF&quot;&gt;Вводим пароль в этом поле и нажимаем &amp;quot;OK&amp;quot;&lt;/p&gt;
    &lt;p id=&quot;wEsl&quot;&gt;После ввода пароля нажимаем на &amp;quot;Test Connection&amp;quot;&lt;/p&gt;
    &lt;p id=&quot;ImTj&quot;&gt;Должно появиться такое окошко:&lt;/p&gt;
    &lt;figure id=&quot;6uMA&quot; class=&quot;m_custom&quot;&gt;
      &lt;img src=&quot;https://img4.teletype.in/files/ff/31/ff311a0d-9ac8-4957-85d7-5e99477c7167.png&quot; width=&quot;299&quot; /&gt;
    &lt;/figure&gt;
    &lt;p id=&quot;n4RS&quot;&gt;Если вы не поменяли порт на 8080 то будет такое окошко:&lt;/p&gt;
    &lt;figure id=&quot;zJ8g&quot; class=&quot;m_original&quot;&gt;
      &lt;img src=&quot;https://img1.teletype.in/files/ca/25/ca25ddf5-c975-46f0-b671-a0ab6c02270f.png&quot; width=&quot;350&quot; /&gt;
    &lt;/figure&gt;
    &lt;blockquote id=&quot;rUJq&quot;&gt;Если же поменяв порт на 8080, у вас осталось такое окно, то поменяйте на порт 3306, и попробуйте снова&lt;/blockquote&gt;
    &lt;p id=&quot;lTZO&quot;&gt;и так мы настроили базу, осталось её создать (Нажимаем на OK)&lt;/p&gt;
    &lt;p id=&quot;FIBZ&quot;&gt;У нас появилась база данных:&lt;/p&gt;
    &lt;figure id=&quot;G3Iq&quot; class=&quot;m_original&quot;&gt;
      &lt;img src=&quot;https://img2.teletype.in/files/1f/f6/1ff6461f-2ba9-493c-9eaf-056dd15431f4.png&quot; width=&quot;254&quot; /&gt;
    &lt;/figure&gt;
    &lt;p id=&quot;zg3m&quot;&gt;В будущем через код мы сможем к ней подключиться...&lt;/p&gt;
  &lt;/section&gt;
  &lt;p id=&quot;5Z6a&quot;&gt;Давайте мы с вами посмотрим несколько уроков по aiogram:&lt;/p&gt;
  &lt;ol id=&quot;zrpn&quot;&gt;
    &lt;li id=&quot;nGJ8&quot;&gt;&lt;a href=&quot;https://youtu.be/ayUBlf9pvn0?list=PLe-iIMbo5JOJm6DRTjhleHojroS-Bbocr&quot; target=&quot;_blank&quot;&gt;Создание бота через BotFather&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;KhyL&quot;&gt;&lt;a href=&quot;https://youtu.be/WFIuSzaowlg?t=126&quot; target=&quot;_blank&quot;&gt;Пишем код простого Эхо бота&lt;/a&gt; (Эхо бот - бот которому ты пишешь сообщение, он тебе отправляет твой текст)&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;e3uy&quot;&gt;После просмотра 2 ролика у нас получился код:&lt;/p&gt;
  &lt;pre id=&quot;c00J&quot; data-lang=&quot;python&quot;&gt;from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor

bot = Bot(token=&amp;#x27;Токен вашего бота&amp;#x27;)
dp = Dispatcher(bot)

@dp.message_handler()
async def echo(message: types.Message):
    await message.answer(message.text)


executor.start_polling(dp, skip_updates=True)&lt;/pre&gt;
  &lt;p id=&quot;pf0m&quot;&gt;Давайте я подправлю код и напишу комментарии к некоторым участкам кода:&lt;/p&gt;
  &lt;pre id=&quot;VXO3&quot; data-lang=&quot;python&quot;&gt;from aiogram import Bot, types, Dispatcher
from aiogram.utils import executor


bot = Bot(token=&amp;#x27;Токен вашего бота&amp;#x27;)
dp = Dispatcher(bot)


@dp.message_handler() #Обрабатываем каждое сообщение от пользователей 
async def echo(message: types.Message): #Асинхронная функция с название &amp;quot;echo&amp;quot; которая принимает в переменную message, текст пользователя отправевшего сообщение
    await message.answer(message.text) #Отправляет сообщение пользователя обратно ему
    #Так же можно использовать: await bot.send_message(message.chat.id, messgae.text)
    #Отправляет сообщение пользователя обрано, но с помощью этой конструкции мы можем отправлять сообщение любому пользователю по его id


if __name__ == &amp;quot;__main__&amp;quot;: #Если скрипт запущен с этого файла, запускаем executor
    executor.start_polling(dp, skip_updates=True) #skip_updates=True - нужен для того чтобы не обрабатывать сообщения которые были присланы пользователем в тот момент когда бот был выключен&lt;/pre&gt;
  &lt;p id=&quot;B3AO&quot;&gt;И так у нас получился переработанный код&lt;/p&gt;
  &lt;p id=&quot;umQJ&quot;&gt;Для запуска подобных скриптов, нам нужна будет консоль (WIN+R -&amp;gt; cmd)&lt;/p&gt;
  &lt;p id=&quot;eaou&quot;&gt;В консоль пишем команду: &lt;/p&gt;
  &lt;pre id=&quot;7K8i&quot;&gt;cd C:\путь\до\папки\с\ботом\&lt;/pre&gt;
  &lt;blockquote id=&quot;22Mq&quot;&gt;Скопировать его можно тут:&lt;/blockquote&gt;
  &lt;figure id=&quot;6ba9&quot; class=&quot;m_custom&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/1f/79/1f797fd9-c330-49bc-9867-c09d58912a4e.png&quot; width=&quot;675&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;iaO9&quot;&gt;Далее мы перешли в директорию с ботом&lt;/p&gt;
  &lt;p id=&quot;Pois&quot;&gt;Пишем в консоль: &lt;/p&gt;
  &lt;pre id=&quot;aumO&quot;&gt;python main.py&lt;/pre&gt;
  &lt;p id=&quot;VOxh&quot;&gt;После чего ждём запуска, после запуска мы видим в консоли текст: &lt;/p&gt;
  &lt;pre id=&quot;kudE&quot;&gt;Updates were skipped successfully.&lt;/pre&gt;
  &lt;p id=&quot;X2Pk&quot;&gt;Это означает что бот успешно запущен!&lt;/p&gt;
  &lt;p id=&quot;ozyX&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;FFuP&quot;&gt;Во второй части мы научимся работать с:&lt;/h2&gt;
  &lt;ol id=&quot;P44s&quot;&gt;
    &lt;li id=&quot;Wm2T&quot;&gt;Работой с базой данных&lt;/li&gt;
    &lt;ol id=&quot;KQH9&quot;&gt;
      &lt;li id=&quot;rxbk&quot;&gt;Научимся записывать данные в базу&lt;/li&gt;
      &lt;li id=&quot;DjNQ&quot;&gt;Научимся читать данные из базы&lt;/li&gt;
      &lt;li id=&quot;ihIt&quot;&gt;Научимся удалять данные с базы&lt;/li&gt;
    &lt;/ol&gt;
    &lt;li id=&quot;Bi8C&quot;&gt;Напишем telegram бота с логикой анкетирования&lt;/li&gt;
    &lt;ol id=&quot;VITV&quot;&gt;
      &lt;li id=&quot;8DDD&quot;&gt;Сможем получить имя&lt;/li&gt;
      &lt;li id=&quot;6FiA&quot;&gt;Сможем получить пол&lt;/li&gt;
      &lt;li id=&quot;3Tq0&quot;&gt;Сможем получить возраст&lt;/li&gt;
    &lt;/ol&gt;
    &lt;li id=&quot;rM3w&quot;&gt;Работой с кнопками&lt;/li&gt;
    &lt;ol id=&quot;ieoi&quot;&gt;
      &lt;li id=&quot;ksCt&quot;&gt;Сделаем 2 кнопки (Заполнить анкету\Информация)&lt;/li&gt;
      &lt;li id=&quot;5AcW&quot;&gt;Сделаем текстовое меню&lt;/li&gt;
      &lt;li id=&quot;j2zg&quot;&gt;Сделаем выбор пола через текстовое меню&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;ita4&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;JiPj&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;BRe3&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;XBgD&quot;&gt;Спасибо за внимание&lt;/h2&gt;
  &lt;p id=&quot;nXCL&quot;&gt;С вами был &lt;a href=&quot;https://t.me/Xacker_Name_new&quot; target=&quot;_blank&quot;&gt;@Xacker_Name_new&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;FthM&quot;&gt;Поддержка: &lt;a href=&quot;https://t.me/Bsc_Black_Secret_Club_bot&quot; target=&quot;_blank&quot;&gt;@Bsc_Black_Secret_Club_bot&lt;/a&gt;&lt;/p&gt;

</content></entry></feed>