11 Commits

Author SHA1 Message Date
root e9502c7a38 feat(proxy): add http proxy protocol support
Build and Push (dev) / build (push) Successful in 36s
2026-08-16 10:06:38 +05:00
root 31bf50aaca feat(proxy): add proxy support to Telegram client
Build and Push (main) / build (push) Successful in 39s
Build and Push (dev) / build (push) Successful in 35s
2026-08-16 06:36:49 +05:00
root 8423912dbb chore(examples): add UID/GID environment defaults 2026-08-16 06:23:03 +05:00
root 64508438e7 docs(readme): reformat tables and reorg sections
Build and Push (main) / build (push) Successful in 2m33s
2026-08-16 06:02:13 +05:00
root f5cf63bac0 docs: update README with new features and settings 2026-08-16 05:41:19 +05:00
root 37d4400513 refactor(config): remove DEFAULT_CHOICE option
Build and Push (dev) / build (push) Successful in 1m56s
2026-08-16 05:20:24 +05:00
root 5dece14c8b build: update requirements.txt 2026-08-16 05:18:16 +05:00
root 5c325bd8b9 feat(config): add proxy support and API timeout
Build and Push (dev) / build (push) Successful in 3m31s
2026-08-16 05:15:24 +05:00
root 62873c7f8c Delete .gitea/FUNDING.yml 2026-08-12 21:28:27 +00:00
root 4883320aaa Update .gitea/FUNDING.yml 2026-08-12 21:27:51 +00:00
root 0f9d6470b8 Add .gitea/FUNDING.md 2026-08-12 21:27:19 +00:00
9 changed files with 419 additions and 68 deletions
+15 -5
View File
@@ -14,14 +14,11 @@ LOLZ_TOKEN=
LOLZ_THREAD_ID= LOLZ_THREAD_ID=
STARS_COUNT=1 STARS_COUNT=1
# 1 - Начать мониторинг
# 2 - Спарсить все существующие посты
DEFAULT_CHOICE=2
START_PAGE=1 START_PAGE=1
CHECK_INTERVAL=30 CHECK_INTERVAL=10
API_DELAY=5 API_DELAY=5
API_TIMEOUT=15
MAX_RETRIES=3 MAX_RETRIES=3
ENABLE_REPLY=true ENABLE_REPLY=true
@@ -39,3 +36,16 @@ CAPTCHA_ANSWER=40
# Капча будет автоматически обновляться из файла storage/captcha.txt # Капча будет автоматически обновляться из файла storage/captcha.txt
CAPTCHA_CHECK_INTERVAL=1800 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= # Можно не ставить, если для прокси авторизация не нужна
+114 -10
View File
@@ -7,11 +7,15 @@
- Автоматический мониторинг темы на Lolz.team - Автоматический мониторинг темы на Lolz.team
- Отправка Telegram Stars за каждый новый пост - Отправка Telegram Stars за каждый новый пост
- Автоматические ответы с поддержкой шаблонов (включая случайный выбор) - Автоматические ответы с поддержкой шаблонов (включая случайный выбор)
- Автоматическое поднятие темы (bump) с настраиваемым интервалом
- Система капчи для фильтрации пользователей
- Поддержка прокси для Telegram и Lolz API (SOCKS5/HTTPS)
- Полная поддержка Docker (рекомендуется) - Полная поддержка Docker (рекомендуется)
- CI/CD через Gitea Actions (сборка и публикация образов) - CI/CD через Gitea Actions (сборка и публикация образов)
- Уведомления администратору через Telegram - Уведомления администратору через Telegram
- Гибкая настройка через `.env` - Гибкая настройка через `.env`
- Логирование и сохранение сессии - Логирование и сохранение сессии
- Обработка ошибок и повторные попытки
## Требования ## Требования
@@ -23,12 +27,14 @@
## Быстрый старт (Docker — рекомендуется) ## Быстрый старт (Docker — рекомендуется)
1. Клонируйте репозиторий: 1. Клонируйте репозиторий:
```bash ```bash
git clone https://git.sakamoto.best/Lolz/Auto-Stars-Improved.git git clone https://git.sakamoto.best/Lolz/Auto-Stars-Improved.git
cd Auto-Stars-Improved cd Auto-Stars-Improved
``` ```
2. Скопируйте пример конфигурации: 2. Скопируйте пример конфигурации:
```bash ```bash
cp examples/.env.example .env cp examples/.env.example .env
``` ```
@@ -36,6 +42,7 @@
3. Отредактируйте `.env` и заполните необходимые значения (`API_ID`, `API_HASH`, `LOLZ_TOKEN`, `LOLZ_THREAD_ID` и т.д.). 3. Отредактируйте `.env` и заполните необходимые значения (`API_ID`, `API_HASH`, `LOLZ_TOKEN`, `LOLZ_THREAD_ID` и т.д.).
4. Запустите: 4. Запустите:
```bash ```bash
docker compose -f examples/docker-compose.yml up -d docker compose -f examples/docker-compose.yml up -d
``` ```
@@ -61,19 +68,108 @@ python main.py
Все настройки находятся в файле `.env`. Все настройки находятся в файле `.env`.
Пример конфигурации лежит здесь: Пример конфигурации лежит здесь:
- `examples/.env.example` - `examples/.env.example`
**Основные параметры:** ### Основные параметры
| Переменная | Описание | По умолчанию | | Переменная | Описание | По умолчанию |
|-----------------------|-----------------------------------------------|--------------| | --------------------- | ----------------------------------------- | ------------ |
| `API_ID` / `API_HASH` | Данные Telegram API | - | | `API_ID` / `API_HASH` | Данные Telegram API | - |
| `LOLZ_TOKEN` | Токен API Lolz.team | - | | `LOLZ_TOKEN` | Токен API Lolz.team | - |
| `LOLZ_THREAD_ID` | ID темы на форуме | - | | `LOLZ_THREAD_ID` | ID темы на форуме | - |
| `STARS_COUNT` | Сколько звёзд отправлять за пост | 1 | | `STARS_COUNT` | Сколько звёзд отправлять за пост | 1 |
| `DEFAULT_CHOICE` | 1 — реал-тайм, 2 — обработать все посты | 2 | | `START_PAGE` | С какой страницы начинать парсинг | 1 |
| `ENABLE_REPLY` | Отправлять ли комментарии | true | | `ENABLE_REPLY` | Отправлять ли комментарии | true |
| `SKIP_COMMENTED` | Пропускать посты, на которые уже отвечали | 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`. Шаблоны хранятся в файле `storage/replies.txt`.
**Формат:** **Формат:**
- Каждая строка — отдельный шаблон - Каждая строка — отдельный шаблон
- Можно использовать `||` для случайного выбора - Можно использовать `||` для случайного выбора
**Пример:** **Пример:**
``` ```
:catdance: Отправил звёзды || :animeyes2: Отправил :catdance: Отправил звёзды || :animeyes2: Отправил
:sadge: Тут может быть реклама :sadge: Тут может быть реклама
``` ```
Если файл пустой — используется `✓`. Если файл пустой — используется `✓`.
## Поддержка
- Автор: [Дриада](https://lolz.team/members/7272152/)
- Создайте Issue на Gitea: https://git.sakamoto.best/Lolz/Auto-Stars-Improved/issues
- Тема на форуме Lolz.team: https://lolz.team/threads/10187517/
+141 -2
View File
@@ -106,7 +106,6 @@ class Config:
stars_count = int(os.getenv(key="STARS_COUNT", default=1)) stars_count = int(os.getenv(key="STARS_COUNT", default=1))
# Misc # Misc
default_choice = int(os.getenv(key="DEFAULT_CHOICE", default=2))
start_page = max(int(os.getenv(key="START_PAGE", default=1)), 1) start_page = max(int(os.getenv(key="START_PAGE", default=1)), 1)
check_interval = max( check_interval = max(
@@ -115,6 +114,7 @@ class Config:
api_delay = max( api_delay = max(
float(os.getenv(key="API_DELAY", default=5)), 2 float(os.getenv(key="API_DELAY", default=5)), 2
) # 30r/60s для non-GET запросов, 60/30 = минимум ) # 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)) max_retries = int(os.getenv(key="MAX_RETRIES", default=3))
enable_reply = ( enable_reply = (
@@ -145,6 +145,135 @@ class Config:
"ENABLE_CAPTCHA установлен, но CAPTCHA_ANSWER не задан" "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 { return {
# Pyrogram # Pyrogram
"api_id": api_id, "api_id": api_id,
@@ -165,8 +294,8 @@ class Config:
"skip_commented": skip_commented, "skip_commented": skip_commented,
# Misc # Misc
"api_delay": api_delay, "api_delay": api_delay,
"api_timeout": api_timeout,
"max_retries": max_retries, "max_retries": max_retries,
"default_choice": default_choice,
# Bump # Bump
"enable_auto_bump": enable_auto_bump, "enable_auto_bump": enable_auto_bump,
"bump_check_interval": bump_check_interval, "bump_check_interval": bump_check_interval,
@@ -174,13 +303,23 @@ class Config:
"enable_captcha": enable_captcha, "enable_captcha": enable_captcha,
"captcha_answer": captcha_answer, "captcha_answer": captcha_answer,
"captcha_check_interval": captcha_check_interval, "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: except ConfigError:
raise raise
except (ValueError, TypeError) as e: except (ValueError, TypeError) as e:
logger.error(f"Invalid configuration value: {e}") logger.error(f"Invalid configuration value: {e}")
raise ConfigError(f"Invalid configuration value: {e}") from e raise ConfigError(f"Invalid configuration value: {e}") from e
except Exception as e: except Exception as e:
logger.error(f"Unexpected error loading configuration: {e}") logger.error(f"Unexpected error loading configuration: {e}")
raise ConfigError(f"Failed to load configuration: {e}") from e raise ConfigError(f"Failed to load configuration: {e}") from e
+19 -5
View File
@@ -1,6 +1,9 @@
LOGS_PATH=./logs LOGS_PATH=./logs
STORAGE_PATH=./storage STORAGE_PATH=./storage
UID=1000
GID=1000
# Значения для клиента Telegram Desktop, ставятся по умолчанию # Значения для клиента Telegram Desktop, ставятся по умолчанию
# Не рекомендуется оставлять, лучше использовать API_ID и API_HASH от # Не рекомендуется оставлять, лучше использовать API_ID и API_HASH от
# аккаунта с которого будет воспроизведен вход # аккаунта с которого будет воспроизведен вход
@@ -17,14 +20,11 @@ LOLZ_TOKEN=
LOLZ_THREAD_ID= LOLZ_THREAD_ID=
STARS_COUNT=1 STARS_COUNT=1
# 1 - Начать мониторинг
# 2 - Спарсить все существующие посты
DEFAULT_CHOICE=2
START_PAGE=1 START_PAGE=1
CHECK_INTERVAL=30 CHECK_INTERVAL=10
API_DELAY=5 API_DELAY=5
API_TIMEOUT=15
MAX_RETRIES=3 MAX_RETRIES=3
ENABLE_REPLY=true ENABLE_REPLY=true
@@ -42,3 +42,17 @@ CAPTCHA_ANSWER=40
# Капча будет автоматически обновляться из файла storage/captcha.txt # Капча будет автоматически обновляться из файла storage/captcha.txt
CAPTCHA_CHECK_INTERVAL=1800 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= # Можно не ставить, если для прокси авторизация не нужна
+1
View File
@@ -3,6 +3,7 @@ name: auto-stars
services: services:
auto-stars: auto-stars:
image: git.sakamoto.best/lolz/auto-stars:latest image: git.sakamoto.best/lolz/auto-stars:latest
user: ${UID:-1000}:${GID:-1000}
volumes: volumes:
- ${LOGS_PATH:-./logs}:/app/logs - ${LOGS_PATH:-./logs}:/app/logs
+30 -5
View File
@@ -4,6 +4,8 @@ import asyncio
from LOLZTEAM.Client import Forum from LOLZTEAM.Client import Forum
from typing import Dict, Any, Optional, Union, List from typing import Dict, Any, Optional, Union, List
from config import Config
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -26,15 +28,38 @@ class LolzResponseError(LolzAPIError):
class Lolz: class Lolz:
def __init__(self, token: str): def __init__(self, config: Config):
if not token: if not config.lolz_token:
raise ValueError("LOLZ_TOKEN обязателен") raise ValueError("LOLZ_TOKEN обязателен")
try: 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() # self.client.settings.logger.enable()
except Exception as e: except Exception as e:
+60 -11
View File
@@ -1,10 +1,18 @@
import logging import logging
from aiogram import Bot from aiogram import Bot
from aiohttp import BasicAuth
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.enums import ParseMode from aiogram.enums import ParseMode
from aiogram.client.default import DefaultBotProperties from aiogram.client.default import DefaultBotProperties
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup 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 config import Config
from typing import Dict, Any, List, Optional from typing import Dict, Any, List, Optional
@@ -17,14 +25,51 @@ class NotificationBot:
self.config = config self.config = config
try: try:
self.bot: Bot = Bot( if config.proxy_telegram:
token=config.bot_token, proxy = (
default=DefaultBotProperties( f"{config.proxy_protocol}://{config.proxy_host}:{config.proxy_port}"
parse_mode=ParseMode.HTML, )
disable_notification=True,
link_preview_is_disabled=True, 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( logger.info(
"Бот для уведомлений инициализирован (admin_id=%s)", config.admin_id "Бот для уведомлений инициализирован (admin_id=%s)", config.admin_id
) )
@@ -33,7 +78,9 @@ class NotificationBot:
logger.error(f"Не удалось инициализировать Бот для уведомлений: {e}") logger.error(f"Не удалось инициализировать Бот для уведомлений: {e}")
raise 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: try:
logger.debug("Отправка уведомления (reply_to=%s, link=%s)", reply_to, link) logger.debug("Отправка уведомления (reply_to=%s, link=%s)", reply_to, link)
keyboard = None keyboard = None
@@ -142,7 +189,9 @@ class NotificationBot:
logger.error(f"Неожиданная ошибка в success: {e}") logger.error(f"Неожиданная ошибка в success: {e}")
return None 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: try:
permalink = post.get("links", {}).get("permalink") permalink = post.get("links", {}).get("permalink")
logger.warning( logger.warning(
+39 -30
View File
@@ -53,7 +53,7 @@ class TelegramStarsBot:
self.config = config self.config = config
self.start_page: int = 1 self.start_page: int = 1
self.lolz_api = Lolz(config.lolz_token) self.lolz_api = Lolz(config=config)
self.processed_manager = ProcessedPostsManager() self.processed_manager = ProcessedPostsManager()
self.client: Optional[Client] = None self.client: Optional[Client] = None
@@ -427,37 +427,46 @@ class TelegramStarsBot:
if is_first_login: if is_first_login:
logger.info("Сессия Telegram не найдена. Запускаю процесс входа...") logger.info("Сессия Telegram не найдена. Запускаю процесс входа...")
else: 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.start_page = self.config.start_page
self.client = Client( if self.config.proxy_telegram:
name=self.SESSION_NAME, proxy = {
api_id=self.config.api_id, "scheme": self.config.proxy_protocol,
api_hash=self.config.api_hash, "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: try:
await self.client.start() await self.client.start()
BIN
View File
Binary file not shown.