Files
jellybit/openspec/changes/archive/2026-07-18-telegram-download-id-code/tasks.md
T
avandClaude Opus 4.8 4a58b0bda0 tgbot: download id моноширинным (code) для tap-to-copy
Включён HTML parse mode у всех исходящих сообщений бота (send + edit-путь
refreshCard), download id выводится моноширинным <code> — в клиентах Telegram
по нему работает tap-to-copy (скопировать id для /download/{id} или диагностики).
Префикс # / download_id= остаётся вне <code>, чтобы копировался чистый id.

Parse mode делает разметку значимой для всех текстов, поэтому добавлен
escape-хелпер и экранированы все внешние/недоверенные фрагменты: display name,
распознанное название, источник/контекст, целевой путь, причины, provider,
error_code/error_msg (инвариант «выход LLM недоверенный»). esc применяется
последним шагом, после усечения, чтобы обрез не разрубил HTML-сущность.

Capability notifications: два ADDED-требования (формат id + экранирование).
Беклог: задача закрыта, зонтичный telegram-revyu-uvedomleniy обновлён.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 15:17:26 +03:00

2.2 KiB
Raw Blame History

1. Код

  • 1.1 internal/tgbot/render.go: добавить хелпер esc (экранирование внешнего текста для HTML parse mode Telegram) и idCode (обёртка download id в <code> для tap-to-copy)
  • 1.2 internal/tgbot/bot.go: в send() выставить ParseMode = HTML; в refreshCard() выставить ParseMode = HTML на edit-конфиге (оба варианта: с клавиатурой и без)
  • 1.3 Заменить вывод download id на idCode(id) во всех сообщениях (bot.go: pending/принято/дубль/refine/opErr; render.go: карточки, дефолтная ветка renderCard, распознаю/раскладываю, done/failed, renderDesync)
  • 1.4 Экранировать все внешние фрагменты в render.go через esc: display name / распознанное название, источник/контекст, путь плана, причины, provider и provider_id, error_code, error_msg. Не забыть renderDesync (внешний displayTitle уходит в send с HTML). Порядок: esc применяем ПОСЛЕДНИМ шагом — над уже усечённым текстом (после shorten/tailPath/firstLine), иначе обрез посреди сущности &lt; даст битую разметку → Telegram 400 → сообщение не доставится.

2. Тесты

  • 2.1 internal/tgbot/bot_test.go: обновить ожидания текста под <code>-id
  • 2.2 Добавить тест: внешний фрагмент со спецсимволами (</>/&) в уведомлении экранируется (не ломает разметку) — покрыть desync/failed-путь и кейс усечения длинного значения со спецсимволом у границы shorten

3. Спека

  • 3.1 Дельта notifications (два ADDED-требования); openspec validate --strict telegram-download-id-code