17 KiB
ComfyUI Telegram Bridge Specification
1. Purpose
ComfyUI-tgBridge provides a ComfyUI custom node that runs after a video generation/save node, collects generation metadata from connected inputs, formats that metadata into a readable Telegram report, and sends the generated video plus metadata to a configured Telegram group.
The primary target workflow is:
Video Combine
|
| VHS_FILENAMES
v
Telegram Workflow Report
The node must not replace existing image/video save nodes. It must consume already-saved output paths and act as a post-processing uploader.
2. Goals
- Send generated videos from ComfyUI to a Telegram group through the official Telegram Bot API.
- Preserve local ComfyUI output behavior exactly as configured by upstream nodes.
- Support VideoHelperSuite
Video Combineoutput viaVHS_FILENAMES. - Collect common generation metadata through explicit ComfyUI input sockets.
- Format a compact video caption and a richer metadata reply message.
- Support Wan 2.2 style high/low model and LoRA reporting.
- Optionally attach/send reference images used by the workflow.
- Keep secrets outside the ComfyUI workflow graph.
- Make failed Telegram uploads visible without breaking local output generation by default.
3. Non-Goals for V1
- Do not implement a replacement
Save Imagenode. - Do not implement a replacement
Video Combinenode. - Do not require Telegram CLI or MTProto user login for V1.
- Do not handle large file workarounds beyond the normal Telegram Bot API.
- Do not parse the entire ComfyUI graph automatically in V1.
- Do not implement dynamic socket add/remove frontend behavior in V1.
4. Target Users
The node is intended for ComfyUI users who:
- Generate videos with nodes such as VideoHelperSuite
Video Combine. - Want the final video posted to a private Telegram group.
- Want enough workflow metadata in Telegram to understand or reproduce a generation.
- Prefer manually linking important values into a final report node rather than relying on fragile automatic graph inspection.
5. Main Node
5.1 Node Name
Display name:
Telegram Workflow Report
Suggested class name:
TelegramWorkflowReport
Suggested category:
Telegram
5.2 Primary Input and Output
The node consumes and returns VHS_FILENAMES:
required:
filenames: VHS_FILENAMES
returns:
filenames: VHS_FILENAMES
Video Combine returns this shape:
(save_output, output_files)
where:
save_outputis a boolean from the upstream save/combine node.output_filesis a list of absolute or ComfyUI-resolved output file paths.
The node must return the original filenames value unchanged so it remains chainable.
6. Node Inputs
6.1 Required Inputs
| Input | Type | Default | Description |
|---|---|---|---|
filenames |
VHS_FILENAMES |
none | Output from VideoHelperSuite Video Combine. |
6.2 Core Controls
| Input | Type | Default | Description |
|---|---|---|---|
enabled |
BOOLEAN |
True |
If false, skip Telegram sending and return filenames unchanged. |
upload_mode |
enum | final_only |
Which files from output_files to send. |
send_as |
enum | auto |
Telegram media method. |
message_mode |
enum | caption_and_reply |
How metadata is sent. |
failure_mode |
enum | warn |
Whether Telegram upload failure raises an exception. |
Enums:
upload_mode:
final_only
all_files
send_as:
auto
video
photo
document
message_mode:
caption_only
caption_and_reply
caption_reply_and_json
failure_mode:
warn
raise
Behavior:
final_onlysends only the final item inoutput_files.all_filessends every existing file inoutput_files.autoshould send common video extensions as video, common still image extensions as photo, and unknown extensions as document.warnlogs upload errors to ComfyUI console and does not fail the workflow.raiseraises a node exception when Telegram sending fails.
6.3 Human Metadata Inputs
| Input | Type | Default | Description |
|---|---|---|---|
title |
STRING |
empty | Optional short generation title. |
positive_prompt |
STRING multiline |
empty | Main prompt text. |
negative_prompt |
STRING multiline |
empty | Negative prompt text. |
extra_notes |
STRING multiline |
empty | Free-form notes appended to the report. |
6.4 Model Inputs
| Input | Type | Default | Description |
|---|---|---|---|
base_model |
STRING |
empty | Single-model workflow base model. |
high_model |
STRING |
empty | Wan 2.2 or similar high-noise model. |
low_model |
STRING |
empty | Wan 2.2 or similar low-noise model. |
vae |
STRING |
empty | Optional VAE name. |
Formatting rule:
- If
high_modelorlow_modelis set, render a High/Low model section. - Otherwise render
base_modelif set. - If both single model and high/low fields are set, high/low takes precedence and
base_modelis rendered asBase.
6.5 LoRA Inputs
V1 should provide both fixed simple slots and advanced multiline slots.
Fixed slots:
| Input | Type | Default |
|---|---|---|
lora_1_name |
STRING |
empty |
lora_1_strength |
FLOAT |
0.0 |
lora_2_name |
STRING |
empty |
lora_2_strength |
FLOAT |
0.0 |
lora_3_name |
STRING |
empty |
lora_3_strength |
FLOAT |
0.0 |
lora_4_name |
STRING |
empty |
lora_4_strength |
FLOAT |
0.0 |
lora_5_name |
STRING |
empty |
lora_5_strength |
FLOAT |
0.0 |
Advanced slots:
| Input | Type | Default | Description |
|---|---|---|---|
high_loras |
STRING multiline |
empty | One high-noise LoRA per line. |
low_loras |
STRING multiline |
empty | One low-noise LoRA per line. |
extra_loras |
STRING multiline |
empty | One general LoRA per line. |
Recommended multiline format:
detail_boost_v2.safetensors: 0.65
motion_style_wan22.safetensors: 0.8
character_ref.safetensors: 0.55
Formatting rule:
- Ignore fixed LoRA slots with empty names.
- Render fixed LoRA slots under
LoRA. - Render
high_lorasandlow_lorasas separate subsections if either exists. - Render
extra_lorasunderLoRA. - Preserve user-provided multiline LoRA text with light cleanup only.
6.6 Generation Settings Inputs
| Input | Type | Default |
|---|---|---|
seed |
INT |
-1 |
steps |
INT |
0 |
cfg |
FLOAT |
0.0 |
sampler |
STRING |
empty |
scheduler |
STRING |
empty |
width |
INT |
0 |
height |
INT |
0 |
frames |
INT |
0 |
fps |
FLOAT |
0.0 |
Formatting rule:
- Omit numeric fields with sentinel values.
seed = -1means unknown/unset.steps = 0,width = 0,height = 0,frames = 0, andfps = 0.0mean unknown/unset.- Render resolution as
WIDTHxHEIGHTonly when both width and height are set.
6.7 Reference Inputs
| Input | Type | Default | Description |
|---|---|---|---|
reference_label |
STRING |
empty | Short label for the reference. |
reference_image |
IMAGE optional |
none | Optional ComfyUI image tensor to send after the video. |
send_reference_image |
BOOLEAN |
False |
Whether to send the reference image to Telegram. |
Behavior:
- If
send_reference_imageis false, do not upload the image. - If true and
reference_imageis connected, convert the first image tensor to a temporary PNG and send it as a reply to the video. - If
reference_labelis set, include it in the metadata report.
7. Telegram Configuration
Secrets must be read from environment variables or a local config file excluded from Git.
7.1 Environment Variables
Required:
COMFY_TG_BOT_TOKEN=...
COMFY_TG_CHAT_ID=...
Optional:
COMFY_TG_BOT_API_BASE=https://api.telegram.org
COMFY_TG_DISABLE_NOTIFICATION=false
COMFY_TG_MESSAGE_THREAD_ID=
COMFY_TG_PARSE_MODE=HTML
COMFY_TG_TIMEOUT_SECONDS=120
Meanings:
COMFY_TG_BOT_TOKEN: Telegram bot token from BotFather.COMFY_TG_CHAT_ID: Target group or channel chat ID.COMFY_TG_BOT_API_BASE: Allows standard Telegram API or a local Bot API server later.COMFY_TG_DISABLE_NOTIFICATION: If true, send silently.COMFY_TG_MESSAGE_THREAD_ID: Optional forum topic/thread ID for Telegram groups with topics.COMFY_TG_PARSE_MODE:HTMLby default for safer escaping.COMFY_TG_TIMEOUT_SECONDS: HTTP timeout for media uploads.
7.2 Config File
Optional V1 config file path:
config/telegram.json
This file must be listed in .gitignore.
Environment variables take precedence over config file values.
8. Telegram Message Format
8.1 Default Message Mode
Default:
caption_and_reply
This sends:
- Generated video with compact caption.
- Metadata report as a reply to the video.
This avoids overloading the video caption and keeps the group readable on mobile.
8.2 Compact Caption Template
Generation Complete
{title_or_prompt_summary}
Seed: {seed}
Size: {width}x{height} | Frames: {frames} | FPS: {fps}
Rules:
- Use the title when provided.
- Otherwise use a shortened positive prompt summary.
- Omit unset fields.
- Keep the caption short enough for Telegram media captions.
- Escape all text for the selected Telegram parse mode.
Example:
Generation Complete
Rainy neon alley camera push
Seed: 3829147701
Size: 832x480 | Frames: 81 | FPS: 16
8.3 Detailed Reply Template
Generation Details
Prompt:
{positive_prompt}
Negative:
{negative_prompt}
Model:
Base: {base_model}
High: {high_model}
Low: {low_model}
VAE: {vae}
LoRA:
- {lora_1_name}: {lora_1_strength}
- {lora_2_name}: {lora_2_strength}
High LoRA:
{high_loras}
Low LoRA:
{low_loras}
Settings:
Seed: {seed}
Steps: {steps}
CFG: {cfg}
Sampler: {sampler}
Scheduler: {scheduler}
Size: {width}x{height}
Frames: {frames}
FPS: {fps}
Reference:
{reference_label_or_attached}
Files:
{uploaded_file_names}
Notes:
{extra_notes}
Rules:
- Omit entire sections that have no content.
- Omit individual fields that are empty or sentinel values.
- Keep section order stable.
- Prefer plain readable text over raw JSON.
- Escape HTML entities when
COMFY_TG_PARSE_MODE=HTML. - If the final message exceeds Telegram text limits, split it into multiple reply messages by section.
8.4 JSON Attachment Mode
When message_mode = caption_reply_and_json, send an additional .json document containing structured metadata.
Suggested JSON shape:
{
"title": "",
"prompts": {
"positive": "",
"negative": ""
},
"models": {
"base": "",
"high": "",
"low": "",
"vae": ""
},
"loras": {
"general": [],
"high": [],
"low": []
},
"settings": {
"seed": null,
"steps": null,
"cfg": null,
"sampler": "",
"scheduler": "",
"width": null,
"height": null,
"frames": null,
"fps": null
},
"reference": {
"label": "",
"attached": false
},
"files": []
}
9. File Selection Rules
For upload_mode = final_only:
- Upload only the last existing path from
output_files. - This avoids sending metadata PNGs or intermediate files from VideoHelperSuite.
For upload_mode = all_files:
- Upload every existing path from
output_files. - Skip missing paths and log a warning.
Extension handling:
video:
.mp4
.mov
.webm
.mkv
image:
.png
.jpg
.jpeg
.webp
.gif
document:
everything else
send_as = auto:
- Use
sendVideofor video extensions. - Use
sendPhotofor common still image extensions. - Use
sendDocumentfor unknown files.
For generated videos, sendVideo should be the default path.
10. Telegram API Behavior
10.1 Send Order
For one final video:
- Send video with compact caption.
- Capture returned Telegram message ID.
- Send detailed metadata as a reply to that message ID.
- If enabled, send reference image as a reply to that message ID.
- If enabled, send JSON metadata as a reply to that message ID.
10.2 Reply Threading
When sending follow-up messages:
- Use
reply_to_message_idpointing to the uploaded video message. - If
COMFY_TG_MESSAGE_THREAD_IDis set, include it in all messages.
10.3 Error Handling
Expected failures:
- Missing bot token.
- Missing chat ID.
- Missing output file.
- HTTP timeout.
- Telegram API error.
- File upload rejected.
Behavior:
- In
failure_mode = warn, log a concise warning and return filenames unchanged. - In
failure_mode = raise, raise a ComfyUI node exception.
Logs must not print the bot token.
11. Security
- Never store bot tokens in workflow JSON by default.
- Never print bot tokens in logs.
- Local config files containing secrets must be ignored by Git.
- Metadata messages may contain prompts and model names; users should assume anything sent to Telegram is visible to group members.
12. Implementation Structure
Suggested package layout:
ComfyUI-tgBridge/
__init__.py
nodes.py
tgbridge/
__init__.py
config.py
formatter.py
telegram_bot.py
reference_image.py
metadata.py
tests/
test_formatter.py
test_file_selection.py
test_config.py
pyproject.toml
README.md
SPEC.md
12.1 Module Responsibilities
nodes.py:
- Defines ComfyUI node classes.
- Maps node inputs to metadata objects.
- Calls formatter and Telegram sender.
- Returns original
VHS_FILENAMES.
tgbridge/config.py:
- Reads environment variables.
- Optionally reads local config file.
- Validates required Telegram settings.
tgbridge/metadata.py:
- Defines structured metadata dataclasses or typed dictionaries.
- Normalizes empty/sentinel values.
- Parses LoRA inputs.
tgbridge/formatter.py:
- Builds compact caption.
- Builds detailed reply body.
- Builds JSON metadata payload.
- Escapes text for Telegram parse mode.
- Splits long text messages.
tgbridge/telegram_bot.py:
- Sends video/photo/document/message through Bot API.
- Handles reply IDs and thread IDs.
- Converts Telegram API errors into clear exceptions.
tgbridge/reference_image.py:
- Converts optional ComfyUI
IMAGEtensor to temporary PNG. - Cleans up temporary file after upload.
13. Dependencies
Use uv for Python environment management.
Suggested runtime dependencies:
requests
Pillow
Suggested dev dependencies:
pytest
ruff
Avoid heavyweight Telegram clients in V1 because the official Bot API is enough for the expected file sizes.
14. Testing Plan
14.1 Unit Tests
Formatter:
- Empty metadata produces no blank sections.
- High/low models render correctly.
- Fixed LoRA slots render correctly.
- Multiline high/low LoRA fields render correctly.
- Sentinel values are omitted.
- HTML escaping works.
- Long messages split by section.
File selection:
final_onlyselects the last existing file.all_filesselects all existing files.- Missing files are skipped or reported as configured.
- Extension detection maps videos to
sendVideo.
Config:
- Env vars load correctly.
- Config file values load correctly.
- Env vars override config file.
- Missing required values produce clear errors.
14.2 Manual Integration Tests
Basic video upload:
Video Combine -> Telegram Workflow Report
Expected:
- Video appears in Telegram group.
- Caption is compact.
- Metadata reply appears under the video.
Wan 2.2 report:
Expected:
- High and low models are separate.
- High and low LoRAs are separate.
Reference image:
Expected:
- Reference image is uploaded only when enabled.
- Reference image replies to the video.
Failure mode:
Expected:
- Invalid chat ID logs a warning when
failure_mode = warn. - Invalid chat ID fails node when
failure_mode = raise.
15. V1 Acceptance Criteria
V1 is complete when:
- The node appears in ComfyUI as
Telegram Workflow Report. - The node accepts
VHS_FILENAMESfrom VideoHelperSuiteVideo Combine. - The node returns the same
VHS_FILENAMESunchanged. - A generated video can be sent to a configured Telegram group.
- The video caption uses the compact format.
- The detailed metadata message is sent as a reply.
- Empty metadata fields are omitted cleanly.
- Wan 2.2 high/low model and LoRA fields are supported.
- Optional reference image upload works.
- Secrets are loaded from environment variables or ignored local config.
- Unit tests cover formatting, file selection, and config behavior.
16. Future Enhancements
- Automatic extraction from ComfyUI prompt/workflow JSON.
- Support for Telegram local Bot API server configuration.
- Support for Telethon user-session sending.
- Frontend dynamic LoRA socket add/remove behavior.
- Optional upload queue for background sending.
- Optional per-workflow Telegram destination override.
- Optional HTML template customization.
- Optional workflow JSON export as a Telegram attachment.