Discord Send & Save Image 📤
ComfyUI images, straight to Discord — with a copy saved locally
- images
- image_path
Every ComfyUI render ends the same way: a SaveImage node writes a file you then have to go find. DiscordSendSaveImage does that job and posts the result to a Discord channel while it's at it - no downloading, no dragging files into a chat window, no hunting through ComfyUI/output folders. You hit Queue, and the image lands in a Discord channel your eyes are already on.
That's the entire pitch, and it's a good one if you render on a machine you don't sit at, share progress with friends, or batch-generate into a gallery channel. Since it embeds the full workflow into the PNG metadata exactly like stock SaveImage does, the "workflow included" sharing culture keeps working - the file is still a self-contained reproduction recipe.
How it works
The name is accurate: it saves and sends, two separate jobs in one node. Locally it converts the IMAGE tensor to PIL, writes it in your chosen format, and tucks the prompt and workflow JSON into PNG metadata (PngInfo) just like the core SaveImage node. For Discord it does a plain webhook POST - requests multipart upload to discord.com/api/webhooks/... - which means no bot account and no token; the webhook URL itself carries the auth. One nice detail: before it attaches a workflow JSON to the Discord message, it sanitizes the data to strip out webhook URLs and tokens, so you're not leaking your webhook secret into every share.
The inputs that matter
The required trio is images, filename_prefix, and overwrite_last. Then the ones you'll actually touch:
send_to_discord+webhook_url- the whole point. Flip the switch, paste the URL from Server Settings → Integrations → Webhooks. If you forget the URL, the node just quietly logs "no webhook URL provided" and saves locally.file_format-png(lossless, big),jpeg, orwebp.quality(1–100) only affects JPEG/WebP;losslessforces JPEG to max quality and WebP to lossless.group_batched_images- batches of up to 9 images go into one Discord gallery message instead of 20 separate spam posts. Leave it on.add_date/add_time/add_dimensions- filename decoration. Handy, butoverwrite_lastonly works if you turn the first two off so filenames stop changing.resize_to_power_of_2- a niche one for game textures; it can distort aspect ratio, so skip unless you actually need power-of-2 dimensions.
There's also a whole GitHub section (github_cdn_update, github_repo, github_token…) that mirrors Discord CDN URLs into a markdown file in a repo. Cool for building a public gallery, but it's the fiddliest part of the node and most people never touch it.
The single output is image_path - a STRING path to the first saved file. Since this is an output node you usually don't wire it anywhere; it's the end of the line.
Install
Two nodes, one pack:
cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/AEmotionStudio/ComfyUI-DiscordSend
cd ComfyUI-DiscordSend
pip install -r requirements-nodes.txt
Or just search "ComfyUI-DiscordSend" in ComfyUI Manager and click install. No model downloads, no heavy deps - requests, Pillow, numpy. Restart ComfyUI and both nodes appear under their output categories.
Where people get burned
- Sending to Discord is a one-way street. Discord re-encodes and caps file sizes (roughly 10MB before it gets picky), so a quality-100 PNG at 4K may be refused. If a big batch fails, drop the resolution or switch to WebP.
- The webhook URL is a secret-ish thing sitting inside your workflow JSON. It's a per-channel credential anyone with it can post to. Don't share a workflow with the URL pasted in - the node's own sanitizing only protects the messages it sends, not the one you export yourself.
overwrite_lastis a trap in batch production. It replaces the previous file on every run - great for iterating on one image, awful when you queue 50 and realize you've kept one.
Inputs (25)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | The images to save and/or send to Discord. | |
| filename_prefix | STRING | ComfyUI-Image | The prefix for the saved files. Supports %batch_num% placeholder for batch indexing. |
| overwrite_last | BOOLEAN | false | ⚠️ CAUTION: If enabled, new saves will REPLACE the previous file with the same name. Useful for iterative testing, dangerous for batch production. Note: You must also disable 'add_time' and 'add_date' to ensure filenames are identical. |
| file_formatopt | COMBO | png | The format to save images in. PNG is lossless but larger. JPEG and WebP are smaller but lossy. |
| qualityopt | INT | 951–100 | Quality (1-100) for JPEG/WebP. Ignored for PNG. Higher values = better quality but larger file size. |
| losslessopt | BOOLEAN | true | Use lossless compression for WebP (PNG is always lossless). For JPEG, forces maximum quality (100). |
| save_outputopt | BOOLEAN | true | Whether to save images to disk. When disabled, images will only be previewed in the UI. |
| show_previewopt | BOOLEAN | true | Whether to show image previews in the UI. Disable to reduce UI clutter for large batches. |
| resize_to_power_of_2opt | BOOLEAN | false | Resize images to nearest power of 2 dimensions (useful for game textures). ⚠️ May distort aspect ratio. Uses the algorithm selected in 'resize_method'. |
| resize_methodopt | COMBO | lanczos | Resampling algorithm used ONLY when 'resize_to_power_of_2' is enabled. Ignored otherwise. • lanczos: Best for photos • nearest-exact: Best for pixel art • bilinear/bicubic: Faster |
| include_format_in_messageopt | BOOLEAN | false | Whether to include the image format in the Discord message. |
| group_batched_imagesopt | BOOLEAN | true | Group all images from a batch into a single Discord message with a gallery, rather than sending each one separately. Maximum is 9 images. |
| add_dateopt | BOOLEAN | false | Add date (YYYY-MM-DD) to the filename. |
| add_timeopt | BOOLEAN | true | Add time (HH-MM-SS) to the filename. |
| add_dimensionsopt | BOOLEAN | false | Add dimensions (WxH) to the filename. |
| send_to_discordopt | BOOLEAN | false | If enabled, will send the media to Discord via webhook. |
| webhook_urlopt | STRING | Discord webhook URL. Get this from Discord server settings > Integrations > Webhooks. | |
| discord_messageopt | STRING | Message to include with the media when sending to Discord. | |
| include_prompts_in_messageopt | BOOLEAN | false | If enabled, will include the generation prompts in the Discord message. |
| send_workflow_jsonopt | BOOLEAN | false | If enabled, will send the workflow JSON alongside the media. |
| save_cdn_urlsopt | BOOLEAN | false | If enabled, will extract and save Discord CDN URLs. |
| github_cdn_updateopt | BOOLEAN | false | If enabled, will update a GitHub repository with the CDN URLs. |
| github_repoopt | STRING | GitHub repository in format 'username/repo'. | |
| github_tokenopt | STRING | GitHub Personal Access Token (PAT). Generate at: Settings > Developer settings > Tokens. ⚠️ Requires 'repo' scope (or 'public_repo') to upload files. | |
| github_file_pathopt | STRING | cdn_urls.md | Path to the file in the GitHub repository to update. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image_path | STRING | — |