Добро пожаловать! Этот проект позволяет получать сообщения от вашей Meshtastic ноды через MQTT брокер и автоматически отправлять их в Telegram. Отлично подходит для мониторинга сети Meshtastic и получения уведомлений прямо в Telegram.
Если вы никогда не работали с Docker или Python - не переживайте! Я постарался сделать установку максимально простой. Следуйте шагам по порядку.
-
Компьютер с установленным Docker (Windows, Mac или Linux)
- Если Docker не установлен, скачайте с официального сайта
- После установки Docker Desktop запустите его и дождитесь полной загрузки
-
Telegram бот (бесплатно, создается за 2 минуты)
- Откройте Telegram и найдите бота @BotFather
- Отправьте команду
/newbotи следуйте инструкциям - Сохраните токен бота (выглядит как
123456789:ABCdefGHIjklMNOpqrsTUVwxyz)
-
Meshtastic нода (уже должна быть настроена и работать)
Откройте терминал (или PowerShell на Windows) и выполните:
git clone <repository-url>
cd Meshtastic_MQTT_botЕсли у вас нет Git, просто скачайте проект как ZIP-архив и распакуйте его.
-
Найдите файл
env.exampleв папке проекта -
Скопируйте его и переименуйте в
.env(точка в начале важна!) -
Откройте файл
.envв любом текстовом редакторе (Блокнот, Notepad++, VS Code - что угодно) -
Заполните обязательные поля:
# Вставьте токен вашего бота (получили от @BotFather)
TELEGRAM_BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrsTUVwxyz
# ID группового чата (пока оставьте пустым, настроим позже)
TELEGRAM_GROUP_CHAT_ID=
# Ваши Telegram ID (можно оставить пустым для доступа всем)
TELEGRAM_ALLOWED_USER_IDS=
# Настройки MQTT брокера (для Docker оставьте как есть)
MQTT_SOURCE_HOST=mosquitto
MQTT_SOURCE_PORT=1883
MQTT_SOURCE_TOPIC=msh/#Важно: Не используйте кавычки вокруг значений! Просто пишите значение после знака =
В терминале (в папке проекта) выполните:
docker-compose up -dЭта команда:
- Скачает необходимые образы (если их еще нет)
- Запустит MQTT брокер (Mosquitto)
- Запустит Telegram бота
- Все будет работать в фоновом режиме
Посмотрите логи бота:
docker-compose logs -f telegram-botВы должны увидеть что-то вроде:
INFO - Инициализация Meshtastic Telegram Bot
INFO - Запуск Meshtastic Telegram Bot
INFO - Успешно подключен к MQTT брокеру
INFO - Приложение запущено и готово к работе
Если видите ошибки - переходите к разделу "Решение проблем" ниже.
- Создайте группу в Telegram (или используйте существующую)
- Добавьте вашего бота в группу
- Дайте боту права администратора (опционально, но рекомендуется)
- Отправьте в группе команду
/get_chat_id - Бот ответит с ID чата (обычно отрицательное число, например
-1001234567890) - Откройте файл
.envи вставьте этот ID:TELEGRAM_GROUP_CHAT_ID=-1001234567890
- Перезапустите бота:
docker-compose restart telegram-bot
Готово! Теперь сообщения от вашей Meshtastic ноды будут приходить в Telegram.
Чтобы нода отправляла данные на ваш MQTT брокер, нужно настроить MQTT в приложении Meshtastic.
На Windows:
- Откройте командную строку (Win+R, введите
cmd) - Выполните:
ipconfig - Найдите "IPv4-адрес" (обычно что-то вроде
192.168.1.100)
На Linux/Mac:
ip addr show # или ifconfig- Откройте приложение Meshtastic на телефоне
- Перейдите в настройки ноды
- Найдите раздел "MQTT" или "Network"
- Включите MQTT
- Укажите:
- MQTT Server:
ВАШ_IP_АДРЕС:1883- Например:
192.168.1.100:1883
- Например:
- MQTT Topic: выберите один из вариантов:
msh- режим ALL (все сообщения - и в группу, и пользователям)msh/group- режим GROUP (только групповые сообщения)msh/private/{ваш_telegram_id}- режим PRIVATE (только личные сообщения)- Узнайте ваш Telegram ID через команду
/idв боте - Например:
msh/private/123456789
- Узнайте ваш Telegram ID через команду
msh/private/{ваш_telegram_id}/group- режим PRIVATE_GROUP (личные + группа)
- Client Proxy Enabled: выключите (если не нужна двусторонняя связь)
- MQTT Server:
- Шифрование: откл. (так как protobuf формат не работает с шифрованием)
- Сохраните настройки
Примечание: Режим работы бота определяется по структуре MQTT топика. Вы можете настроить разные ноды для разных режимов работы.
-
Посмотрите логи Mosquitto:
docker-compose logs -f mosquitto
-
Вы должны увидеть что-то вроде:
New client connected from 192.168.1.50:54321 as !698535e0 -
Если видите ошибки - проверьте:
- Правильно ли указан IP адрес
- Открыт ли порт 1883 в файрволе
- Находятся ли нода и сервер в одной сети Wi-Fi
Давайте разберемся, как устроен этот бот. Не пугайтесь - я объясню простыми словами.
Бот построен по принципу "слоеного пирога" - каждый слой отвечает за свою задачу:
┌─────────────────────────────────────┐
│ Application (Оркестрация) │ ← Управляет всем процессом
├─────────────────────────────────────┤
│ Handlers (Обработчики) │ ← Реагируют на события
├─────────────────────────────────────┤
│ Services (Бизнес-логика) │ ← Обрабатывают данные
├─────────────────────────────────────┤
│ Repositories (Хранилища) │ ← Работают с внешними системами
├─────────────────────────────────────┤
│ Domain (Модели данных) │ ← Описывают структуру данных
└─────────────────────────────────────└
Meshtastic_MQTT_bot/
├── src/ # Весь исходный код
│ ├── application/ # Главный "дирижер" оркестра
│ │ └── app.py # Запускает и останавливает все компоненты
│ │
│ ├── domain/ # Модели данных (как "чертежи")
│ │ └── message.py # Описывает, как выглядит сообщение
│ │
│ ├── repo/ # Работа с внешними системами
│ │ ├── mqtt_repository.py # Читает сообщения из MQTT
│ │ └── telegram_repository.py # Отправляет в Telegram
│ │
│ ├── service/ # Бизнес-логика (обработка данных)
│ │ ├── message_service.py # Парсит MQTT сообщения
│ │ ├── mqtt_proxy_service.py # Пересылает в другие брокеры
│ │ ├── node_cache_service.py # Хранит информацию о нодах
│ │ ├── topic_routing_service.py # Определяет режим работы по топику
│ │ ├── message_processing_strategy.py # Стратегии обработки сообщений
│ │ └── message_grouping_service.py # Группировка сообщений от разных нод
│ │
│ ├── handlers/ # Реагируют на события
│ │ ├── mqtt_handler.py # Обрабатывает MQTT сообщения (legacy)
│ │ ├── telegram_commands.py # Обрабатывает команды бота (/start, /help)
│ │ ├── message_handler_chain.py # Цепочка обработчиков (Chain of Responsibility)
│ │ ├── handler_registry.py # Реестр обработчиков
│ │ ├── handler_factory.py # Фабрика для создания обработчиков
│ │ ├── concrete_handlers.py # Конкретные реализации обработчиков
│ │ └── message_handler_adapter.py # Адаптер для совместимости
│ │
│ └── config.py # Все настройки приложения
│
├── main.py # Точка входа (отсюда все начинается)
├── docker-compose.yml # Настройки Docker
├── Dockerfile # Как собрать образ бота
├── requirements.txt # Список библиотек Python
├── .env # Ваши настройки (создаете сами)
└── mqtt_config.yaml.example # Пример конфигурации MQTT (опционально)
Это "чертежи" данных. Описывают, как выглядят сообщения от Meshtastic.
Класс: MeshtasticMessage
Это основной класс, который описывает сообщение от Meshtastic. Представьте его как форму, которую нужно заполнить.
Основные поля (атрибуты):
topic- откуда пришло сообщение (MQTT топик)from_node- кто отправил (ID ноды, например!698535e0)from_node_name- имя отправителя (например, "NCH.PT.0.63 (Ruslan)")from_node_short- короткое имя (например, "35e0")to_node- кому отправлено (или "Всем" если4294967295)text- текст сообщенияtimestamp- когда отправлено (Unix timestamp)rssi- качество сигнала (чем ближе к 0, тем лучше)snr- отношение сигнал/шумhops_away- сколько раз ретранслировано (0 = прямая доставка)message_type- тип сообщения (text,nodeinfo,position)
Методы:
-
format_for_telegram()- превращает сообщение в красивый текст для Telegram- Добавляет эмодзи
- Форматирует дату и время
- Добавляет ссылку на местоположение (если есть координаты)
- Экранирует HTML для безопасности
-
format_for_telegram_with_grouping()- форматирует сообщение с учетом группировки нод-получателей- Показывает список всех нод, которые получили сообщение
- Опционально показывает время получения каждой нодой
- Отображает качество сигнала для каждой ноды
- Блок "📥 Получено нодами:" расположен над блоком местоположения
-
get_rssi_quality_emoji()- определяет цвет эмодзи по качеству сигнала- 🟢 Отличный (> -80 dBm)
- 🟡 Нормальный (-80 до -100 dBm)
- 🔴 Плохой (-100 до -120 dBm)
- ⚫ Очень плохой (< -120 dBm)
-
get_snr_quality_emoji()- аналогично для SNR
Эти классы работают напрямую с внешними системами - MQTT брокером и Telegram API.
Класс: AsyncMQTTRepository
Отвечает за подключение к MQTT брокеру и получение сообщений.
Методы:
-
connect()- подключается к брокеру- Создает MQTT клиент
- Устанавливает соединение
- Настраивает параметры (username, password, keepalive)
-
disconnect()- отключается от брокера- Корректно закрывает соединение
- Освобождает ресурсы
-
subscribe(topic, qos)- подписывается на топикtopic- на какой топик подписаться (например,msh/#для всех сообщений)qos- уровень качества (0, 1 или 2)
-
publish(topic, payload, qos)- публикует сообщение- Используется прокси-сервисом для пересылки
Как это работает:
- Бот подключается к MQTT брокеру (Mosquitto)
- Подписывается на топик
msh/#(получает все сообщения от Meshtastic) - Когда Meshtastic нода отправляет сообщение, брокер получает его
- Брокер передает сообщение боту
- Бот автоматически определяет формат (JSON или Protobuf) и парсит сообщение
- Бот обрабатывает сообщение и отправляет в Telegram
Класс: AsyncTelegramRepository
Отвечает за отправку сообщений в Telegram.
Методы:
-
send_message(chat_id, text, parse_mode)- отправляет сообщение в чатchat_id- ID чата (группы или пользователя)text- текст сообщенияparse_mode- формат (HTML для ссылок и форматирования)- Возвращает ID отправленного сообщения
-
send_to_group(text)- отправляет в групповой чат- Использует
group_chat_idиз конфигурации - Возвращает ID отправленного сообщения (для группировки)
- Использует
-
send_to_user(user_id, text)- отправляет пользователю в личный чат- Проверяет, разрешен ли пользователь
-
edit_message(chat_id, message_id, text, parse_mode)- редактирует существующее сообщение- Используется для группировки сообщений
- Обновляет текст сообщения, добавляя информацию о новых нодах-получателях
-
edit_group_message(message_id, text)- редактирует сообщение в групповом чате- Удобный метод для редактирования групповых сообщений
-
is_user_allowed(user_id)- проверяет доступ пользователя- Если
allowed_user_idsне задан - разрешает всем - Иначе проверяет, есть ли пользователь в списке
- Если
Здесь происходит обработка данных - парсинг, кэширование, пересылка.
Класс: MessageService
Превращает сырые MQTT сообщения в структурированные объекты. Поддерживает два формата: JSON и Protobuf.
Методы:
parse_mqtt_message(topic, payload)- парсит MQTT сообщение- Принимает топик и данные (байты)
- Автоматически определяет формат по топику и настройке
payload_format - Использует соответствующий парсер (JSON или Protobuf)
- Извлекает информацию о нодах из кэша
- Определяет тип сообщения (
text,nodeinfo,position) - Возвращает объект
MeshtasticMessage
Парсеры:
Бот использует два отдельных парсера для разных форматов:
-
JsonMessageParser- для JSON сообщений- Декодирует UTF-8 текст
- Парсит JSON структуру
- Извлекает поля напрямую из JSON
-
ProtobufMessageParser- для Protobuf сообщений- Декодирует бинарный protobuf через
meshtastic.protobuf.mqtt_pb2 - Определяет тип сообщения по
portnum(TEXT_MESSAGE_APP, NODEINFO_APP, POSITION_APP и т.д.) - Декодирует payload в зависимости от типа:
- Текстовые сообщения - декодирует UTF-8
- Сжатые тексты - распаковывает через Unishox2 (если доступен)
- Nodeinfo - парсит через
mesh_pb2.User - Position - парсит через
mesh_pb2.Position - Telemetry - парсит через
telemetry_pb2.Telemetry - И другие типы по необходимости
- Вычисляет
hops_awayкакhop_start - hop_limit
- Декодирует бинарный protobuf через
Как это работает:
- Получает сырые данные от MQTT брокера
- Определяет формат по топику:
- Топики с
/e/(без/json/) - protobuf формат - Топики с
/json/- JSON формат
- Топики с
- Выбирает соответствующий парсер
- Парсер извлекает данные и определяет тип сообщения
- Если это
nodeinfo- обновляет кэш нод (имена, ID) - Если это
position- обновляет координаты в кэше - Если это
text- извлекает текст и информацию об отправителе - Создает объект
MeshtasticMessageсо всей информацией
Настройка формата:
В .env или mqtt_config.yaml можно указать:
MQTT_SOURCE_PAYLOAD_FORMAT=json- только JSON (по умолчанию)MQTT_SOURCE_PAYLOAD_FORMAT=protobuf- только ProtobufMQTT_SOURCE_PAYLOAD_FORMAT=both- оба формата (может быть дублирование)
Класс: NodeCacheService
Хранит информацию о нодах Meshtastic: имена, координаты, когда обновлялись.
Зачем это нужно:
Meshtastic ноды отправляют разные типы сообщений:
text- текстовые сообщения (часто без полной информации об отправителе)nodeinfo- информация о ноде (имя, ID)position- координаты ноды
Чтобы показывать красивые имена вместо ID, бот кэширует информацию о нодах.
Методы:
-
update_node_info(node_id, longname, shortname)- обновляет информацию о ноде- Всегда обновляет имена в памяти (при получении
nodeinfo) - На диск сохраняет только раз в 3 дня (чтобы не изнашивать диск)
- Используется при получении
nodeinfoсообщений - Важно: Имена обновляются сразу, независимо от интервала сохранения на диск
- Всегда обновляет имена в памяти (при получении
-
update_node_position(node_id, latitude, longitude, altitude)- обновляет координаты- Всегда обновляет в памяти
- На диск сохраняет только раз в 3 дня (чтобы не изнашивать диск)
-
get_node_name(node_id)- получает имя ноды из кэша- Сначала ищет в памяти
- Если не находит - загружает с диска
-
get_node_shortname(node_id)- получает короткое имя -
get_node_position(node_id)- получает координаты ноды
Где хранится:
- В памяти (быстро, но теряется при перезапуске)
- На диске в файле
data/nodes_cache.json(сохраняется между перезапусками)
Структура файла кэша:
{
"nodes": [
{
"node_id": "!698535e0",
"longname": "NCH.PT.0.63 (Ruslan)",
"shortname": "35e0",
"latitude": 55.756899,
"longitude": 52.463371,
"altitude": 125,
"last_updated": "2025-12-10T00:18:00",
"last_position_updated": "2025-12-10T00:18:00"
}
],
"last_saved": "2025-12-10T00:18:00"
}Класс: MessageGroupingService
Группирует сообщения от разных нод с одинаковым message_id в одно Telegram сообщение.
Зачем это нужно:
Когда одно и то же сообщение получают несколько нод, вместо отправки отдельного сообщения для каждой ноды, бот:
- Отправляет одно сообщение при первом получении
- Редактирует это сообщение, добавляя информацию о других нодах-получателях
- Показывает компактный список всех нод, которые получили сообщение
Методы:
get_or_create_group(message_id, telegram_message_id)- получает или создает группу сообщенийadd_received_node(message_id, message, receiver_node_id)- добавляет ноду-получателя в группуis_grouping_active(message_id)- проверяет, активна ли еще группировка (не истек таймаут)cleanup_expired_groups()- удаляет устаревшие группы
Настройки:
message_grouping_enabled- включить/выключить группировку (по умолчаниюtrue)message_grouping_timeout- таймаут группировки в секундах (по умолчанию 30)show_receive_time- показывать время получения каждой нодой (по умолчаниюfalse)
Пример работы:
- Нода A получает сообщение с
message_id=123→ отправляется новое Telegram сообщение - Нода B получает то же сообщение (
message_id=123) → редактируется существующее сообщение, добавляется "Нода B" - Нода C получает то же сообщение → редактируется сообщение, добавляется "Нода C"
- Через 30 секунд (таймаут) новые ноды больше не добавляются
Класс: TopicRoutingService
Определяет режим обработки сообщений на основе структуры MQTT топика.
Поддерживаемые режимы:
ALL- все пакеты (топикmsh)PRIVATE- только личные сообщения (топикmsh/private/{tg_id})GROUP- только групповые сообщения (топикmsh/group)PRIVATE_GROUP- личные + группа (топикmsh/private/{tg_id}/group)
Методы:
detect_mode_from_topic(topic)- определяет режим из топикаset_user_mode(tg_id, mode)- устанавливает режим для пользователя (переопределяет топик)get_user_mode(tg_id)- получает режим пользователяget_effective_mode(topic, tg_id)- определяет итоговый режим (с учетом переопределений)
Как это работает:
- Нода публикует сообщения в определенный топик (например,
msh/private/123456789) - Бот анализирует топик и определяет режим работы
- Сообщение обрабатывается согласно режиму (отправляется в личный чат, в группу, или и туда, и туда)
Класс: MessageProcessingStrategy (абстрактный)
Реализует паттерн Strategy для разных режимов обработки сообщений.
Реализации:
PrivateModeStrategy- обработка в режиме PRIVATE (только личные сообщения)GroupModeStrategy- обработка в режиме GROUP (только групповые сообщения)AllModeStrategy- обработка в режиме ALL (все сообщения)
Методы:
should_process(message)- проверяет, нужно ли обрабатывать сообщениеprocess_message(message, telegram_repo, node_cache_service)- обрабатывает сообщение
Класс: MQTTProxyService
Пересылает сообщения в другие MQTT брокеры (например, в облачный брокер для мониторинга).
Зачем это нужно:
- Отправка данных в облако для анализа
- Синхронизация с другими системами
- Резервное копирование сообщений
Класс: MQTTProxyTarget
Представляет один целевой брокер для прокси.
Методы:
connect()- подключается к целевому брокеруdisconnect()- отключаетсяpublish_message(message)- публикует сообщение
Класс: MQTTProxyService
Управляет несколькими целевыми брокерами.
Методы:
-
start()- подключается ко всем брокерам параллельно- Использует
asyncio.gather()для одновременного подключения - Если один брокер недоступен - остальные все равно подключатся
- Использует
-
stop()- отключается от всех брокеров параллельно -
proxy_message(message)- пересылает сообщение во все брокеры параллельно- Это ключевое улучшение! Все брокеры получают сообщение одновременно
- Если один брокер медленный - остальные не ждут
Пример работы:
До улучшения (последовательно):
- Брокер 1: 100 мс
- Брокер 2: 100 мс
- Брокер 3: 100 мс
- Итого: 300 мс
После улучшения (параллельно):
- Все брокеры одновременно: 100 мс
- Итого: 100 мс (в 3 раза быстрее!)
Эти классы реагируют на события - приход MQTT сообщений или команд в Telegram.
Класс: MQTTMessageHandlerImpl
Старая реализация обработчика MQTT сообщений. Сохранена для обратной совместимости.
Новая архитектура обработчиков:
Бот использует паттерны Chain of Responsibility, Strategy, Registry и Factory для гибкой обработки сообщений:
-
Handler Chain (
message_handler_chain.py) - цепочка обработчиков- Каждый обработчик может обработать сообщение или передать следующему
- Порядок обработки определяется приоритетом
-
Handler Registry (
handler_registry.py) - реестр обработчиков- Централизованное управление обработчиками
- Легко добавлять новые обработчики
-
Handler Factory (
handler_factory.py) - фабрика обработчиков- Создает цепочку обработчиков из конфигурации
- Инжектирует зависимости
-
Concrete Handlers (
concrete_handlers.py) - конкретные реализацииProxyHandler- пересылка в другие брокерыTelegramHandler- отправка в Telegram
Как это работает:
- Сообщение приходит от MQTT брокера
- Определяется режим работы через
TopicRoutingService(по топику) - Выбирается стратегия обработки (
MessageProcessingStrategy) - Сообщение проходит через цепочку обработчиков:
ProxyHandler- пересылает в другие брокеры (если режим не PRIVATE)TelegramHandler- отправляет в Telegram согласно стратегии
- Если включена группировка (
message_grouping_enabled=true):- Сообщения с одинаковым
message_idгруппируются - Первое сообщение отправляется как новое
- Последующие редактируют существующее сообщение, добавляя информацию о новых нодах-получателях
- Сообщения с одинаковым
Режимы работы:
- PRIVATE (
msh/private/{tg_id}) - только личные сообщения пользователю - GROUP (
msh/group) - только групповые сообщения - ALL (
msh) - все сообщения (и в группу, и пользователям) - PRIVATE_GROUP (
msh/private/{tg_id}/group) - личные + группа
Фильтрация сообщений:
- В Telegram отправляются только сообщения типа
text nodeinfoиpositionобрабатываются для кэша, но не отправляются- Это работает для обоих форматов (JSON и Protobuf)
Класс: TelegramCommandsHandler
Обрабатывает команды, которые пользователи отправляют боту в личном чате.
Доступные команды:
/start- приветствие и краткая информация/help- справка по всем командам/status- текущий статус бота- Подключен ли к MQTT
- Работает ли Telegram polling
- Количество прокси-брокеров
/info- детальная информация- ID группового чата
- Разрешенные пользователи
- Настройки MQTT прокси
/get_chat_id- получить ID текущего чата/id- получить ваш Telegram ID и пример приватного топика- Показывает ваш user_id, username, имя
- Выводит пример топика для приватного режима (например,
msh/private/123456789)
/mode- управление режимом работы бота- Просмотр текущего режима
- Установка режима для пользователя (переопределяет режим из топика)
Контроль доступа:
Перед обработкой команды проверяется, разрешен ли пользователь:
- Если
TELEGRAM_ALLOWED_USER_IDSне задан - доступ у всех - Если задан - только указанные пользователи
Метод: register_handlers(bot)
Регистрирует все обработчики команд в боте.
Это "дирижер оркестра" - управляет всеми компонентами.
Класс: MeshtasticTelegramBotApp
Собирает все компоненты вместе и управляет жизненным циклом приложения.
Что делает при инициализации:
- Загружает конфигурацию
- Создает все сервисы:
MQTTRepository- для работы с MQTTTelegramRepository- для работы с TelegramMessageService- для парсинга сообщенийNodeCacheService- для кэша нодMQTTProxyService- для пересылкиMQTTMessageHandler- для обработки MQTTTelegramCommandsHandler- для команд
Методы:
-
start()- запускает приложение- Подключается к MQTT брокеру
- Подписывается на топик
- Запускает Telegram polling (получение команд)
- Запускает прокси-сервис
- Запускает обработку MQTT сообщений в фоне
-
stop()- останавливает приложение- Останавливает Telegram polling
- Отключается от MQTT
- Останавливает прокси-сервис
- Корректно закрывает все соединения
-
run_forever()- запускает и работает до получения сигнала остановки- Обрабатывает сигналы (Ctrl+C, SIGTERM)
- Корректно завершает работу
Асинхронные задачи:
_subscribe_task- обрабатывает входящие MQTT сообщения_telegram_polling_task- обрабатывает команды Telegram
Здесь хранятся все настройки приложения.
MQTTBrokerConfig - настройки основного MQTT брокера (источник данных)
host- адрес брокера (mosquittoдля Docker,localhostдля локального запуска)port- порт (обычно 1883)username/password- для аутентификации (если требуется)topic- топик для подписки (msh/#для всех сообщений)client_id- идентификатор клиентаqos- уровень качества (0, 1 или 2)
MQTTProxyTargetConfig - настройки одного прокси-брокера
name- имя (для логирования)host/port- адрес целевого брокераusername/password- аутентификацияtopic_prefix- префикс для топика (опционально)enabled- включен ли этот проксиqos- уровень качестваtls- использовать TLS/SSL соединение (обычноtrueдля порта 8883)tls_insecure- отключить проверку сертификата (только для самоподписанных сертификатов, не рекомендуется для продакшена)
TelegramConfig - настройки Telegram бота
bot_token- токен бота (обязательно)group_chat_id- ID группового чата (опционально)group_topic_id- ID темы в группе для форумов (опционально)allowed_user_ids- список разрешенных пользователей (опционально)show_receive_time- показывать время получения каждой нодой в группированных сообщениях (по умолчаниюfalse)message_grouping_enabled- включить группировку сообщений поmessage_id(по умолчаниюtrue)message_grouping_timeout- таймаут группировки в секундах (по умолчанию 30)
MessageProcessingConfig - настройки обработки сообщений
default_mode- режим обработки по умолчанию:private,group,all(по умолчаниюgroup)group_mode_send_to_users- отправлять личные сообщения в режиме GROUP (по умолчаниюfalse)handlers- конфигурация обработчиков (порядок и приоритет)
AppConfig - главная конфигурация
Собирает все настройки вместе.
Методы:
-
load_from_yaml(yaml_path)- загружает конфигурацию из YAML файла- Если файл не найден - использует
.env - Если файл найден - объединяет с
.env(переменные окружения имеют приоритет)
- Если файл не найден - использует
-
setup_logging()- настраивает логирование
Создайте файл .env в корне проекта и заполните настройки (см. env.example).
Преимущества:
- Просто и понятно
- Подходит для одного прокси-брокера
Недостатки:
- Неудобно для множественных прокси-брокеров
Создайте файл mqtt_config.yaml на основе mqtt_config.yaml.example.
Преимущества:
- Удобно для множественных прокси-брокеров
- Структурированная конфигурация
- Легко добавлять/удалять брокеры
Пример:
mqtt_source:
host: mosquitto
port: 1883
topic: msh/#
payload_format: json # json | protobuf | both
qos: 1
mqtt_proxy_targets:
- name: cloud_broker
host: cloud.mqtt.example.com
port: 1883
username: user1
password: pass1
enabled: true
qos: 1
tls: false # Обычный MQTT (порт 1883)
- name: secure_broker
host: secure.mqtt.example.com
port: 8883 # Стандартный порт для MQTT over TLS
username: user2
password: pass2
enabled: true
qos: 1
tls: true # Включить TLS для порта 8883
tls_insecure: false # Проверять сертификат (рекомендуется)
- name: internal_broker
host: internal.mqtt.local
port: 8883
enabled: true
qos: 1
tls: true
tls_insecure: true # Отключить проверку для самоподписанного сертификатаПриоритет настроек:
- Переменные окружения (
.env) - наивысший приоритет - YAML файл - средний приоритет
- Значения по умолчанию - низкий приоритет
Ошибка: "TELEGRAM_BOT_TOKEN не задан"
Решение:
- Проверьте, что файл
.envсуществует - Убедитесь, что токен указан правильно (без кавычек)
- Пересоберите контейнер:
docker-compose build telegram-bot && docker-compose up -d
Проверьте:
-
Нода подключена к брокеру?
docker-compose logs mosquitto | grep "New client connected"
Должны увидеть подключение вашей ноды.
-
Правильный IP адрес?
- В настройках ноды должен быть IP вашего сервера
- Нода и сервер должны быть в одной сети Wi-Fi
-
Правильный топик?
- В ноде:
msh(без решетки - подписка на все сообщения) - В боте:
msh/№(с решеткой - получает все сообщения) - Бот автоматически определяет формат (JSON или Protobuf) по топику
- В ноде:
-
Порт открыт?
- Проверьте файрвол
- Убедитесь, что порт 1883 доступен
-
Бот добавлен в группу?
- Добавьте бота в группу
- Дайте права администратора
-
Правильный ID чата?
- Используйте команду
/get_chat_idв группе - Убедитесь, что ID отрицательный (начинается с
-)
- Используйте команду
-
Проверьте логи:
docker-compose logs -f telegram-bot
Ищите ошибки отправки сообщений.
-
Прокси включен?
- Проверьте
MQTT_PROXY_TARGET_ENABLED=trueв.env - Или
enabled: trueв YAML
- Проверьте
-
Брокер доступен?
- Проверьте адрес и порт
- Убедитесь, что брокер работает
-
Проверьте логи:
docker-compose logs telegram-bot | grep proxy
Если вы изменили код и хотите применить изменения:
# Остановить контейнеры
docker-compose down
# Пересобрать образ бота
docker-compose build telegram-bot
# Запустить заново
docker-compose up -d
# Или одной командой:
docker-compose up --build -dЛоги бота:
docker-compose logs -f telegram-botЛоги MQTT брокера:
docker-compose logs -f mosquittoВсе логи:
docker-compose logs -fВ файле .env можно настроить уровень логирования:
LOG_LEVEL=DEBUG # Показывает все, включая отладочную информацию
LOG_LEVEL=INFO # Обычная информация (по умолчанию)
LOG_LEVEL=WARNING # Только предупреждения и ошибки
LOG_LEVEL=ERROR # Только ошибкиСтатус контейнеров:
docker-compose psHealth checks: Docker автоматически проверяет здоровье контейнеров. Если контейнер нездоров - он будет перезапущен.
# Запустить
docker-compose up -d
# Остановить
docker-compose down
# Перезапустить
docker-compose restart telegram-bot
# Просмотр логов
docker-compose logs -f telegram-bot
# Пересобрать
docker-compose build telegram-bot
# Остановить и удалить все (включая данные)
docker-compose down -vКэш нод хранится в data/nodes_cache.json. Вы можете:
- Просмотреть содержимое (текстовым редактором)
- Удалить для сброса кэша
- Вручную отредактировать (не рекомендуется)
-
Не публикуйте
.envфайл- Он содержит секреты (токены, пароли)
- Уже добавлен в
.gitignore
-
Не публикуйте
mqtt_config.yaml- Может содержать пароли
- Уже добавлен в
.gitignore
-
Используйте сильные пароли
- Для MQTT брокера (если требуется)
- Для прокси-брокеров
-
Ограничьте доступ
- Настройте
TELEGRAM_ALLOWED_USER_IDS - Не давайте всем доступ к командам бота
- Настройте
-
Файрвол
- Откройте только необходимые порты (1883 для MQTT)
- Ограничьте доступ к порту 1883 только вашей локальной сети
Q: Сколько прокси-брокеров можно добавить?
A: Неограниченно! Добавляйте столько, сколько нужно.
Q: Можно ли использовать без Docker?
A: Да, но нужно установить Python 3.11+ и все зависимости. См. раздел "Локальная установка" в старом README.
Q: Как часто обновляется кэш нод?
A: Имена нод (longname, shortname) всегда обновляются в памяти при получении nodeinfo. На диск сохраняются раз в 3 дня (чтобы не изнашивать диск). Координаты обновляются в памяти всегда, на диск - раз в 3 дня.
Q: Что такое группировка сообщений?
A: Когда одно и то же сообщение получают несколько нод, бот группирует их в одно Telegram сообщение. Вместо нескольких отдельных сообщений вы видите одно с компактным списком всех нод-получателей. Можно включить/выключить через TELEGRAM_MESSAGE_GROUPING_ENABLED.
Q: Как работают режимы работы бота?
A: Бот определяет режим работы по структуре MQTT топика:
msh- режим ALL (все сообщения)msh/private/{tg_id}- режим PRIVATE (только личные)msh/group- режим GROUP (только группа)msh/private/{tg_id}/group- режим PRIVATE_GROUP (личные + группа)
Вы можете переопределить режим через команду /mode в Telegram.
Q: Почему не все сообщения попадают в Telegram?
A: В Telegram отправляются только сообщения типа text. Технические сообщения (nodeinfo, position) обрабатываются для кэша, но не отправляются. Это работает для обоих форматов - JSON и Protobuf. Также сообщения могут не отправляться в зависимости от режима работы (PRIVATE/GROUP/ALL) и настроек обработки.
Q: Какой формат сообщений использовать - JSON или Protobuf?
A: По умолчанию используется JSON (payload_format=json). Protobuf более компактный, но требует дополнительных зависимостей. Можно использовать оба формата одновременно (payload_format=both), но это может привести к дублированию сообщений, так как Meshtastic часто отправляет один и тот же пакет в обоих форматах.
Q: Можно ли изменить формат сообщений?
A: Да, отредактируйте метод format_for_telegram() в файле src/domain/message.py.
Q: Как добавить новый прокси-брокер?
A: Добавьте новую запись в mqtt_config.yaml в секцию mqtt_proxy_targets или используйте переменные окружения с другим префиксом.
Проект использует следующие паттерны проектирования для обеспечения гибкости и расширяемости:
Различные стратегии обработки сообщений (MessageProcessingStrategy):
PrivateModeStrategy- обработка личных сообщенийGroupModeStrategy- обработка групповых сообщенийAllModeStrategy- обработка всех сообщений
Цепочка обработчиков (MessageHandler):
- Каждый обработчик может обработать сообщение или передать следующему
- Порядок определяется приоритетом из конфигурации
Централизованный реестр обработчиков (HandlerRegistry):
- Упрощает добавление новых обработчиков
- Единая точка регистрации
Фабрика для создания обработчиков и стратегий (HandlerFactory):
- Инкапсулирует логику создания объектов
- Упрощает управление зависимостями
Адаптер для совместимости (MessageHandlerAdapter):
- Адаптирует новую архитектуру обработчиков к существующему интерфейсу
Если вы хотите улучшить проект:
- Добавьте фильтрацию сообщений (по отправителю, содержимому)
- Реализуйте дополнительные команды для управления ботом через Telegram
- Добавьте метрики и мониторинг (Prometheus, Grafana)
- Создайте веб-интерфейс для управления
- Добавьте поддержку других протоколов (например, HTTP API)
- Расширьте группировку сообщений (например, группировка по времени)
См. файл LICENSE
Спасибо всем, кто использует этот проект! Если у вас есть вопросы или предложения - создавайте Issues в репозитории.
Удачной работы с Meshtastic! 📡