feat: add native Discord transport - #167
Merged
Merged
Conversation
Adds a native `discord` transport on top of the Home Assistant `discord` integration (legacy notify platform): - markdown title composition (`**title**` + message), skipped when the embed carries its own title - rich embed passthrough (`discord_embed` -> `data.embed`) - camera snapshot upload via `envelope.grab_image()` (`discord_attach_image`) - remote image URLs (`discord_image_urls`, `discord_verify_ssl`) - opt-in priority emoji prefix (`discord_priority_prefix`) - numeric channel/user target validation (target required by the service) - 2000-character content truncation (Discord hard limit) - residual generic data keys are not forwarded (service ignores them) Docs page, CHANGELOG entry and 71 unit tests included. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HydbFBwYt3HV83xQ4UzdjV
for more information, see https://pre-commit.ci
…rt.__init__ is abstract)
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.
Motivation
Discord (~2.6k HA installs on analytics) is reachable today only through the generic transport, which loses everything beyond plain text. This adds a native discord transport on top of the Home Assistant discord integration (legacy notify platform), following the same structure as the Telegram/Pushover/Matrix-style transports: markdown title composition, rich embeds, camera snapshot upload, remote image URLs and an opt-in priority emoji prefix.
What it does
Title: the service has no title field, so title + newline + message is composed as Discord markdown — skipped when discord_embed carries its own title (avoids double titles).
Embeds: discord_embed passed through as data.embed (HA core schema: title, description, color, url, fields, footer, author, thumbnail, image).
Snapshots: discord_attach_image: true calls envelope.grab_image() and passes the local path in data.images (the integration checks is_allowed_path, so allowlist_external_dirs must include the SuperNotify media path — documented).
Remote images: discord_image_urls → data.urls (+ discord_verify_ssl), subject to allowlist_external_urls and the integration's 8 MB cap.
Targets: the service requires numeric channel/user IDs and silently sends nothing without them, so targets are validated (int, > 0, deduped) and an empty result fails the delivery (TargetRequired.ALWAYS).
Priority: no native priority on Discord; optional emoji prefix (critical/high/low-minimum, medium none), same mapping as Matrix.
Limits: content truncated at 2000 chars (hard limit; otherwise channel.send() raises and the message is lost).
Action: any notify. accepted, since the slug depends on the config entry name (notify.discord, notify.discord_2, …).
Residual generic data keys are dropped with a debug log (the service ignores unknown keys anyway) — consistent with the Matrix transport.
Features declared: MESSAGE | TITLE | IMAGES | SNAPSHOT_IMAGE.
Files
custom_components/supernotify/transports/discord.py (new)
const.py: TRANSPORT_DISCORD + TRANSPORT_VALUES
notify.py: import + TRANSPORTS registration
docs/transports/discord.md (new)
CHANGELOG.md: entry under 2.0.0
tests/components/supernotify/transports/test_transport_discord.py: 71 cases (100% coverage of the transport)
Testing
Unit: 71 tests green; full suite 815 passed with the branch applied (ruff/codespell clean with repo config).
Real HA: tested on my instance against a Discord bot channel — plain message, title composition, embed with title, snapshot upload from a camera, priority prefix. (compilare con l'esito E2E prima di aprire)
Notes for review
I kept data.color passthrough as-is (int expected by nextcord); no coercion of hex strings.
Happy to rename data keys or trim features if you'd rather keep the first version smaller.