Slack image block with a Sume URL: PNG or JPEG, alt text required

Slack's image block takes a public image_url up to 3000 characters and lists png, jpg, jpeg and gif. Generate a png with Sume, then post it with alt_text.

4 min readSume
All posts

Post an image block with image_url set to the Sume data[0].url and a required alt_text. Slack's image block reference says alt_text is required (at most 2000 characters), image_url is a public URL of at most 3000 characters, and the supported file types are png, jpg, jpeg and gif. WebP is not listed, so request output_format png or jpeg from the Sume image API.

The block can show in modals, messages and home tabs, and title is optional plain text, also up to 2000 characters.

A bot that generates and posts

This Python script generates one image and posts it to a Slack incoming webhook. It stops when either secret is empty, and it posts only on a 200.

import json, os, urllib.request

KEY = os.environ.get("SUME_API_KEY", "")
HOOK = os.environ.get("SLACK_WEBHOOK_URL", "")
if not KEY or not HOOK:
    raise SystemExit("SUME_API_KEY and SLACK_WEBHOOK_URL are required")

def post(url, body, headers):
    req = urllib.request.Request(url, json.dumps(body).encode(), headers)
    with urllib.request.urlopen(req, timeout=60) as r:
        return r.status, r.read()

prompt = "flat illustration of a rocket launch, no text"
status, raw = post("https://api.sume.com/v1/images",
    {"model": "openai/gpt-image-2.5", "prompt": prompt, "quality": "low",
     "output_format": "png"},
    {"Authorization": "Bearer " + KEY, "Content-Type": "application/json"})
if status != 200:
    raise SystemExit(f"status {status}")
url = json.loads(raw)["data"][0]["url"]
block = {"blocks": [{"type": "image", "image_url": url, "alt_text": prompt}]}
print(post(HOOK, block, {"Content-Type": "application/json"})[0])

What should alt_text say?

Use a description of what the picture shows, not the prompt copied blindly. The prompt above is short enough to double as alt text, but a longer prompt that lists style and camera terms reads badly in a screen reader. The field is required anyway, so a blank string is not an option.

If the call returns 202, the image is not ready: the job envelope has status_url and result_url. The script exits in that case; a real bot should poll as the jobs guide says and never resend the create request. A 502 is a terminal failure with an error envelope.

The URL in the block is public, so anyone in the channel, or anyone who gets the link, can open it. Keep confidential product images out of shared channels. Each 200 response carries usage.cost, the USD billed for that image, so a bot that posts daily can log the spend next to the message.

To change the picture for a thread, post a new block instead of editing the old one, and keep the old Sume URL in your own log. For a scheduled post, generate the image first and check the status code before you send anything to Slack, so a failed generation never produces a message with a broken or missing picture.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume