Skip to content

feat: add message_tts parameter + fix parse_mode for notify channels#21

Open
jokerigno wants to merge 2 commits into
jumping2000:mainfrom
jokerigno:main
Open

feat: add message_tts parameter + fix parse_mode for notify channels#21
jokerigno wants to merge 2 commits into
jumping2000:mainfrom
jokerigno:main

Conversation

@jokerigno
Copy link
Copy Markdown

Summary

This PR adds two improvements identified while testing migration from the AppDaemon Package-Notification-HUB.

1. New message_tts parameter

Adds an optional message_tts field to the send service. When provided, voice channels (Google Home, Alexa) use this text instead of message, while text channels (Telegram, Mobile App) continue to use message.

This allows sending emoji/markdown-rich text to Telegram and clean, readable speech to speakers from a single service call — a common pattern in the AppDaemon Notifier ecosystem.

Example:

action: universal_notifier.send
data:
  message: "✅ R2D2 ha finito le pulizie! Batteria: 85% 🤖"
  message_tts: "R2D2 ha terminato le pulizie. Batteria all ottantacinque percento."
  targets:
    - telegram_user   # receives the emoji-rich text
    - google_home     # speaks the clean TTS text

Also supported per-target via target_data[alias][message_tts]. Falls back to message if not provided.

2. Fix: pass parse_mode to notify services

The parse_mode used to format the message (HTML or MarkdownV2) was being stripped before the notify.* service call. This caused Telegram to silently reject messages when the bot's default parse_mode (e.g. markdownv2) did not match the tags in the formatted text (e.g. <b> HTML tags from bold_prefix).

parse_mode is now injected into service_payload["data"] for non-voice notify channels so Telegram renders formatting correctly.

Testing

Tested on a live Home Assistant instance with:

  • notify.telegrammarco channel (telegram_bot configured with parse_mode: markdownv2)
  • HTML bold prefix enabled
  • Both message and message_tts fields

Before fix: messages silently dropped by Telegram due to parse_mode mismatch. After fix: messages received correctly with formatting rendered.

Marco Ragonesi added 2 commits April 29, 2026 23:42
Adds an optional message_tts field to the send service schema.
When provided, voice channels (Google Home, Alexa) use message_tts
instead of message, while text channels (Telegram, Mobile App) keep
using message. Falls back to message if message_tts is not set.

Also supported per-target via target_data[alias][message_tts].

Use case: send emoji/markdown-rich text to Telegram while sending
clean, readable speech to voice assistants from a single service call.

Example:
  action: universal_notifier.send
  data:
    message: '✅ R2D2 ha finito! Batteria: 85% 🤖'
    message_tts: 'R2D2 ha terminato le pulizie. Batteria all ottantacinque percento.'
    targets: [telegram, google_home]
When building text messages with HTML or MarkdownV2 formatting,
the parse_mode was stripped before reaching the notify service call.
This caused Telegram to reject messages silently when the bot's
default parse_mode (e.g. markdownv2) didn't match the tags in the
formatted text (e.g. <b> HTML tags).

Now parse_mode is injected into service_payload['data'] for notify
channels so Telegram renders formatting correctly.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the universal_notifier.send Home Assistant service to better support mixed text + voice notification setups, and fixes Telegram formatting delivery for notify.* channels by correctly propagating parse_mode.

Changes:

  • Added optional message_tts service input (and per-target override) so voice channels can speak different text than what text channels display.
  • Fixed parse_mode propagation for non-voice notify.* calls by injecting it into service_payload["data"].

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
custom_components/universal_notifier/const.py Introduces CONF_MESSAGE_TTS constant for the new service parameter.
custom_components/universal_notifier/__init__.py Extends the send service schema and routing logic to support message_tts, and ensures parse_mode is passed to notify.* payloads.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 123 to 129
SEND_SERVICE_SCHEMA = vol.Schema({
vol.Required(CONF_MESSAGE): cv.string,
vol.Required(CONF_TARGETS): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_MESSAGE_TTS): cv.string,
vol.Optional(CONF_TITLE): cv.string,
vol.Optional(CONF_DATA): dict,
vol.Optional(CONF_TARGET_DATA): dict,
@jokerigno
Copy link
Copy Markdown
Author

Aggiungo un commento:

Migrando a Universal Notifier per inviare notifiche contemporaneamente su Telegram e su speaker Google (via tts.speak). Ho notato che il campo title: è globale: viene applicato a tutti i canali indistintamente.

Comportamento attuale:

Su Telegram: title diventa l'intestazione della notifica (OK)
Sui canali voce (is_voice: true): title viene preposto al testo parlato — es. title: Lavastoviglie fa sì che lo speaker dica "Lavastoviglie: Messaggio..."
Nel codice (init.py, righe ~338-341), per i canali voce il titolo viene concatenato con un punto al testo TTS:

if final_title:
clean_title = clean_text_for_tts(final_title)
if clean_title:
full_spoken_text += f"{clean_title}. "
Proposta:
Aggiungere un'opzione per ignorare il title sui canali is_voice: true, tramite una delle seguenti modalità:

Un flag nella configurazione del canale (es. ignore_title: true)
Oppure, come default, non preporre mai il title al testo TTS per i canali voce (chi lo vuole può includerlo direttamente nel message)
Al momento l'unico workaround è rimuovere completamente title: dalla chiamata, perdendo il titolo anche su Telegram.

ciao!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants