Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e9502c7a38 | |||
| 31bf50aaca | |||
| 8423912dbb | |||
| 64508438e7 | |||
| f5cf63bac0 | |||
| 37d4400513 | |||
| 5dece14c8b | |||
| 5c325bd8b9 | |||
| 62873c7f8c | |||
| 4883320aaa | |||
| 0f9d6470b8 |
+15
-5
@@ -14,14 +14,11 @@ LOLZ_TOKEN=
|
||||
LOLZ_THREAD_ID=
|
||||
|
||||
STARS_COUNT=1
|
||||
|
||||
# 1 - Начать мониторинг
|
||||
# 2 - Спарсить все существующие посты
|
||||
DEFAULT_CHOICE=2
|
||||
START_PAGE=1
|
||||
|
||||
CHECK_INTERVAL=30
|
||||
CHECK_INTERVAL=10
|
||||
API_DELAY=5
|
||||
API_TIMEOUT=15
|
||||
MAX_RETRIES=3
|
||||
|
||||
ENABLE_REPLY=true
|
||||
@@ -39,3 +36,16 @@ CAPTCHA_ANSWER=40
|
||||
# Капча будет автоматически обновляться из файла storage/captcha.txt
|
||||
CAPTCHA_CHECK_INTERVAL=1800
|
||||
|
||||
# Прокси: применяется в зависимости от выбранных опций PROXY_TELEGRAM и PROXY_LOLZ
|
||||
PROXY_TELEGRAM=false
|
||||
PROXY_LOLZ=false
|
||||
# Прокси
|
||||
# Формат protocol://username:password@host:port или protocol://host:port
|
||||
PROXY=
|
||||
|
||||
# Можно задать данные для прокси отдельно
|
||||
PROXY_PROTOCOL=socks5 # поддерживаются socks5 и https форматы
|
||||
PROXY_HOST=
|
||||
PROXY_PORT=
|
||||
PROXY_USERNAME= # Можно не ставить, если для прокси авторизация не нужна
|
||||
PROXY_PASSWORD= # Можно не ставить, если для прокси авторизация не нужна
|
||||
|
||||
@@ -7,11 +7,15 @@
|
||||
- Автоматический мониторинг темы на Lolz.team
|
||||
- Отправка Telegram Stars за каждый новый пост
|
||||
- Автоматические ответы с поддержкой шаблонов (включая случайный выбор)
|
||||
- Автоматическое поднятие темы (bump) с настраиваемым интервалом
|
||||
- Система капчи для фильтрации пользователей
|
||||
- Поддержка прокси для Telegram и Lolz API (SOCKS5/HTTPS)
|
||||
- Полная поддержка Docker (рекомендуется)
|
||||
- CI/CD через Gitea Actions (сборка и публикация образов)
|
||||
- Уведомления администратору через Telegram
|
||||
- Гибкая настройка через `.env`
|
||||
- Логирование и сохранение сессии
|
||||
- Обработка ошибок и повторные попытки
|
||||
|
||||
## Требования
|
||||
|
||||
@@ -23,12 +27,14 @@
|
||||
## Быстрый старт (Docker — рекомендуется)
|
||||
|
||||
1. Клонируйте репозиторий:
|
||||
|
||||
```bash
|
||||
git clone https://git.sakamoto.best/Lolz/Auto-Stars-Improved.git
|
||||
cd Auto-Stars-Improved
|
||||
```
|
||||
|
||||
2. Скопируйте пример конфигурации:
|
||||
|
||||
```bash
|
||||
cp examples/.env.example .env
|
||||
```
|
||||
@@ -36,6 +42,7 @@
|
||||
3. Отредактируйте `.env` и заполните необходимые значения (`API_ID`, `API_HASH`, `LOLZ_TOKEN`, `LOLZ_THREAD_ID` и т.д.).
|
||||
|
||||
4. Запустите:
|
||||
|
||||
```bash
|
||||
docker compose -f examples/docker-compose.yml up -d
|
||||
```
|
||||
@@ -61,19 +68,108 @@ python main.py
|
||||
Все настройки находятся в файле `.env`.
|
||||
|
||||
Пример конфигурации лежит здесь:
|
||||
|
||||
- `examples/.env.example`
|
||||
|
||||
**Основные параметры:**
|
||||
### Основные параметры
|
||||
|
||||
| Переменная | Описание | По умолчанию |
|
||||
|-----------------------|-----------------------------------------------|--------------|
|
||||
| `API_ID` / `API_HASH` | Данные Telegram API | - |
|
||||
| `LOLZ_TOKEN` | Токен API Lolz.team | - |
|
||||
| `LOLZ_THREAD_ID` | ID темы на форуме | - |
|
||||
| `STARS_COUNT` | Сколько звёзд отправлять за пост | 1 |
|
||||
| `DEFAULT_CHOICE` | 1 — реал-тайм, 2 — обработать все посты | 2 |
|
||||
| `ENABLE_REPLY` | Отправлять ли комментарии | true |
|
||||
| `SKIP_COMMENTED` | Пропускать посты, на которые уже отвечали | true |
|
||||
| Переменная | Описание | По умолчанию |
|
||||
| --------------------- | ----------------------------------------- | ------------ |
|
||||
| `API_ID` / `API_HASH` | Данные Telegram API | - |
|
||||
| `LOLZ_TOKEN` | Токен API Lolz.team | - |
|
||||
| `LOLZ_THREAD_ID` | ID темы на форуме | - |
|
||||
| `STARS_COUNT` | Сколько звёзд отправлять за пост | 1 |
|
||||
| `START_PAGE` | С какой страницы начинать парсинг | 1 |
|
||||
| `ENABLE_REPLY` | Отправлять ли комментарии | true |
|
||||
| `SKIP_COMMENTED` | Пропускать посты, на которые уже отвечали | true |
|
||||
|
||||
### Параметры производительности
|
||||
|
||||
| Переменная | Описание | По умолчанию |
|
||||
| ---------------- | ---------------------------------------- | ------------ |
|
||||
| `CHECK_INTERVAL` | Интервал проверки новых постов (секунды) | 10 |
|
||||
| `API_DELAY` | Задержка между API запросами (секунды) | 5 |
|
||||
| `API_TIMEOUT` | Таймаут для API запросов (секунды) | 15 |
|
||||
| `MAX_RETRIES` | Количество повторных попыток при ошибках | 3 |
|
||||
|
||||
### Уведомления
|
||||
|
||||
| Переменная | Описание | По умолчанию |
|
||||
| -------------- | ------------------------------------------ | ------------ |
|
||||
| `BOT_TOKEN` | Токен бота для уведомлений (от @BotFather) | - |
|
||||
| `ADMIN_ID` | Telegram ID администратора для уведомлений | - |
|
||||
| `NOTIFY_ADMIN` | Включить уведомления администратору | true |
|
||||
|
||||
### Автоматическое поднятие темы (Bump)
|
||||
|
||||
| Переменная | Описание | По умолчанию |
|
||||
| --------------------- | ------------------------------------- | ------------ |
|
||||
| `ENABLE_AUTO_BUMP` | Включить автоматическое поднятие темы | true |
|
||||
| `BUMP_CHECK_INTERVAL` | Интервал между поднятиями (секунды) | 3600 |
|
||||
|
||||
> **Примечание**: Минимальный интервал поднятия — 3600 секунд (1 час) согласно правилам Lolz.team.
|
||||
|
||||
### Система капчи
|
||||
|
||||
| Переменная | Описание | По умолчанию |
|
||||
| ------------------------ | -------------------------------------------- | ------------ |
|
||||
| `ENABLE_CAPTCHA` | Включить систему капчи | false |
|
||||
| `CAPTCHA_ANSWER` | Правильный ответ на капчу | - |
|
||||
| `CAPTCHA_CHECK_INTERVAL` | Интервал проверки обновления капчи (секунды) | 1800 |
|
||||
|
||||
Капча добавляется в нижний спойлер первого поста темы: `Капча (обязательно)`.
|
||||
|
||||
Текст капчи хранится в файле `storage/captcha.txt` и поддерживает BBCode форматирование.
|
||||
|
||||
**Пример `storage/captcha.txt`:**
|
||||
|
||||
```
|
||||
[CENTER][B]Напишите ответ:[/B]
|
||||
сколько будет 20 + 20? [I][COLOR=rgb(80, 80, 78)](Капча меняется раз в месяц)[/COLOR][/I][/CENTER]
|
||||
```
|
||||
|
||||
### Прокси
|
||||
|
||||
Бот поддерживает использование прокси отдельно для Telegram и Lolz API.
|
||||
|
||||
| Переменная | Описание | По умолчанию |
|
||||
| ---------------- | -------------------------------- | ------------ |
|
||||
| `PROXY_TELEGRAM` | Использовать прокси для Telegram | false |
|
||||
| `PROXY_LOLZ` | Использовать прокси для Lolz API | false |
|
||||
|
||||
#### Вариант 1: Единая строка прокси
|
||||
|
||||
```env
|
||||
PROXY=socks5://username:password@host:port
|
||||
```
|
||||
|
||||
Или без авторизации:
|
||||
|
||||
```env
|
||||
PROXY=socks5://host:port
|
||||
```
|
||||
|
||||
#### Вариант 2: Отдельные параметры
|
||||
|
||||
| Переменная | Описание | По умолчанию |
|
||||
| ---------------- | ---------------------------------- | ------------ |
|
||||
| `PROXY_PROTOCOL` | Протокол прокси (socks5 или https) | socks5 |
|
||||
| `PROXY_HOST` | Хост прокси-сервера | - |
|
||||
| `PROXY_PORT` | Порт прокси-сервера | - |
|
||||
| `PROXY_USERNAME` | Логин (опционально) | - |
|
||||
| `PROXY_PASSWORD` | Пароль (опционально) | - |
|
||||
|
||||
**Поддерживаемые форматы прокси:**
|
||||
|
||||
- SOCKS5: `socks5://host:port`
|
||||
- HTTPS: `https://host:port`
|
||||
|
||||
**Поддерживаемые возможности:**
|
||||
|
||||
- ✓ Пароли с символом `:` внутри
|
||||
- ✓ IPv6 адреса
|
||||
- ✓ Авторизация с логином и паролем
|
||||
- ✓ Независимая настройка для Telegram и Lolz API
|
||||
|
||||
## Шаблоны ответов
|
||||
|
||||
@@ -82,13 +178,21 @@ python main.py
|
||||
Шаблоны хранятся в файле `storage/replies.txt`.
|
||||
|
||||
**Формат:**
|
||||
|
||||
- Каждая строка — отдельный шаблон
|
||||
- Можно использовать `||` для случайного выбора
|
||||
|
||||
**Пример:**
|
||||
|
||||
```
|
||||
:catdance: Отправил звёзды || :animeyes2: Отправил
|
||||
:sadge: Тут может быть реклама
|
||||
```
|
||||
|
||||
Если файл пустой — используется `✓`.
|
||||
|
||||
## Поддержка
|
||||
|
||||
- Автор: [Дриада](https://lolz.team/members/7272152/)
|
||||
- Создайте Issue на Gitea: https://git.sakamoto.best/Lolz/Auto-Stars-Improved/issues
|
||||
- Тема на форуме Lolz.team: https://lolz.team/threads/10187517/
|
||||
|
||||
@@ -106,7 +106,6 @@ class Config:
|
||||
stars_count = int(os.getenv(key="STARS_COUNT", default=1))
|
||||
|
||||
# Misc
|
||||
default_choice = int(os.getenv(key="DEFAULT_CHOICE", default=2))
|
||||
start_page = max(int(os.getenv(key="START_PAGE", default=1)), 1)
|
||||
|
||||
check_interval = max(
|
||||
@@ -115,6 +114,7 @@ class Config:
|
||||
api_delay = max(
|
||||
float(os.getenv(key="API_DELAY", default=5)), 2
|
||||
) # 30r/60s для non-GET запросов, 60/30 = минимум
|
||||
api_timeout = float(os.getenv(key="API_TIMEOUT", default=15))
|
||||
max_retries = int(os.getenv(key="MAX_RETRIES", default=3))
|
||||
|
||||
enable_reply = (
|
||||
@@ -145,6 +145,135 @@ class Config:
|
||||
"ENABLE_CAPTCHA установлен, но CAPTCHA_ANSWER не задан"
|
||||
)
|
||||
|
||||
proxy_telegram = (
|
||||
os.getenv(key="PROXY_TELEGRAM", default="false")
|
||||
).lower() == "true"
|
||||
proxy_lolz = (
|
||||
os.getenv(key="PROXY_LOLZ", default="false")
|
||||
).lower() == "true"
|
||||
|
||||
proxy_protocol = None
|
||||
proxy_host = None
|
||||
proxy_port = None
|
||||
proxy_port_str = None
|
||||
proxy_username = None
|
||||
proxy_password = None
|
||||
|
||||
if proxy_telegram or proxy_lolz:
|
||||
proxy = os.getenv(key="PROXY", default=None)
|
||||
|
||||
proxy_protocol = os.getenv(key="PROXY_PROTOCOL", default="socks5")
|
||||
proxy_host = os.getenv(key="PROXY_HOST", default=None)
|
||||
proxy_port_str = os.getenv(key="PROXY_PORT", default=None)
|
||||
proxy_username = os.getenv(key="PROXY_USERNAME", default=None)
|
||||
proxy_password = os.getenv(key="PROXY_PASSWORD", default=None)
|
||||
|
||||
if proxy:
|
||||
logger.info("Парсинг прокси из переменной PROXY...")
|
||||
try:
|
||||
parts = proxy.split("://")
|
||||
if len(parts) != 2:
|
||||
raise ConfigError(
|
||||
"Неверный формат PROXY. Ожидается: protocol://[username:password@]host:port"
|
||||
)
|
||||
|
||||
proxy_protocol = parts[0]
|
||||
main = parts[1]
|
||||
|
||||
# Проверяем наличие авторизации (username:password@host:port)
|
||||
if "@" in main:
|
||||
main_split = main.split("@")
|
||||
if len(main_split) != 2:
|
||||
raise ConfigError("Неверный формат авторизации в PROXY")
|
||||
|
||||
authorization = main_split[0]
|
||||
server = main_split[1]
|
||||
|
||||
# Парсим username:password (используем split с limit для поддержки : в пароле)
|
||||
auth_parts = authorization.split(":", 1)
|
||||
if len(auth_parts) != 2:
|
||||
raise ConfigError(
|
||||
"Неверный формат авторизации в PROXY. Ожидается: username:password"
|
||||
)
|
||||
proxy_username = auth_parts[0]
|
||||
proxy_password = auth_parts[1]
|
||||
else:
|
||||
server = main
|
||||
|
||||
# Парсим host:port (используем rsplit для поддержки IPv6)
|
||||
server_parts = server.rsplit(":", 1)
|
||||
if len(server_parts) != 2:
|
||||
raise ConfigError(
|
||||
"Неверный формат сервера в PROXY. Ожидается: host:port"
|
||||
)
|
||||
proxy_host = server_parts[0]
|
||||
try:
|
||||
proxy_port = int(server_parts[1])
|
||||
except ValueError as e:
|
||||
raise ConfigError(
|
||||
f"PROXY_PORT должен быть целым числом: {server_parts[1]}"
|
||||
) from e
|
||||
|
||||
logger.info(
|
||||
"Прокси успешно распарсен: protocol=%s, host=%s, port=%s, auth=%s",
|
||||
proxy_protocol,
|
||||
proxy_host,
|
||||
proxy_port,
|
||||
"да" if proxy_username else "нет",
|
||||
)
|
||||
|
||||
except ConfigError:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise ConfigError(
|
||||
f"Произошла ошибка при парсе PROXY: {e}"
|
||||
) from e
|
||||
|
||||
else:
|
||||
logger.info("Загрузка прокси из отдельных переменных...")
|
||||
# Используем отдельные поля
|
||||
if not proxy_host or not proxy_port_str:
|
||||
raise ConfigError(
|
||||
"PROXY не указан, но PROXY_HOST или PROXY_PORT также отсутствуют"
|
||||
)
|
||||
|
||||
try:
|
||||
proxy_port = int(proxy_port_str)
|
||||
except (ValueError, TypeError) as e:
|
||||
raise ConfigError(
|
||||
f"PROXY_PORT должен быть целым числом: {proxy_port_str}"
|
||||
) from e
|
||||
|
||||
logger.info(
|
||||
"Прокси загружен: protocol=%s, host=%s, port=%s, auth=%s",
|
||||
proxy_protocol,
|
||||
proxy_host,
|
||||
proxy_port,
|
||||
"да" if proxy_username else "нет",
|
||||
)
|
||||
|
||||
# Валидация
|
||||
if proxy_protocol not in ["socks5", "https", "http"]:
|
||||
raise ConfigError(
|
||||
f"Формат прокси '{proxy_protocol}' не поддерживается. Укажите socks5 или https"
|
||||
)
|
||||
|
||||
if (proxy_username and not proxy_password) or (
|
||||
proxy_password and not proxy_username
|
||||
):
|
||||
raise ConfigError(
|
||||
"PROXY_USERNAME и PROXY_PASSWORD должны быть указаны оба или не указаны вовсе"
|
||||
)
|
||||
|
||||
# Финальная проверка
|
||||
if not (proxy_protocol and proxy_host and proxy_port):
|
||||
raise ConfigError("Прокси не полностью настроены")
|
||||
|
||||
if proxy_telegram:
|
||||
logger.info("Прокси для Telegram включен")
|
||||
if proxy_lolz:
|
||||
logger.info("Прокси для Lolz API включен")
|
||||
|
||||
return {
|
||||
# Pyrogram
|
||||
"api_id": api_id,
|
||||
@@ -165,8 +294,8 @@ class Config:
|
||||
"skip_commented": skip_commented,
|
||||
# Misc
|
||||
"api_delay": api_delay,
|
||||
"api_timeout": api_timeout,
|
||||
"max_retries": max_retries,
|
||||
"default_choice": default_choice,
|
||||
# Bump
|
||||
"enable_auto_bump": enable_auto_bump,
|
||||
"bump_check_interval": bump_check_interval,
|
||||
@@ -174,13 +303,23 @@ class Config:
|
||||
"enable_captcha": enable_captcha,
|
||||
"captcha_answer": captcha_answer,
|
||||
"captcha_check_interval": captcha_check_interval,
|
||||
# Proxy
|
||||
"proxy_telegram": proxy_telegram,
|
||||
"proxy_lolz": proxy_lolz,
|
||||
"proxy_protocol": proxy_protocol,
|
||||
"proxy_host": proxy_host,
|
||||
"proxy_port": proxy_port,
|
||||
"proxy_username": proxy_username,
|
||||
"proxy_password": proxy_password,
|
||||
}
|
||||
|
||||
except ConfigError:
|
||||
raise
|
||||
|
||||
except (ValueError, TypeError) as e:
|
||||
logger.error(f"Invalid configuration value: {e}")
|
||||
raise ConfigError(f"Invalid configuration value: {e}") from e
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Unexpected error loading configuration: {e}")
|
||||
raise ConfigError(f"Failed to load configuration: {e}") from e
|
||||
|
||||
+19
-5
@@ -1,6 +1,9 @@
|
||||
LOGS_PATH=./logs
|
||||
STORAGE_PATH=./storage
|
||||
|
||||
UID=1000
|
||||
GID=1000
|
||||
|
||||
# Значения для клиента Telegram Desktop, ставятся по умолчанию
|
||||
# Не рекомендуется оставлять, лучше использовать API_ID и API_HASH от
|
||||
# аккаунта с которого будет воспроизведен вход
|
||||
@@ -17,14 +20,11 @@ LOLZ_TOKEN=
|
||||
LOLZ_THREAD_ID=
|
||||
|
||||
STARS_COUNT=1
|
||||
|
||||
# 1 - Начать мониторинг
|
||||
# 2 - Спарсить все существующие посты
|
||||
DEFAULT_CHOICE=2
|
||||
START_PAGE=1
|
||||
|
||||
CHECK_INTERVAL=30
|
||||
CHECK_INTERVAL=10
|
||||
API_DELAY=5
|
||||
API_TIMEOUT=15
|
||||
MAX_RETRIES=3
|
||||
|
||||
ENABLE_REPLY=true
|
||||
@@ -42,3 +42,17 @@ CAPTCHA_ANSWER=40
|
||||
# Капча будет автоматически обновляться из файла storage/captcha.txt
|
||||
CAPTCHA_CHECK_INTERVAL=1800
|
||||
|
||||
# Прокси: применяется в зависимости от выбранных опций PROXY_TELEGRAM и PROXY_LOLZ
|
||||
PROXY_TELEGRAM=false
|
||||
PROXY_LOLZ=false
|
||||
# Прокси
|
||||
# Формат protocol://username:password@host:port или protocol://host:port
|
||||
PROXY=
|
||||
|
||||
# Можно задать данные для прокси отдельно
|
||||
PROXY_PROTOCOL=socks5 # поддерживаются socks5 и https форматы
|
||||
PROXY_HOST=
|
||||
PROXY_PORT=
|
||||
PROXY_USERNAME= # Можно не ставить, если для прокси авторизация не нужна
|
||||
PROXY_PASSWORD= # Можно не ставить, если для прокси авторизация не нужна
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ name: auto-stars
|
||||
services:
|
||||
auto-stars:
|
||||
image: git.sakamoto.best/lolz/auto-stars:latest
|
||||
user: ${UID:-1000}:${GID:-1000}
|
||||
|
||||
volumes:
|
||||
- ${LOGS_PATH:-./logs}:/app/logs
|
||||
|
||||
+30
-5
@@ -4,6 +4,8 @@ import asyncio
|
||||
from LOLZTEAM.Client import Forum
|
||||
from typing import Dict, Any, Optional, Union, List
|
||||
|
||||
from config import Config
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -26,15 +28,38 @@ class LolzResponseError(LolzAPIError):
|
||||
|
||||
|
||||
class Lolz:
|
||||
def __init__(self, token: str):
|
||||
if not token:
|
||||
def __init__(self, config: Config):
|
||||
if not config.lolz_token:
|
||||
raise ValueError("LOLZ_TOKEN обязателен")
|
||||
|
||||
try:
|
||||
self.client = Forum(token=token, timeout=15)
|
||||
if config.proxy_lolz:
|
||||
if config.proxy_username and config.proxy_password:
|
||||
proxy = f"{config.proxy_protocol}://{config.proxy_username}:{config.proxy_password}@{config.proxy_host}:{config.proxy_port}"
|
||||
logger.info(
|
||||
"Инициализация Lolz клиента с прокси: %s://%s:%s (с авторизацией)",
|
||||
config.proxy_protocol,
|
||||
config.proxy_host,
|
||||
config.proxy_port
|
||||
)
|
||||
else:
|
||||
proxy = f"{config.proxy_protocol}://{config.proxy_host}:{config.proxy_port}"
|
||||
logger.info(
|
||||
"Инициализация Lolz клиента с прокси: %s://%s:%s (без авторизации)",
|
||||
config.proxy_protocol,
|
||||
config.proxy_host,
|
||||
config.proxy_port
|
||||
)
|
||||
|
||||
# ! Не рекомендуется включить этот логгер,
|
||||
# ! ибо логи занимают очень много места в экране при этом логгере
|
||||
self.client = Forum(
|
||||
token=config.lolz_token, proxy=proxy, timeout=config.api_timeout
|
||||
)
|
||||
else:
|
||||
logger.info("Инициализация Lolz клиента без прокси")
|
||||
self.client = Forum(token=config.lolz_token, timeout=config.api_timeout)
|
||||
|
||||
# ! Не рекомендуется включать этот логгер,
|
||||
# ! ибо логи занимают очень много места в экране с этим логгером
|
||||
# self.client.settings.logger.enable()
|
||||
|
||||
except Exception as e:
|
||||
|
||||
+60
-11
@@ -1,10 +1,18 @@
|
||||
import logging
|
||||
|
||||
from aiogram import Bot
|
||||
|
||||
from aiohttp import BasicAuth
|
||||
from aiogram.client.session.aiohttp import AiohttpSession
|
||||
|
||||
from aiogram.enums import ParseMode
|
||||
from aiogram.client.default import DefaultBotProperties
|
||||
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from aiogram.exceptions import TelegramAPIError, TelegramBadRequest, TelegramNetworkError
|
||||
from aiogram.exceptions import (
|
||||
TelegramAPIError,
|
||||
TelegramBadRequest,
|
||||
TelegramNetworkError,
|
||||
)
|
||||
|
||||
from config import Config
|
||||
from typing import Dict, Any, List, Optional
|
||||
@@ -17,14 +25,51 @@ class NotificationBot:
|
||||
self.config = config
|
||||
|
||||
try:
|
||||
self.bot: Bot = Bot(
|
||||
token=config.bot_token,
|
||||
default=DefaultBotProperties(
|
||||
parse_mode=ParseMode.HTML,
|
||||
disable_notification=True,
|
||||
link_preview_is_disabled=True,
|
||||
),
|
||||
)
|
||||
if config.proxy_telegram:
|
||||
proxy = (
|
||||
f"{config.proxy_protocol}://{config.proxy_host}:{config.proxy_port}"
|
||||
)
|
||||
|
||||
if config.proxy_username and config.proxy_password:
|
||||
logger.info(
|
||||
"Инициализация Telegram бота с прокси: %s://%s:%s (с авторизацией)",
|
||||
config.proxy_protocol,
|
||||
config.proxy_host,
|
||||
config.proxy_port
|
||||
)
|
||||
auth = BasicAuth(
|
||||
login=config.proxy_username, password=config.proxy_password
|
||||
)
|
||||
self.session = AiohttpSession(proxy=(proxy, auth))
|
||||
else:
|
||||
logger.info(
|
||||
"Инициализация Telegram бота с прокси: %s://%s:%s (без авторизации)",
|
||||
config.proxy_protocol,
|
||||
config.proxy_host,
|
||||
config.proxy_port
|
||||
)
|
||||
self.session = AiohttpSession(proxy=proxy)
|
||||
|
||||
self.bot: Bot = Bot(
|
||||
token=config.bot_token,
|
||||
default=DefaultBotProperties(
|
||||
parse_mode=ParseMode.HTML,
|
||||
disable_notification=True,
|
||||
link_preview_is_disabled=True,
|
||||
),
|
||||
session=self.session,
|
||||
)
|
||||
else:
|
||||
logger.info("Инициализация Telegram бота без прокси")
|
||||
self.bot: Bot = Bot(
|
||||
token=config.bot_token,
|
||||
default=DefaultBotProperties(
|
||||
parse_mode=ParseMode.HTML,
|
||||
disable_notification=True,
|
||||
link_preview_is_disabled=True,
|
||||
),
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Бот для уведомлений инициализирован (admin_id=%s)", config.admin_id
|
||||
)
|
||||
@@ -33,7 +78,9 @@ class NotificationBot:
|
||||
logger.error(f"Не удалось инициализировать Бот для уведомлений: {e}")
|
||||
raise
|
||||
|
||||
async def _notify(self, message: str, reply_to: int = None, link: str = None) -> Optional[int]:
|
||||
async def _notify(
|
||||
self, message: str, reply_to: int = None, link: str = None
|
||||
) -> Optional[int]:
|
||||
try:
|
||||
logger.debug("Отправка уведомления (reply_to=%s, link=%s)", reply_to, link)
|
||||
keyboard = None
|
||||
@@ -142,7 +189,9 @@ class NotificationBot:
|
||||
logger.error(f"Неожиданная ошибка в success: {e}")
|
||||
return None
|
||||
|
||||
async def failure(self, post: Dict[str, Any], reason: str, post_message_id: int) -> Optional[int]:
|
||||
async def failure(
|
||||
self, post: Dict[str, Any], reason: str, post_message_id: int
|
||||
) -> Optional[int]:
|
||||
try:
|
||||
permalink = post.get("links", {}).get("permalink")
|
||||
logger.warning(
|
||||
|
||||
+39
-30
@@ -53,7 +53,7 @@ class TelegramStarsBot:
|
||||
self.config = config
|
||||
|
||||
self.start_page: int = 1
|
||||
self.lolz_api = Lolz(config.lolz_token)
|
||||
self.lolz_api = Lolz(config=config)
|
||||
self.processed_manager = ProcessedPostsManager()
|
||||
|
||||
self.client: Optional[Client] = None
|
||||
@@ -427,37 +427,46 @@ class TelegramStarsBot:
|
||||
if is_first_login:
|
||||
logger.info("Сессия Telegram не найдена. Запускаю процесс входа...")
|
||||
else:
|
||||
if self.config.default_choice == 2:
|
||||
logger.info("Выбран режим парсинга существующих постов.")
|
||||
self.client = Client(
|
||||
name=self.SESSION_NAME,
|
||||
api_id=self.config.api_id,
|
||||
api_hash=self.config.api_hash,
|
||||
)
|
||||
|
||||
try:
|
||||
await self.client.start()
|
||||
await self.parse_existing_posts()
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при парсинге существующих постов: {e}")
|
||||
raise
|
||||
finally:
|
||||
if self.client and self.client.is_connected:
|
||||
await self.client.stop()
|
||||
|
||||
logger.info(
|
||||
"Парсинг завершен. Все существующие посты добавлены в обработанные."
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
self.start_page = self.config.start_page
|
||||
|
||||
self.client = Client(
|
||||
name=self.SESSION_NAME,
|
||||
api_id=self.config.api_id,
|
||||
api_hash=self.config.api_hash,
|
||||
)
|
||||
if self.config.proxy_telegram:
|
||||
proxy = {
|
||||
"scheme": self.config.proxy_protocol,
|
||||
"hostname": self.config.proxy_host,
|
||||
"port": self.config.proxy_port,
|
||||
}
|
||||
|
||||
if self.config.proxy_username and self.config.proxy_password:
|
||||
logger.info(
|
||||
"Инициализация Pyrogram с прокси: %s://%s:%s (с авторизацией)",
|
||||
self.config.proxy_protocol,
|
||||
self.config.proxy_host,
|
||||
self.config.proxy_port,
|
||||
)
|
||||
|
||||
proxy["username"] = self.config.proxy_username
|
||||
proxy["password"] = self.config.proxy_password
|
||||
else:
|
||||
logger.info(
|
||||
"Инициализация Pyrogram с прокси: %s://%s:%s (без авторизации)",
|
||||
self.config.proxy_protocol,
|
||||
self.config.proxy_host,
|
||||
self.config.proxy_port,
|
||||
)
|
||||
|
||||
self.client = Client(
|
||||
name=self.SESSION_NAME,
|
||||
api_id=self.config.api_id,
|
||||
api_hash=self.config.api_hash,
|
||||
proxy=proxy,
|
||||
)
|
||||
|
||||
else:
|
||||
self.client = Client(
|
||||
name=self.SESSION_NAME,
|
||||
api_id=self.config.api_id,
|
||||
api_hash=self.config.api_hash,
|
||||
)
|
||||
|
||||
try:
|
||||
await self.client.start()
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user