Compare commits

..

10 Commits

Author SHA1 Message Date
bd2724c612 Fix 2025-02-03 22:15:18 +05:00
dbdcc7b5d9 Fix 2025-02-03 22:12:02 +05:00
e08116ae07 Добавил функцию переписи населения 2025-02-03 22:12:02 +05:00
Udo
2dd292ed4a Update main.py 2025-02-03 22:12:02 +05:00
Udo
e3edf5afbf Update main.py 2025-02-03 22:12:02 +05:00
2c6285d534 add send dogs pic 2025-02-03 22:12:02 +05:00
3fc02009d1 add docker-compose.yaml 2025-02-03 22:12:02 +05:00
880bb42a53 add docker-compose.yaml 2025-02-03 22:12:02 +05:00
d432d8f100 add send_cats 2025-02-03 22:12:02 +05:00
e5086679ad add send_cats 2025-02-03 22:12:02 +05:00
6 changed files with 150 additions and 42 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/.idea/
users.txt

10
.idea/.gitignore generated vendored
View File

@ -1,10 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
.idea/
/.env

View File

@ -1,5 +1,5 @@
# Используем официальный Python образ в качестве базового
FROM python:3.11-slim
FROM python:3.13.1-slim
LABEL authors="UdoChudo"
@ -11,12 +11,13 @@ COPY requirements.txt .
# Устанавливаем зависимости
RUN pip install --no-cache-dir -r requirements.txt
RUN mkdir /app/data
# Копируем все файлы проекта в рабочую директорию
COPY main.py .
# Устанавливаем переменную окружения для токена API
ENV BOT_TOKEN=your_api_token_here
ENV CAT_TOKEN=your_cat_token_here
ENV DOG_TOKEN=your_dog_token_here
# Команда для запуска бота
CMD ["python", "main.py"]

9
docker-compose.yaml Normal file
View File

@ -0,0 +1,9 @@
version: '3.8'
services:
bot:
build: .
env_file:
- stack.env
restart: always
pull_policy: build

147
main.py
View File

