yeetpost

Telegram

#Overview

Post to a Telegram channel through a bot you own. A connection is one channel, not one bot, so a bot that is admin of three channels is three connections.

Telegram posts are free to send. The channel counts as one connected account, like LinkedIn or Bluesky. See pricing.

#How to connect

  1. Message @BotFather and send /newbot to get a bot token.
  2. Add the bot to your channel as an admin with permission to post messages.
  3. In yeetpost, click Add connection, then Telegram, and paste the token and the channel.

The channel is either its public @handle or, for a private channel, the numeric id starting with -100. All three things are checked when you connect: that the token is real, that the chat is a channel rather than a group, and that the bot is an admin that can post. A connection that exists is one that can post.

Your first Telegram connection gets the slug telegram. A second one gets a slug built from the channel, so @shipnotes becomes shipnotes_telegram. GET /connections describes it as Ship notes (Telegram).

The connection is identified by the chat id, so renaming the channel does not break it. A bot token never expires. If you revoke it in BotFather, connect again with the new one.

#What works

ThingValue
Text limit4096 characters
Text limit with an image1024 characters, because the text becomes the photo's caption
ImagesUp to 5 per post
Image formatsimage/png and image/jpeg only
Alt textNo, Telegram has no field for it, so it is dropped
ThreadsYes, up to 24 replies under the head message
First commentNo, LinkedIn only
SchedulingYes
Permalinkhttps://t.me/<handle>/<message id>, or https://t.me/c/<internal id>/<message id> for a private channel
Per-post feeNone

An image turns the text into a caption, and a caption holds a quarter of what a message does. Text over 1024 characters with an image attached is refused rather than split into a photo plus a follow-up message nobody wrote. Send the long text on its own.

Alt text is dropped, silently and per connection. An image's description still travels to every other connection on the same post.

A broken thread is taken back. If Telegram refuses the third reply, the messages this request already published are deleted, newest first, head included, and the item comes back failed with Telegram's own error. If one of those deletes is refused too, what is still up is a shorter thread and the item comes back sent with threadCount at the replies that survived.

An album is never taken back. Several images go out as one album, which is several messages a Telegram client shows as one post. Deleting a piece of it would leave the rest standing with a gap, so when the head carries more than one image only the replies are deleted. The album stays and the item comes back sent.

A private channel's permalink only opens for members of that channel.

#Refusals

Every one of these is a per-item refusal: the other connections on the same post still go out. See the errors reference for the full vocabulary.

CodeStatusWhen
invalid_request400Text over 4096 characters, or over 1024 with an image attached
media_unsupported400The image is not a png or a jpeg
shape_unsupported400A firstComment was given. Telegram has no first comment
unauthorized401The bot token was revoked. Connect again with the new one
platform_rejected422Telegram refused the message, for example the bot lost its admin rights
internal_server_error500Our fault. Quote the req_id when you report it

The image check runs before anything is sent, so a gif aimed at Telegram never reaches the channel and never blocks the other connections on the post.

#Post from curl

curl -X POST https://api.yeetpost.com/api/v2/posts \ -H "x-api-key: $YEETPOST_API_KEY" \ -H "content-type: application/json" \ -d '{ "text": "release 2.4.0 is out", "connectionSlugs": ["telegram"], "thread": ["changelog: https://yeetpost.com/changelog"] }'

#Post from Node

const response = await fetch("https://api.yeetpost.com/api/v2/posts", { method: "POST", headers: { "x-api-key": process.env.YEETPOST_API_KEY, "content-type": "application/json", "Idempotency-Key": crypto.randomUUID(), }, body: JSON.stringify({ text: "release 2.4.0 is out", connectionSlugs: ["telegram"], mediaIds: [process.env.SCREENSHOT_MEDIA_ID], }), }); const data = await response.json(); console.log(data.results[0].status, data.results[0].url);

Remember the caption rule when you attach an image: with mediaIds set, the text has to fit in 1024 characters.

#FAQ

#Can I post to a group or to a person?

No. A connection has to be a channel. A group or a private chat is refused when you try to connect it, because the permalink shapes and the posting rules are not the same.

#Why does my gif come back media_unsupported?

Telegram takes png and jpeg photos only. The check runs before the post is sent, so the same post still goes out to every other connection on it.

#Why did my alt text disappear?

Telegram has no field for a photo description. yeetpost drops it for this connection and still sends it to X, Bluesky, Mastodon and LinkedIn on the same post.

#How do I find a private channel's id?

It is the numeric id starting with -100. Most Telegram clients show it in the channel info, and forwarding a message from the channel to a bot such as @userinfobot returns it.

#Does the bot need any other permission?

Only "post messages". yeetpost checks for exactly that when you connect and refuses the connection if the bot is not an admin that can post.

Other platforms