跳到正文
DEV Community· Nazma Akter·· 3 小時前AI 評分35

一則貼文發佈至 14 個社交平台:VeloxonHub Social 貼文編輯器如何處理各平台文字、限制和排程時間

One post, 14 networks: how our composer handles per-network text, limits and timing

AI 導讀

VeloxonHub Social 的貼文編輯器支援一則貼文發佈至 14 個社交網絡,並按平台管理文字覆寫、內容限制和排程時間。系統會按各平台實際收到的文字及媒體分別驗證,例如 Bluesky 上限為 300 個字元、LinkedIn 為 3,000 個;問題未修正前不會啟用排程。每個帳戶可設定自己的發佈時間,發佈結果會逐次記錄,暫時性錯誤則自動重試。

正文

Write once, post everywhere" is the promise of every social media scheduler. While building the composer for VeloxonHub Social, we found that most of the work is in the exceptions. Bluesky caps a post at 300 characters, and LinkedIn allows 3,000. Some networks need an image, and others can't take the one you attached. Posts are scheduled across time zones. And none of these networks accept formatted text.

Here's how we handle each of these. There's also a 2-minute video of the composer in action.

1. One base text, optional overrides per network

A post has one content and a platform_options map keyed by network. The text a network will actually get is resolved in one place:

const textFor = (p: Platform) => options[p]?.text?.trim() || content;

Clicking "Customize text" copies the current base text into that network's override. From then on, the base text and the override are edited separately until you click "Use main text". Network-specific fields live in the same map: a YouTube title and visibility, a Facebook link, a title, status and tags for Dev.to and WordPress, and tags for Tumblr. Before the post is saved, options for networks that are no longer selected are dropped, so a deselected network doesn't leave stale settings behind.

2. Validate each network, and give each problem a fix

Validation runs separately for each network on the text and media that network would actually receive (textFor(p), mediaFor(p)), not on the base post. Each problem is shown with the network's name, such as "Bluesky allows 300 characters (335 now)". The Schedule button stays disabled until every problem is fixed.

Media problems get a one-click fix. When a network can't take the attached files, the warning shows a "Remove media for LinkedIn" button. It sets a no_media flag in that network's options, and the media resolver then returns nothing for that network. The other networks still get the image.

We count characters with [...text].length, which counts code points, not text.length. An emoji or a "bold" letter is one code point but two UTF-16 units, so text.length would make the counter disagree with the network.

3. "Formatting" is Unicode

Social APIs accept plain text, so the editor's bold, italic and monospace buttons map letters to the Mathematical Alphanumeric Symbols block (sans-serif bold starts at U+1D5D4). Underline and strikethrough add combining marks (U+0332, U+0336). The result survives copy-paste and every network's API exactly as typed. Bullet styles (•, ✅, 👉…), numbered lists, quotes and dividers are line prefixes, so they're plain text too.

One trade-off to be honest about: screen readers may read styled letters one character at a time. We keep formatting for emphasis and don't apply it to whole paragraphs.

4. Time is a wall-clock time plus a zone

The date picker holds a wall-clock time like 2026-10-24T09:00 in your profile's timezone, or in the zone you pick for that post, which is saved with it. It's converted to an instant only when the post is saved. If you change the timezone after picking a time, we keep the wall-clock time, so "9:00" now means 9:00 in the new zone. That's what people expect when they switch from New York to London.

Each account can override the post's time with Post's time, Publish now or Own time. These overrides are sent as separate account_schedules, so one post can go out to LinkedIn at 9:00 in Europe and to Instagram at 18:00 in New York.

5. Retries are part of the record

Every publish attempt is logged with its outcome: published, transient_error, permanent_error or auth_error. Temporary errors (network failures, HTTP 429 and 5xx) are retried automatically with backoff. Validation rejections fail right away, because sending the same request again won't fix them. Authorization errors trigger a token refresh, or ask you to reconnect the account. The post page shows the full history for each network, so "it posted on the second try" is something you can see, not just guess.

See it

The reel shows the full flow: accounts → AI draft → formatting → templates → media → previews → per-network versions → timezone and per-account scheduling → approvals → retries and history → duplicate. 7-day free trial, no card: https://social.veloxonhub.com

Questions about the per-network override model or the Unicode formatter are welcome in the comments.

來源:DEV Community · dev.to