August 16, 2026

The publishing Skill — Technical Rules for Multi-Platform Content Distribution

How Datarim's publishing skill encodes platform limits, HTML sanitization, split patterns, and the channel-comment recipe so content agents distribute posts correctly the first time.

Writing a post and distributing it are two different problems. A finished text can still fail at publish time — truncated by a platform limit, broken by unsanitized HTML, or threaded incorrectly in a Telegram channel. The publishing skill encodes the technical rules that cover the act of publishing, leaving writing and quality review to separate skills.

Platform limits and character counting

Each platform has different limits. Telegram's sendMessage allows 4096 characters and sendPhoto captions allow 1024 — both measured in UTF-16 code units, not bytes. Most Cyrillic characters count as 1 unit; most emoji count as 2 (surrogate pairs). The skill provides a canonical Python counter, telegram_units(text), that uses len(text.encode("utf-16-le")) // 2. LinkedIn caps post text at 3000 characters; Twitter/X at 280 (or 25,000 with Premium+); Facebook at 63,206.

HTML sanitization for Telegram

Sending text with parse_mode=HTML and a raw & or < returns a 400 error. The skill includes a tg_safe_html() function built on Python's html.parser: it escapes raw characters, round-trips whitelisted tags (<b>, <a href>, <code>, and a few others), and drops disallowed tags while preserving their inner text. The href scheme allowlist blocks javascript: and data: links regardless of attribute quoting style.

Split patterns for long posts

When a post exceeds the limit, the skill defines three named patterns. Pattern A handles a photo post between 1024 and 5096 units: a teaser caption on sendPhoto followed by the rest as a reply. Pattern B handles long text-only posts above 4096 units: a chain of reply-threaded sendMessage calls. Pattern C handles a photo post above 5096 units: the photo gets a numbered caption [1/N] and each continuation carries its part number. Split points follow a priority order — operator markers first (<!-- split-here -->), then paragraph breaks, then sentence boundaries, then a hard space-aligned cut as a last resort.

Channel comments and the links-in-first-comment rule

Posting a comment under a Telegram channel post requires discovering the auto-forwarded copy in the linked group via a getUpdates poll loop — reply_to_message_id set to the channel post's ID does not thread correctly, because that ID lives in a different namespace. After posting the comment, the returned message_thread_id must equal the forwarded message's ID; if not, the comment went to the wrong thread and must be deleted. The same skill also encodes the universal links-in-first-comment rule: the post body must never contain a standalone links block — all CTA URLs belong in the author's first comment. See the publishing reference or read what Datarim is for the broader picture.