@ -1,28 +1,59 @@
import os
import logging
import requests
from aiogram import Bot, Dispatcher, types
from aiogram import Bot, Dispatcher, types, BaseMiddleware
from aiogram.filters import Command
from aiogram.types import Message
from aiogram.types import Message, FSInputFile
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from dotenv import load_dotenv
import os
import asyncio
# Загрузка переменных окружения из .env файла
load_dotenv()
# Получение токена из переменной окружения
API_TOKEN = os.getenv('BOT_TOKEN')
BOT_TOKEN = os.getenv('BOT_TOKEN')
LOG_LEVEL = os.getenv("LOG_LEVEL")
if not API_TOKEN:
CAT_API = os.getenv('CAT_TOKEN')
DOG_API = os.getenv('DOG_TOKEN')
BOT_OWNER_ID = os.getenv('BOT_OWNER')
if not BOT_TOKEN:
raise ValueError("No API_TOKEN provided. Please set the API_TOKEN environment variable.")
if not CAT_API:
raise ValueError("No CAT_TOKEN provided. Please set the CAT_TOKEN environment variable.")
if not DOG_API:
raise ValueError("No DOG_TOKEN provided. Please set the DOG_TOKEN environment variable.")
if not BOT_OWNER_ID:
raise ValueError("No BOT_OWNER_ID provided. Please set the BOT_OWNER_ID environment variable.")
FILE_PATH = "/app/data/users.txt"
FILE_PATH_WINDOWS = "./users.txt"
# Настраиваем логирование
logging.basicConfig(level=logging.ERROR)
logging.basicConfig(level=logging.INFO)
# Инициализация бота
bot = Bot(token=API_TOKEN)
bot = Bot(token=BOT_TOKEN)
dp = Dispatcher()
# Middleware для ограничения частоты запросов
class ThrottlingMiddleware(BaseMiddleware):
def __init__(self, rate_limit=1.0):
self.rate_limit = rate_limit
self.last_time = {}
super().__init__()
async def __call__(self, handler, event, data):
if isinstance(event, types.Message):
user_id = event.from_user.id
now = asyncio.get_event_loop().time()
if user_id in self.last_time and now - self.last_time[user_id] < self.rate_limit:
await event.answer("Подождите немного перед повторным нажатием!")
return
self.last_time[user_id] = now
return await handler(event, data)
# Регистрируем middleware
dp.message.middleware(ThrottlingMiddleware())
# Обработчик команды /boobs
@dp.message(Command(commands=['boobs'], prefix="!/"))
async def send_boobs(message: Message):
@ -81,28 +112,98 @@ async def send_butts(message: Message):
@dp.message(Command(commands=['cats'], prefix="!/"))
async def send_cats(message: Message):
response = requests.get('https://api.thecatapi.com/api/images/get?api_key=Mjg0Mzg2&format=json')
response = requests.get('https://api.thecatapi.com/api/images/get?api_key=' + CAT_API + '&format=json')
if response.status_code == 200:
data = response.json()
if data:
img_url = data[0]['url']
await bot.send_photo(
chat_id=message.chat.id, # Отправка в тот же чат, где была вызвана команда
photo=img_url,
has_spoiler=False,
caption=f"{message.from_user.username} заказал котиков!"
)
img_url = str(data[0]['url'])
await bot.send_photo(
chat_id=message.chat.id, # Отправка в тот же чат, где была вызвана команда
photo=img_url,
has_spoiler=False,
caption=f"{message.from_user.username} заказал котиков!"
)
else:
await message.answer("Не удалось получить данные с сервера.")
else:
await message.answer("Ошибка при выполнении запроса к API.")
@dp.message(Command(commands=['dogs'], prefix="!/"))
async def send_dogs(message: Message):
response = requests.get('https://api.thedogapi.com/api/images/get?api_key=' + DOG_API + '&format=json')
if response.status_code == 200:
data = response.json()
if data:
img_url = str(data[0]['url'])
await bot.send_photo(
chat_id=message.chat.id, # Отправка в тот же чат, где была вызвана команда
photo=img_url,
has_spoiler=False,
caption=f"{message.from_user.username} заказал пёсиков!"
)
else:
await message.answer("Не удалось получить данные с сервера.")
else:
await message.answer("Ошибка при выполнении запроса к API.")
@dp.message(Command("census"))
async def start_census(message: types.Message):
if message.from_user.id != int(BOT_OWNER_ID): # Убедитесь, что BOT_OWNER_ID это строка, конвертируем в int
await message.answer("Только владелец бота может запускать перепись!")
return
# Исправленное создание клавиатуры
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Принять участие", callback_data="census_join")]
])
await message.answer("Перепись участников начата! Нажмите кнопку ниже, чтобы участвовать.", reply_markup=keyboard)
@dp.callback_query(lambda c: c.data == "census_join")
async def register_user(callback_query: types.CallbackQuery):
user = callback_query.from_user
username = user.username or user.full_name
try:
with open("/app/data/users.txt", "r", encoding="utf-8") as file:
existing_users = file.readlines()
except FileNotFoundError:
existing_users = []
user_entry = f"{user.id}, @{username}\n"
if user_entry in existing_users:
await callback_query.answer("Вы уже записаны в перепись!")
return
with open("/app/data/users.txt", "a", encoding="utf-8") as file:
file.write(user_entry)
await callback_query.answer("Вы записаны в перепись!")
# Обработчик команды /sendfile
@dp.message(Command(commands=["sendfile"]))
async def send_file(message: Message):
document = ""
# Проверка, является ли отправитель владельцем бота
if message.from_user.id != int(BOT_OWNER_ID):
await message.answer("Только владелец бота может отправить файл!")
return
if os.path.exists(FILE_PATH):
document = FSInputFile(FILE_PATH)
elif os.path.exists(FILE_PATH_WINDOWS):
document = FSInputFile(FILE_PATH_WINDOWS)
else:
await message.answer("Файл не найден на сервере")
await bot.send_document(message.chat.id, document, caption="Вот ваш файл!")
@dp.message()
async def default_message(message: types.Message):
async def default_message():
pass
async def main():
# Регистрация обработчиков
dp.message.register(send_boobs)
dp.message.register(send_butts)
dp.message.register(send_cats)
# Запуск polling
await dp.start_polling(bot)

View File

@ -1,20 +1,25 @@
aiofiles==23.2.1
aiogram==3.12.0
aio-pika==9.5.4
aiofiles==24.1.0
aiogram==3.17.0
aiohappyeyeballs==2.4.0
aiohttp==3.10.5
aiohttp==3.11.11
aiormq==6.8.1
aiosignal==1.3.1
annotated-types==0.7.0
attrs==24.2.0
certifi==2024.8.30
charset-normalizer==3.3.2
exceptiongroup==1.2.2
frozenlist==1.4.1
idna==3.8
magic-filter==1.0.12
multidict==6.0.5
pydantic==2.8.2
pydantic_core==2.20.1
pamqp==3.3.0
propcache==0.2.1
pydantic==2.10.6
pydantic_core==2.27.2
python-dotenv==1.0.1
requests==2.32.3
typing_extensions==4.12.2
urllib3==2.2.2
yarl==1.9.7
yarl==1.18.3