Guide
Auto-Posting From a Bot: A Developer's Guide
Auto-posting is one of those features that's trivial until it's in production. The demo is a cron job and an HTTP call. The production version has to survive retries without double-posting, platform outages without losing posts, and platform rules without losing the account. This guide covers the parts the demo skips.
Start with the trigger, not the platform
Every auto-poster is trigger plus formatter plus publisher, and the trigger defines the whole design. Event-driven triggers (deploy finished, issue closed, sale made) come from webhooks or your app's own code and need idempotency, because upstream systems redeliver events. Scheduled triggers (daily digest, weekly changelog) come from cron and need overlap protection so a slow run and the next run don't both fire. Agent-driven triggers — an LLM deciding a result is worth sharing — need everything above plus output validation. Decide which you're building first; bolting idempotency on later is much harder.
The easy 80%: webhooks and bot tokens
Discord and Telegram are the platforms to start with because their auth is static. A Discord channel webhook is one URL — POST JSON at it and you're posting. A Telegram bot is a token from @BotFather plus the chat ID of your channel. Neither expires, neither refreshes. If your bot only needs to reach your own community, you can be done in an afternoon with no OAuth at all.
The hard 20%: X and Reddit
X requires an OAuth 2.0 app whose access tokens expire and must be refreshed — which means server-side token storage and refresh logic, plus handling the day a refresh fails. Reddit requires a script app and a one-time authorization dance to mint a permanent refresh token, then OAuth token exchange on every posting session. This is where most DIY auto-posters either stall or get outsourced: a unified publishing API like AgentPost holds these credentials server-side, and your bot authenticates with one static API key — the same shape as the Discord webhook you started with.
Idempotency: the double-post killer
The classic auto-poster bug is posting twice: a timeout on your side, a retry, and the platform received both. Fix it structurally — derive a stable key from the trigger (event ID, date, commit SHA), record it before you attempt delivery, and skip if it's already marked done. Retry only errors that can succeed on retry: 429 and 5xx with exponential backoff, never 4xx.
const key = `release-${tag}`; // stable per trigger
if (await db.get(`posted:${key}`)) return; // already handled
await db.set(`posted:${key}`, "pending");
const res = await fetch("https://agentpost.dietsoda.dev/v1/publish", {
method: "POST",
headers: { "X-API-Key": process.env.AGENTPOST_KEY,
"Content-Type": "application/json" },
body: JSON.stringify({ platforms: ["x", "telegram"], text }),
});
if (res.status === 429 || res.status >= 500) throw new Error("retry");
await db.set(`posted:${key}`, "done"); // 2xx and 4xx are both finalLog per-platform deliveries, not just requests
When someone asks 'did the release announcement go out?', 'the bot ran' is not an answer. Persist one record per platform delivery: trigger key, platform, ok flag, post URL or error, timestamp. A publishing API that returns per-platform results makes this a one-line insert per entry. The post URL matters more than it looks — it's the difference between re-checking manually and pasting a link in the incident channel.
Stay off the ban radar
Platforms don't ban bots; they ban spam patterns. The lines that matter: post to accounts and channels you own or moderate, keep frequency human-plausible (a burst of ten identical posts is a pattern-match away from a flag), never post the same text repeatedly, and respect 429s instead of hammering through them. On Reddit, check a subreddit's bot policy before posting into it — some welcome release bots, some auto-remove them. A bot that behaves like a considerate human account is effectively invisible to enforcement.
Skip the four integrations
AgentPost gives your agent one API key and one POST endpoint that publishes to X, Reddit, Telegram, and Discord — with per-platform results back. 7-day trial, no card to start.
Frequently asked
- How do I stop my bot from posting the same thing twice?
- Idempotency keys: derive a stable key from the trigger (event ID, date, version tag), record it before attempting delivery, and skip if already handled. Then retry only 429 and 5xx errors — treating 4xx as final prevents retry storms from duplicating posts.
- Do I need OAuth to auto-post from a bot?
- Only for X and Reddit. Discord posts through a static webhook URL and Telegram through a static bot token — neither expires. Or put a unified publishing API in front of all four and your bot holds a single API key.
- Will platforms ban my account for automated posting?
- Not for automation itself — official APIs, webhooks, and bot tokens exist for it. Bans come from spam patterns: high-frequency duplicates, posting into communities you don't own, and ignoring rate limits. Keep frequency sane and post to your own channels.