Имя автора из MeshCore в Telegram (room-server + каналы) + экранирование HTML - #19
Merged
Conversation
Перед проектированием граничного решения сперва ресёрч того, что уже умеет библиотека (её функции/кэши/события), и только если фреймворк — слабое место, лезть в протокол. Слабые места фиксировать явно. Дистиллировано из разбора room-server атрибуции автора: резолв оказался встроенным (get_contact_by_key_prefix + ensure_contacts), а не поводом писать свой стор. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Room-server CONTACT_MSG_RECV несёт автора структурным полем signature (4-байтовый префикс ключа автора), а не в тексте, как каналы. Подтверждено реальным пейлоадом: txt_type=2, signature присутствует, text чистый. Было: display_name = pubkey_prefix КОМНАТЫ (не автор), и telegram send() ронял display_name для LoRa -> имени автора в Telegram не видно. Стало: - transport держит кэш контактов фреймворка свежим (auto_update_contacts + ensure_contacts) и прокидывает резолвер автора (get_contact_by_key_prefix) в RX-путь через route_rx/try_rx; - room_server_to_message резолвит signature -> adv_name, fallback на hex-префикс; - telegram send() унифицирован: bridge — как есть, каналы (пустой display_name) — passthrough, всё с именем (TG-юзер ИЛИ room-server автор) — жирным префиксом. Каналы пока без изменений (имя у них в тексте) — унификация display_name для каналов отдельным коммитом (задевает LoRa->LoRa relay). Closes LoRa-Bridge-fhb Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Каналы несут автора в тексте как 'Имя: текст' (отдельного поля в CHANNEL_MSG_RECV нет). Выносим его в sender.display_name, как у room-server, чтобы Telegram рисовал автора единообразно (жирным). channel_util.split_author режет по ПЕРВОМУ ': '; channel_to_message кладёт имя в display_name, тело чистит. Ripple-эффекты переноса автора из text в display_name (важно — закрыты тестами): - dedup: ключ был transport_uid+text, но у всех mesh-отправителей transport_uid одинаков (LORA_SENDER_UID) — имя в тексте было единственным различителем. Добавили display_name в ключ, иначе разные авторы с одинаковым телом схлопывались бы в дубль. - relay (LoRa->LoRa): форвардил src.text как есть, что теперь потеряло бы автора. transform.relay_lora_text восстанавливает его как '[ник] текст' — скобки, а не 'ник: текст', чтобы обратный split_author не распарсил и loop-guard эха не сломался (закреплено cross-module тестом echo-safety). Closes LoRa-Bridge-06q Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Контракт relay изменился вместе с переносом автора из text в display_name: relay восстанавливает '[ник] текст' (relay_lora_text), а не форвардит как есть. Старый текст про «без ре-префикса» устарел. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
send() ставил parse_mode=HTML безусловно и интерполировал display_name и msg.text без экранирования — любой <, & или незакрытый тег из эфира/чата ронял send_message (HTML-парсер Telegram), и сообщение терялось. - bold-ветка: html.escape() на имя и тело; - passthrough-ветка (bridge/каналы): без parse_mode (plain) — тело не интерпретируется как HTML. HTML оставлен осознанно: escape-набор минимален (<>&, есть html.escape), MarkdownV2 потребовал бы экранировать ~18 символов в каждом теле. Closes LoRa-Bridge-ozt Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ensure_contacts подтверждён на железе (имя автора room-server и канала видно в Telegram). Тестовые config.room.yaml / config.channel.yaml — в .gitignore (реальные chat id / pubkey / secret). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Проблема
В Telegram не было видно имени ноды-автора сообщений из MeshCore (началось с room-server).
Корень (подтверждён реальным пейлоадом)
Имя автора в MeshCore доставляется по-разному, и мост это не учитывал:
CHANNEL_MSG_RECV): поля автора в кадре нет вообще — имя едет в тексте как"Имя: текст".CONTACT_MSG_RECV,txt_type=2): автор едет структурным полемsignature= 4-байтовый префикс ключа автора (pubkey_prefix— это ключ КОМНАТЫ, не автора). Текст — чистый.При этом
meshcore_pyRX-событие именем не обогащает, а telegramsend()для LoRa-источников вообще ронялdisplay_name.Что сделано
70ac208): резолвsignature → adv_nameчерез встроенныйmc.get_contact_by_key_prefix(+ кэш контактов свежим черезensure_contacts/auto_update_contacts), fallback на hex-префикс. Унифицирован telegramsend(): bridge — как есть, каналы (пустойdisplay_name) — passthrough, всё с именем — жирным префиксом.105bcd9):split_authorвыносит"Имя: текст"вdisplay_name. Ripple-фиксы (закрыты тестами): dedup-ключ получилdisplay_name(у всех mesh-отправителей общийLORA_SENDER_UID), а LoRa↔LoRa relay восстанавливает автора в echo-safe скобочном формате[ник] текст.bd25023):send()ставилparse_mode=HTMLбезусловно без экранирования — любой</&из эфира ронял отправку. Теперьhtml.escapeв bold-ветке, plain без parse_mode в passthrough.d831557,bfb6695): принцип «фреймворк-first» + актуализация §12.1.Проверка
🤖 Generated with Claude Code