Schedule icon
XExecution icon
Log icon
DiscordIncomingWebhook icon

Publish Scheduled X Posts from Copy Reviewed in Git

Run a weekly status broadcast on X with Kestra. The message line lives in Git as an input default, gets reviewed in pull requests, and posts on schedule.

Categories
Business

Social scheduling tools hide the copy inside their own UI, where nobody reviews it and nothing versions it. This blueprint keeps the recurring broadcast in Git instead. The custom message line is the default value of a flow input, so changing next week's copy is a pull request, with a reviewer reading every public word and the diff recording who approved it. A disabled-by-default weekly Schedule trigger publishes it through io.kestra.plugin.x.XExecution, an execution notification poster whose post always leads with the execution state and flow id, carries the reviewed line from customMessage, and ends with a link to the execution. That framing suits a status broadcast, the weekly digest post doubles as public proof that the publishing flow ran, and the execution history becomes the log of everything the account ever posted. Posts on X are public and instant, so the review happens in the PR, not after the post is live, and the 280 character cap covers the full rendered post.

How it works

  1. The post_text input holds the custom message line. Because flows deploy from Git, editing the default is a pull request with normal review.
  2. weekly_slot (io.kestra.plugin.core.trigger.Schedule) fires Wednesdays at 15:00 UTC once enabled, the calendar slot for the recurring broadcast.
  3. post_content (io.kestra.plugin.x.XExecution) authenticates with the OAuth 1.0a credential set and posts the execution notification. The task renders its bundled execution template, so the post opens with the execution state and flow id, carries the reviewed customMessage line, and closes with a link to the execution, all within the 280 character cap.
  4. log_published (io.kestra.plugin.core.log.Log) writes the published copy into the execution history, making every public post auditable.
  5. The errors block posts a Discord alert when publishing fails, so a missed calendar slot is noticed the same day, not at the end of the month.

What you get

  • Post copy under version control, with pull request review as the editorial gate.
  • A publishing log for free, every execution records exactly what went out and when, and every post links back to its execution.
  • One-off posts on demand, executing manually with a different post_text bypasses nothing, the same rendered format, 280 character cap, and audit trail apply.
  • A failure alert in Discord the moment a calendar slot is missed.

Who it's for

  • Developer relations teams who already review docs and blog posts in Git and want the same bar for social copy.
  • Small teams replacing a paid scheduling tool for recurring status broadcasts like changelog digests.
  • Anyone who has discovered a typo in a scheduled post after it published.

Why orchestrate this with Kestra

A scheduling SaaS owns your calendar, your copy, and your audit trail. Here Git owns the copy, Kestra owns the schedule and the credentials, and the execution history owns the record of what was published. Secrets keep the four OAuth values out of the flow file, the trigger ships disabled so nothing posts before the first review, and the errors block guarantees a silent miss becomes a loud message.

Prerequisites

  • An X developer app with OAuth 1.0a user context credentials for the posting account.
  • Flows deployed from Git, so input defaults change through pull requests.
  • A Discord incoming webhook for failure alerts.

Secrets

  • X_CONSUMER_KEY: X app consumer key (API key).
  • X_CONSUMER_SECRET: X app consumer secret (API secret).
  • X_ACCESS_TOKEN: OAuth 1.0a access token for the posting account.
  • X_ACCESS_SECRET: OAuth 1.0a access secret for the posting account.
  • DISCORD_WEBHOOK_URL: Discord incoming webhook for failure alerts.

Quick start

  1. Add the five secrets to your Kestra namespace.
  2. Execute the flow manually with the default copy, confirm the post appears on the X account, then delete the test post.
  3. Open a pull request changing post_text to your real copy and merge after review.
  4. Set disabled: false on the weekly_slot trigger.

How to extend

  • Add more triggers with different cron expressions for additional calendar slots, each slot can pass its own post_text through trigger inputs.
  • Rotate through a list of evergreen posts by selecting one from a KV store entry keyed on the week number.
  • Add customFields entries for structured extras such as the digest issue number, each renders as its own key-value line in the post.
  • Add a core.execution.Fail guard that rejects a message line long enough to push the full rendered post over 280 characters before it reaches the API.
  • Post the same copy to Discord announcement channels in a follow-up task for cross-channel publishing.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.