fix: файлы своего Bot API сервера без TELEGRAM_FILES_URL и токен в ошибке
Без TELEGRAM_FILES_URL адрес скачивания был голым путем, а текст ошибки с путем (в нем токен бота) уходил в чат. Теперь сайт не стартует без TELEGRAM_FILES_URL при заданном TELEGRAM_API_URL, а в ошибке скачивания только тип исключения. env_example: 127.0.0.1 вместо localhost, чтобы не пробовать ::1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a90c265ff3
commit
803a6bf9f2
4 files changed
+34
-6
No files matched your search
+3
-3
@@ -2,11 +2,11 @@
|
||||
TG_APP_ID=
|
||||
TG_APP_HASH=
|
||||
# Адрес своего Bot API сервера для Django. Пусто - api.telegram.org
|
||||
TELEGRAM_API_URL=http://localhost:8081
|
||||
TELEGRAM_API_URL=http://127.0.0.1:8081
|
||||
# Файлы, присланные ботам документами (сервис telegram-files): свой Bot API сервер не отдает их по HTTP
|
||||
TELEGRAM_FILES_URL=http://localhost:8083
|
||||
TELEGRAM_FILES_URL=http://127.0.0.1:8083
|
||||
# Адрес сайта для webhook ботов, как его видит Bot API сервер (он в сети хоста, network_mode: host)
|
||||
TELEGRAM_WEBHOOK_URL=http://localhost:8000
|
||||
TELEGRAM_WEBHOOK_URL=http://127.0.0.1:8000
|
||||
# Хосты сайта через запятую, в том числе хост из TELEGRAM_WEBHOOK_URL
|
||||
ALLOWED_HOSTS=127.0.0.1,localhost
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ class Shop(Interface):
|
||||
3. Отдельный процесс не нужен: обновления принимает сайт. Смена интерфейса применяется без перезапуска.
|
||||
|
||||
`TELEGRAM_API_URL` направляет бота на свой Bot API сервер (сервис `telegram` в `docker-compose.yaml`).
|
||||
`TELEGRAM_FILES_URL` - раздача файлов своего Bot API сервера (сервис `telegram-files`). В `--local` режиме сервер не отдает файлы по HTTP, а пишет их в свою папку (`api.WORK_DIR`) с правами 0600 от uid 101. Рядом с ним работает nginx, воркеры которого тоже от uid 101: он отдает только `documents/` и слушает только локальный адрес.
|
||||
`TELEGRAM_FILES_URL` - раздача файлов своего Bot API сервера (сервис `telegram-files`). В `--local` режиме сервер не отдает файлы по HTTP, а пишет их в свою папку (`api.WORK_DIR`) с правами 0600 от uid 101. Рядом с ним работает nginx, воркеры которого тоже от uid 101: он отдает только `documents/` и слушает только локальный адрес. При заданном `TELEGRAM_API_URL` переменная обязательна: без нее сайт не запустится (`ImproperlyConfigured`).
|
||||
|
||||
`TELEGRAM_WEBHOOK_URL` - адрес сайта, как его видит Bot API сервер, к нему дописывается путь webhook. Сервер в docker запущен с `--local` (`TELEGRAM_LOCAL`), поэтому webhook может быть на http и на любом порту. Хост из этого адреса нужно добавить в `ALLOWED_HOSTS`.
|
||||
|
||||
|
||||
+12
-2
@@ -1,8 +1,13 @@
|
||||
import logging
|
||||
|
||||
import requests
|
||||
import telebot
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from telebot import apihelper
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def configure_api_server():
|
||||
"""Направляет pyTelegramBotAPI на свой инстанс Bot API сервера, если он задан в TELEGRAM_API_URL."""
|
||||
@@ -10,7 +15,10 @@ def configure_api_server():
|
||||
url = settings.TELEGRAM_API_URL.rstrip('/')
|
||||
apihelper.API_URL = url + '/bot{0}/{1}'
|
||||
# в --local режиме сервер файлы не отдает, их раздает TELEGRAM_FILES_URL по пути внутри WORK_DIR
|
||||
apihelper.FILE_URL = getattr(settings, 'TELEGRAM_FILES_URL', '').rstrip('/') + '{1}'
|
||||
files_url = getattr(settings, 'TELEGRAM_FILES_URL', '')
|
||||
if not files_url:
|
||||
raise ImproperlyConfigured('TELEGRAM_API_URL is set, so TELEGRAM_FILES_URL is required')
|
||||
apihelper.FILE_URL = files_url.rstrip('/') + '{1}'
|
||||
|
||||
|
||||
CLOUD_API_URL = 'https://api.telegram.org'
|
||||
@@ -62,7 +70,9 @@ def download_file(api: telebot.TeleBot, file_id: str, max_size: int) -> bytes:
|
||||
except ApiError:
|
||||
raise
|
||||
except Exception as error:
|
||||
raise ApiError(f'download: {error}') from error
|
||||
# путь к файлу и URL содержат токен бота: текст ошибки уходит в чат, поэтому подробности только в лог
|
||||
logger.exception('Failed to download file %s', file_id)
|
||||
raise ApiError(f'download: {type(error).__name__}') from error
|
||||
if len(content) > max_size:
|
||||
raise FileTooLarge(f'file is larger than {max_size} bytes')
|
||||
return content
|
||||
@@ -194,6 +194,24 @@ class DocumentTests(TestCase):
|
||||
'http://127.0.0.1:8083/1:t/documents/file_0.zip',
|
||||
)
|
||||
|
||||
@override_settings(TELEGRAM_API_URL='http://127.0.0.1:8081', TELEGRAM_FILES_URL='')
|
||||
def test_own_server_requires_file_url(self):
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from telebot import apihelper
|
||||
|
||||
with mock.patch.object(apihelper, 'API_URL', None), mock.patch.object(apihelper, 'FILE_URL', None):
|
||||
with self.assertRaises(ImproperlyConfigured):
|
||||
bot_api.configure_api_server()
|
||||
|
||||
@override_settings(TELEGRAM_API_URL='http://127.0.0.1:8081')
|
||||
def test_download_error_hides_token(self):
|
||||
api = mock.Mock()
|
||||
api.get_file.return_value = SimpleNamespace(file_path=f'{bot_api.WORK_DIR}/1:secret/documents/a.zip', file_size=1)
|
||||
api.download_file.side_effect = ValueError('No connection adapters were found for /1:secret/documents/a.zip')
|
||||
with self.assertLogs('Telegram.api', 'ERROR'), self.assertRaises(bot_api.ApiError) as raised:
|
||||
bot_api.download_file(api, 'id', 10)
|
||||
self.assertNotIn('secret', str(raised.exception))
|
||||
|
||||
|
||||
@override_settings(TELEGRAM_WEBHOOK_URL='http://localhost:8000/')
|
||||
class PublishTests(TestCase):
|
||||
|
||||
Reference in new issue
Block a user