Oleg Polikhronidi
Умник
Привет, меня тут вдруг внезапно разблокировали на форуме (очень неожиданно для меня, я думал пиро никогда не разблокирует меня). Первым делом я хочу поделиться скриптом бота для знакомств, возможно кому-то поможет и кто-то в дальнейшем будет его развивать. Этого кода нет на других форумах и прочего, это не паблик скрипт, а по большей части самописный скрипт 1х1 с ботом знакомств (я боюсь оставлять ссылку на бота, вдруг меня забанят опять на пару лет).
Используемые библиотеки: aiogram. Я крайне не рекомендую писать ботов на pyTelegramBotApi.
Для начала отправимся к отцу Telegram-ботов Bot Father: t.me/BotFather.
На момент публикации этой темы, токен не будет работать, а сам бот будет удалён.
Можете не пытаться подключиться к нему.
После того как мы получили API Token для бота, делаем следующее:
Если у Вас нет Python, устанавливаем его. Не могу оставить ссылки на установщик, поскольку могу быть забанен.
Ограничиваю себя в использовании ссылок в этой теме, по-скольку уже был забанен за такое. Ищите сами как установить Python.
Например, на все мои боты я использую ОС Ubuntu 20.04. Если используете тоже, пишем в консоль следующее:
Мы установили Python на ОС Ubuntu 20.04, отлично! Двигаемся дальше.
Модули и библиотеку aiogram устанавливаем следующим сообщением в консоль:
Сервер готов. Возвращаемся к коду.
Мы используем локальную базу данных. Для начала, подключаем модули.
После того как указали модули, нам необходимо настроить бота.
Там, где указано
Отлично, мы настроили базовую конфигурацию бота. Переходим далее.
Я не буду объяснять каждый фрагмент кода, а сразу кину сюда всю остальную часть.
Всё что я посчитал нужным к объяснению - объяснил прямо в коде. Что не понятно - спрашивайте в теме.
Заготовленные ответы для пользователей и клавиатура.
Подключаем классы состояний для навигации.
Весь код ниже - процесс регистрации профиля. Занесение его в базу данных.
В случае если анкета есть - показываем анкету. В случае если анкеты нет - предлагаем создать.
Здесь мы преобразовываем значение словаря в (d). В основном так же взаимодействуем с анкетами.
Код для пересоздания анкеты. Тут мы её пересоздаем.
Почему мы используем skip_updates=True в конце? Что это значит?
Параметр
Далее создаём базу данных. Я не мастер объяснять SQL-запросы, к сожалению.
Код ниже - запросы к базе, они и не нуждаются в представлениях и описаниях. Используем sqlite3.
Ура! Бот готов. Что у нас получилось? Смотрим скриншоты.
Бот работает. Все данные о пользователях хранятся в database.bd
Фотографии пользователей хранятся в папке photos.
Для тех, кто хочет сразу же скачать бота и запустить, архив прикреплён. Качайте и пользуйтесь.
Пароль от прикреплённого архива: pawno-info.ru
Используемые библиотеки: aiogram. Я крайне не рекомендую писать ботов на pyTelegramBotApi.
Для начала отправимся к отцу Telegram-ботов Bot Father: t.me/BotFather.
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
На момент публикации этой темы, токен не будет работать, а сам бот будет удалён.
Можете не пытаться подключиться к нему.
После того как мы получили API Token для бота, делаем следующее:
- Жмём Win + R
- В поле ввода пишем cmd (или cmd.exe)
- Откроется командная строка, туда пишем:
pip install aiogramЕсли у Вас нет Python, устанавливаем его. Не могу оставить ссылки на установщик, поскольку могу быть забанен.
Ограничиваю себя в использовании ссылок в этой теме, по-скольку уже был забанен за такое. Ищите сами как установить Python.
Например, на все мои боты я использую ОС Ubuntu 20.04. Если используете тоже, пишем в консоль следующее:
Код:
sudo apt-get update
sudo apt-get upgrade -y
sudo apt install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get install screen -y
sudo apt-get install python3.9 -y
sudo apt-get install python3-pip -y
sudo apt-get install python3.9-dev -y
sudo apt-get install python3.9-distutils -y
python3.9 -m pip install pip --upgrade
Модули и библиотеку aiogram устанавливаем следующим сообщением в консоль:
Код:
python3.9 -m pip install aiogram
Мы используем локальную базу данных. Для начала, подключаем модули.
Python:
import random
import logging
from db import BotDB
from aiogram.dispatcher import FSMContext
from aiogram import Bot, Dispatcher, executor, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher.filters.state import State, StatesGroup
Python:
bot = Bot(token="token_bot")
dp = Dispatcher(bot, storage=MemoryStorage())
logging.basicConfig(level=logging.INFO)
BotDB = BotDB('database.db')
token_bot вставляем значение от BotFather.
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
Отлично, мы настроили базовую конфигурацию бота. Переходим далее.
Я не буду объяснять каждый фрагмент кода, а сразу кину сюда всю остальную часть.
Всё что я посчитал нужным к объяснению - объяснил прямо в коде. Что не понятно - спрашивайте в теме.
Заготовленные ответы для пользователей и клавиатура.
Python:
main_text = '1. Смотреть анкеты\n2. Моя анкета\n3. Удалить анкету'
profile_text = '1. Заполнить анкету заново\n2. Изменить текст анкеты\n3. Изменить фото\n4. Вернутся назад'
def show_profile(name, age, city, text):
return f'{name}\n{age}\n{city}\n{text}'
def get_random_anketa(list_of_anketi):
anketa = list_of_anketi[random.randint(0, len(list_of_anketi) - 1)]
a = anketa
return [show_profile(a[2], a[3], a[4], a[5]), BotDB.get_photo_id(a[1])]
Python:
class Wait(StatesGroup):
choosing_gender = State()
choosing_interest = State()
name = State()
age = State()
city = State()
text = State()
photo = State()
menu_answer = State()
my_anketa_answer = State()
change_text = State()
change_photo = State()
delete_confirm = State()
anketa_reaction = State()
В случае если анкета есть - показываем анкету. В случае если анкеты нет - предлагаем создать.
Python:
@dp.message_handler(commands="start", state = "*")
async def anketa_start(message: types.Message):
if(not BotDB.user_exists(message.from_user.id)):
BotDB.add_user(message.from_user.id)
if(BotDB.anketa_exists(message.from_user.id)):
anketa = BotDB.get_anketa(message.from_user.id)
a = anketa[0]
caption = show_profile(a[2], a[3], a[4], a[5])
await bot.send_photo(photo = open(f"photos/{message.from_user.id}.jpg", "rb"), chat_id = message.from_user.id, caption = caption)
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["1", "2", "3"]
keyboard.add(*buttons)
await message.answer(main_text, reply_markup = keyboard)
await Wait.menu_answer.set()
else:
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["Парень", "Девушка"]
keyboard.add(*buttons)
await message.answer("Заполним анкету!\nДля начала выберите свой пол",
reply_markup=keyboard)
await Wait.choosing_gender.set()
@dp.message_handler(state = Wait.choosing_gender)
async def choose_gender(message: types.Message, state: FSMContext):
if message.text not in ["Парень", "Девушка"]:
await message.answer("Выберите вариант из кнопок ниже")
return
await state.update_data(gender = message.text.lower())
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["Парни", "Девушки"]
keyboard.add(*buttons)
await message.answer("Кто тебя интересует?", reply_markup = keyboard)
await Wait.choosing_interest.set()
@dp.message_handler(state = Wait.choosing_interest)
async def choose_interest(message: types.Message, state: FSMContext):
if message.text == "Парни" or message.text == "Девушки":
await state.update_data(interest = message.text.lower())
await message.answer("Введите своё имя", reply_markup=types.ReplyKeyboardRemove())
await Wait.name.set()
else:
await message.answer("Выберите вариант из кнопок ниже")
return
@dp.message_handler(state = Wait.name)
async def name(message: types.Message, state: FSMContext):
if len(message.text) > 30:
await message.answer("Слишком длинное имя")
return
await state.update_data(name = message.text)
await message.answer("Сколько вам лет?")
await Wait.age.set()
@dp.message_handler(state = Wait.age)
async def age(message: types.Message, state: FSMContext):
try:
if 10 > int(message.text) or int(message.text) > 100:
await message.answer("Какой-то странный возраст")
return
except(TypeError, ValueError):
await message.answer("Какой-то странный возраст")
return
await state.update_data(age = message.text)
await message.answer("Напишите свой город")
await Wait.city.set()
@dp.message_handler(state = Wait.city)
async def city(message: types.Message, state: FSMContext):
if len(message.text) > 30:
await message.answer("Слишком длинный город")
return
await state.update_data(city = message.text)
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
keyboard.add("Оставить пустым")
await message.answer("Введите описание анкеты до 200 символов. Можно пропустить.", reply_markup = keyboard)
await Wait.text.set()
@dp.message_handler(state = Wait.text)
async def text(message: types.Message, state: FSMContext):
if message.text == "Оставить пустым":
await state.update_data(text = '')
else:
if len(message.text) > 200:
await message.answer("Описание должно быть длинной до 200 символов")
return
await state.update_data(text = message.text)
await message.answer("Загрузите своё фото", reply_markup=types.ReplyKeyboardRemove())
await Wait.photo.set()
Python:
@dp.message_handler(state = Wait.photo, content_types = ["photo"])
async def download_photo(message: types.Message, state: FSMContext):
await message.photo[-1].download(destination_file=f"photos/{message.from_user.id}.jpg")
data = await state.get_data()
d = list(data.values())
print(d)
BotDB.add_anketa(message.from_user.id, d[0], d[1], d[2], d[3], d[4], d[5])
caption = show_profile(d[2], d[3], d[4], d[5])
await message.answer("Так выглядит твоя анкета: ")
await bot.send_photo(photo = open(f"photos/{message.from_user.id}.jpg", "rb"), caption = caption, chat_id = message.from_user.id)
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["1", "2", "3"]
keyboard.add(*buttons)
await message.answer(main_text, reply_markup = keyboard)
await Wait.menu_answer.set()
@dp.message_handler(state = Wait.menu_answer)
async def menu_answer(message: types.Message, state: FSMContext):
if message.text == "1":
anketa = BotDB.get_anketa(message.from_user.id)
a = anketa[0]
caption = show_profile(a[2], a[3], a[4], a[5])
list_of_anketi = BotDB.find_anketi(message.from_user.id, a[7], a[4], a[3])
try:
get_random_anketa(list_of_anketi)
except ValueError:
await message.answer("Никого не могу найти. Возможно, твой город некорректный / не популярный.")
await bot.send_photo(photo = open(f"photos/{message.from_user.id}.jpg", "rb"), caption = caption, chat_id = message.from_user.id)
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["1", "2", "3", "4"]
keyboard.add(*buttons)
await message.answer(profile_text, reply_markup = keyboard)
await Wait.my_anketa_answer.set()
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["Лайк", "Скип", "Вернутся назад"]
keyboard.add(*buttons)
anketa = get_random_anketa(list_of_anketi)
caption = anketa[0]
photo_id = anketa[1]
await state.update_data(liked_id = photo_id)
await bot.send_photo(photo = open(f"photos/{photo_id}.jpg", "rb"), caption = caption, chat_id = message.from_user.id, reply_markup = keyboard)
await Wait.anketa_reaction.set()
elif message.text == "2":
anketa = BotDB.get_anketa(message.from_user.id)
a = anketa[0]
caption = show_profile(a[2], a[3], a[4], a[5])
await bot.send_photo(photo = open(f"photos/{message.from_user.id}.jpg", "rb"), caption = caption, chat_id = message.from_user.id)
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["1", "2", "3", "4"]
keyboard.add(*buttons)
await message.answer(profile_text, reply_markup = keyboard)
await Wait.my_anketa_answer.set()
elif message.text == "3":
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["Да", "Нет"]
keyboard.add(*buttons)
await message.answer("Вы точно хотите удалить свою анкету?", reply_markup = keyboard)
await Wait.delete_confirm.set()
else:
await message.answer("Выберите вариант из кнопок ниже")
return
@dp.message_handler(state = Wait.anketa_reaction)
async def anketa_reaction(message: types.Message, state: FSMContext):
if message.text == "Лайк":
data = await state.get_data()
d = list(data.values())
anketa = BotDB.get_anketa(message.from_user.id)
a = anketa[0]
caption = show_profile(a[2], a[3], a[4], a[5])
list_of_anketi = BotDB.find_anketi(message.from_user.id, data["interest"], data["city"], data["age"])
liked_id = data["liked_id"]
await bot.send_message(text = "Вы понравились этому человеку: ", chat_id = liked_id)
await bot.send_photo(photo = open(f"photos/{message.from_user.id}.jpg", "rb"), chat_id = liked_id, caption = caption)
await bot.send_message(text = f"Начинай общатся, если понравлися(лась) - @{message.from_user.username}", chat_id = liked_id)
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["Лайк", "Скип", "Вернутся назад"]
keyboard.add(*buttons)
anketa = get_random_anketa(list_of_anketi)
caption = anketa[0]
photo_id = anketa[1]
await bot.send_photo(photo = open(f"photos/{photo_id}.jpg", "rb"), caption = caption, chat_id = message.from_user.id)
await Wait.anketa_reaction.set()
elif message.text == "Скип":
data = await state.get_data()
list_of_anketi = BotDB.find_anketi(message.from_user.id, data["interest"], data["city"], data["age"])
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["Лайк", "Скип", "Вернутся назад"]
keyboard.add(*buttons)
caption = get_random_anketa(list_of_anketi)[0]
photo_id = get_random_anketa(list_of_anketi)[1]
await bot.send_photo(photo = open(f"photos/{photo_id}.jpg", "rb"), caption = caption, chat_id = message.from_user.id)
await Wait.anketa_reaction.set()
elif message.text == "Вернутся назад":
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["1", "2", "3"]
keyboard.add(*buttons)
await message.answer(main_text, reply_markup = keyboard)
await Wait.menu_answer.set()
else:
await message.answer("Выберите вариант из кнопок")
return
@dp.message_handler(state = Wait.delete_confirm)
async def delete_confirm(message: types.Message, state: FSMContext):
if message.text == "Да":
BotDB.delete_anketa(message.from_user.id)
BotDB.delete_user(message.from_user.id)
await message.answer("Ваша анкета удалена!\nВы можете вернутся сюда в любое время по команде /start", reply_markup = types.ReplyKeyboardRemove())
elif message.text == "Нет":
anketa = BotDB.get_anketa(message.from_user.id)
a = anketa[0]
caption = show_profile(a[2], a[3], a[4], a[5])
await bot.send_photo(photo = open(f"photos/{message.from_user.id}.jpg", "rb"), caption = caption, chat_id = message.from_user.id)
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["1", "2", "3", "4"]
keyboard.add(*buttons)
await message.answer(profile_text, reply_markup = keyboard)
await Wait.my_anketa_answer.set()
else:
await message.answer("Выберите вариант из кнопок ниже")
return
Python:
@dp.message_handler(state = Wait.my_anketa_answer)
async def my_anketa_answer(message: types.Message, state: FSMContext):
if message.text == "1":
BotDB.delete_anketa(message.from_user.id)
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["Парень", "Девушка"]
keyboard.add(*buttons)
await message.answer("Для начала выберите свой пол",
reply_markup=keyboard)
await Wait.choosing_gender.set()
# вводим новый текст
elif message.text == "2":
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
keyboard.add("Оставить пустым")
await message.answer("Введите новый текст анкеты", reply_markup=keyboard)
await Wait.change_text.set()
elif message.text == "3":
await message.answer("Загрузите новое фото", reply_markup = types.ReplyKeyboardRemove())
await Wait.change_photo.set()
elif message.text == "4":
anketa = BotDB.get_anketa(message.from_user.id)
a = anketa[0]
caption = show_profile(a[2], a[3], a[4], a[5])
await bot.send_photo(photo = open(f"photos/{message.from_user.id}.jpg", "rb"), caption = caption, chat_id = message.from_user.id)
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["1", "2", "3"]
keyboard.add(*buttons)
await message.answer(main_text, reply_markup = keyboard)
await Wait.menu_answer.set()
else:
await message.answer("Выберите вариант из кнопок ниже")
return
@dp.message_handler(state = Wait.change_text)
async def change_text(message: types.Message, state: FSMContext):
if message.text == "Оставить пустым":
BotDB.update_text(message.from_user.id, '')
anketa = BotDB.get_anketa(message.from_user.id)
a = anketa[0]
caption = show_profile(a[2], a[3], a[4], a[5])
await bot.send_photo(photo = open(f"photos/{message.from_user.id}.jpg", "rb"), caption = caption, chat_id = message.from_user.id)
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["1", "2", "3", "4"]
keyboard.add(*buttons)
await message.answer(profile_text, reply_markup = keyboard)
await Wait.my_anketa_answer.set()
else:
if len(message.text) > 200:
await message.answer("Описание должно быть длинной до 200 символов")
return
BotDB.update_text(message.from_user.id, message.text)
anketa = BotDB.get_anketa(message.from_user.id)
a = anketa[0]
caption = show_profile(a[2], a[3], a[4], a[5])
await bot.send_photo(photo = open(f"photos/{message.from_user.id}.jpg", "rb"), caption = caption, chat_id = message.from_user.id)
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["1", "2", "3"]
keyboard.add(*buttons)
await message.answer(main_text, reply_markup = keyboard)
await Wait.menu_answer.set()
@dp.message_handler(state = Wait.change_photo, content_types = ["photo"])
async def change_photo(message: types.Message, state: FSMContext):
await message.photo[-1].download(destination_file=f"photos/{message.from_user.id}.jpg")
anketa = BotDB.get_anketa(message.from_user.id)
a = anketa[0]
caption = show_profile(a[2], a[3], a[4], a[5])
await message.answer("Вот ваша анкета: ")
await bot.send_photo(photo = open(f"photos/{message.from_user.id}.jpg", "rb"), caption = caption, chat_id = message.from_user.id)
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
buttons = ["1", "2", "3"]
keyboard.add(*buttons)
await message.answer(main_text, reply_markup = keyboard)
await Wait.menu_answer.set()
if __name__ == "__main__":
executor.start_polling(dp, skip_updates=True)
Параметр
skip_updates=True позволяет пропустить накопившиеся входящие сообщения, если они нам не важны.Далее создаём базу данных. Я не мастер объяснять SQL-запросы, к сожалению.
Код ниже - запросы к базе, они и не нуждаются в представлениях и описаниях. Используем sqlite3.
SQL:
import sqlite3
class BotDB:
# название базы напишите сюда
def __init__(self, db_file):
self.conn = sqlite3.connect(db_file)
self.cursor = self.conn.cursor()
def user_exists(self, user_id):
result = self.cursor.execute("SELECT `id` FROM `users` WHERE `user_id` = ?", (user_id,))
return bool(len(result.fetchall()))
def anketa_exists(self, user_id):
result = self.cursor.execute("SELECT COUNT (*) FROM `anketi` WHERE `users_id` = ?", (self.get_user_id(user_id),))
result = result.fetchone()[0]
if result == 0:
return False
elif result == 1:
return True
else:
return None
def get_user_id(self, user_id):
result = self.cursor.execute("SELECT `id` FROM `users` WHERE `user_id` = ?", (user_id,))
return result.fetchone()[0]
def get_photo_id(self, users_id):
result = self.cursor.execute("SELECT `user_id` FROM `users` WHERE `id` = ?", (users_id,))
return result.fetchone()[0]
def add_user(self, user_id):
self.cursor.execute("INSERT INTO `users` (`user_id`) VALUES (?)", (user_id,))
return self.conn.commit()
def add_anketa(self, user_id, gender, interest, name, age, city, text):
self.cursor.execute("INSERT INTO `anketi` (`users_id`, `name`, `age`, `city`, `text`, `gender`, `interest`) VALUES\
(?, ?, ?, ?, ?, ?, ?)", (self.get_user_id(user_id), name, age, city.title(), text, gender, interest))
return self.conn.commit()
def update_text(self, user_id, new_text):
self.cursor.execute("UPDATE `anketi` SET `text` = ? WHERE `users_id` = ?", (new_text, self.get_user_id(user_id)))
return self.conn.commit()
def get_anketa(self, user_id):
result = self.cursor.execute("SELECT * FROM `anketi` WHERE `users_id` = ?", (self.get_user_id(user_id),))
return result.fetchall()
def delete_anketa(self, user_id):
self.cursor.execute("DELETE FROM `anketi` WHERE `users_id` = ?", (self.get_user_id(user_id),))
return self.conn.commit()
def delete_user(self, user_id):
self.cursor.execute("DELETE FROM `users` WHERE `id` = ?", (self.get_user_id(user_id),))
return self.conn.commit()
def find_anketi(self, user_id, interest, city, age):
gender: str = ""
if interest == "парни":
gender = "парень"
if interest == "девушки":
gender = "девушка"
result = self.cursor.execute("SELECT * FROM `anketi` WHERE `users_id` != ? AND `gender` = ? AND `city` = ? AND `age` BETWEEN ? AND ?", (self.get_user_id(user_id), gender, city.title(), int(age) - 1, int(age) + 1))
return result.fetchall()
def close(self):
self.connection.close()
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
Бот работает. Все данные о пользователях хранятся в database.bd
Чтобы видеть скрытое содержание Зарегистрируйтесь на форуме!
Фотографии пользователей хранятся в папке photos.
Для тех, кто хочет сразу же скачать бота и запустить, архив прикреплён. Качайте и пользуйтесь.
Пароль от прикреплённого архива: pawno-info.ru
Вложения
-
145.8 KB Просмотры: 239
Последнее редактирование модератором:
