TG Send Image(s) ◀️
Telegram will recompress your render unless you stop it
- IMAGE
- trigger
- message
- message_id
- trigger
You rendered something nice, wired it into this node, and the version on your phone looks softer than the one in your ComfyUI preview. That's not the node being lazy - that's what "photo" means in Telegram. Understanding the difference between photo and document is 80% of using this node well.
What it does with your batch
It takes the IMAGE socket, converts each tensor to 8-bit with a clip-to-0-255 and hands the array to Pillow, which encodes it in whichever format you picked (PNG, WEBP, JPG). Then it counts what's left:
- One image → one
sendPhotocall (orsendDocumentifsend_as_fileis on). - Several images,
groupon (default) → a singlesendMediaGroupalbum, which is the nice grid layout. Telegram caps albums at 10, and rather than silently dropping extras the node raisesTelegram media groups allow at most 10 images; set group=False for larger batches. - Several images,
groupoff → individual sends, one request each. Slower, more rate-limit exposure, but no album limit.
Either way, message and message_id refer to the last image sent, per the README - so if you're chaining into an Edit Message Image, you're editing the last one of the batch, not the first.
The compression thing
Telegram re-encodes anything uploaded as a photo: it resizes to a sane dimension and applies its own JPEG. For a meme this is invisible and great - the recipient can open it inline, gets a preview, no download prompt. For a 4K SDXL render or anything with fine detail it's a real quality loss, and no node setting can opt out of it while staying a photo.
send_as_file is the fix. It switches the call to sendDocument, the bytes go up untouched inside a .png/.jpg/.webp container, and Telegram delivers the file with no re-encode - at the cost of it arriving as a file attachment instead of an inline picture. Send a preview as a photo and the master as a file, if you care.
One thing that quietly goes right: image and audio senders encode the pixels, so your Telegram uploads carry no ComfyUI workflow metadata. The workflow JSON that normally travels inside a ComfyUI PNG doesn't ride along here. Note the videos are a different story - see Send Video.
The rest of the widgets
chat_id is a socket fed from the Listener. caption is plain text, 0–1024 characters, and parse_mode (None/HTML/Markdown/MarkdownV2) applies to it. has_spoiler blurs the image behind a tap-to-reveal overlay - genuinely useful for a bot that hands out NSFW or spoiler-y renders. show_caption_above_media moves the caption over the image instead of under it, which mostly matters on newer Telegram clients.
disable_notification defaults to True, so your bot is silent unless you turn it off; protect_content blocks forwarding and saving. file_name is the basename used for the attachment plus the extension from format; batches get numbered suffixes. message_thread_id takes the Listener's thread ID (-1 for normal chats, and non-positive values are stripped from the request before it's sent).
And the trigger input: it's a pure ordering leash, untyped (*), passed through to the output unchanged. Chain it across senders and editors when you want "send this, then edit that" to be guaranteed rather than hoped for.
Outputs
message is the Telegram response DICT; message_id is the ID of the last sent image; trigger mirrors the input. On a failed send - all five retry attempts exhausted - message and message_id become silent blockers so a follow-up edit can't grab a stale ID, trigger still passes through, and the run continues instead of throwing an execution error.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/CoolBreeze164/ComfyUI-Autonomous-Telegram-Bot
python -m pip install -r ComfyUI-Autonomous-Telegram-Bot/requirements.txt
Portable installs use python_embeded\python.exe for the pip step. Needs httpx, numpy, pillow, av>=14.2.0 - Pillow does the actual encoding here. Or install through ComfyUI Manager by searching ComfyUI Autonomous Telegram Bot, then restart.
Common issues
Telegram media groups allow at most 10 images- either setgroupto false or split the batch. This is a hard Telegram limit, not a config you can raise.- Image looks degraded - turn on
send_as_file, or send PNG instead of JPG, or both. A photo is always re-encoded. - Caption vanishes - captions only make sense on the media object; empty caption plus a parse mode that fails to parse will get you a rejected request. If you're pasting user text into a caption, keep
parse_modeonNone. - Editing the wrong picture later - remember the outputs point at the last image of the batch.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| bot_token | STRING | Telegram bot token from BotFather | |
| chat_id | INT | Unique identifier for the target chat | |
| IMAGE | IMAGE | the image(s) to send | |
| caption | STRING | Media caption, 0-1024 characters after entities parsing | |
| parse_mode | COMBO | Mode for parsing entities in the photo caption. See https://core.telegram.org/bots/api#formatting-options for more details. | |
| show_caption_above_media | BOOLEAN | false | Pass True, if the caption must be shown above the message media |
| has_spoiler | BOOLEAN | false | Pass True if the media needs to be covered with a spoiler animation |
| disable_notification | BOOLEAN | true | Sends the message silently. Users will receive a notification with no sound. |
| protect_content | BOOLEAN | false | Protects the contents of the sent message from forwarding and saving |
| group | BOOLEAN | true | Pass True to send multiple media as media group |
| send_as_file | BOOLEAN | false | Pass True to send the media as file without compression |
| file_name | STRING | image | the file name for this media |
| format | COMBO | image format | |
| message_thread_id | INT | -1-1–9223372036854776000 | Unique identifier for the target message thread of the forum topic (-1 = None) |
| triggeropt | * | Optional trigger to enforce execution order |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| message | DICT | — |
| message_id | INT | — |
| trigger | * | — |