From 4204c434f8327c2a73014b309515642a4a20184a Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sun, 6 Sep 2026 16:50:53 -0300 Subject: [PATCH 1/2] docs: remove the automations module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit trypostit/trypost#333 removed Automations end to end. Drops the four knowledge-base pages and the nav group, then clears every reference the rest of the docs still made to the feature. Checked against origin/main of the app: - `CreatedVia` is now web/mcp/api only, so the webhooks payload table and the two automation FAQ accordions go with it - routes/console.php has no `automation:*` commands — out of the production scheduler table - Horizon has no automations supervisor — Horizon/scheduler/queue rows in installation.mdx, production.mdx and configuration.mdx reworded - SafeHttpFetcher no longer serves RSS, so TRYPOST_ALLOW_PRIVATE_NETWORK lists webhooks, URL media fetches and brand autofill instead `automations_rewritten` stays in the upgrading.mdx log sample: the 2026_08_21 social-accounts migration is byte-identical on main and still reads the table, so anyone crossing that version still sees the key. Co-Authored-By: Claude Opus 5 (1M context) --- docs.json | 9 -- knowledge-base/automations/introduction.mdx | 93 ------------- knowledge-base/automations/monitoring.mdx | 90 ------------- .../automations/triggers-and-nodes.mdx | 108 --------------- knowledge-base/automations/variables.mdx | 124 ------------------ knowledge-base/plans-and-billing.mdx | 2 +- knowledge-base/social-accounts.mdx | 2 +- knowledge-base/webhooks.mdx | 14 +- self-hosting/configuration.mdx | 4 +- self-hosting/installation.mdx | 6 +- self-hosting/production.mdx | 13 +- self-hosting/upgrading.mdx | 2 +- 12 files changed, 16 insertions(+), 451 deletions(-) delete mode 100644 knowledge-base/automations/introduction.mdx delete mode 100644 knowledge-base/automations/monitoring.mdx delete mode 100644 knowledge-base/automations/triggers-and-nodes.mdx delete mode 100644 knowledge-base/automations/variables.mdx diff --git a/docs.json b/docs.json index 169b249..9350aba 100644 --- a/docs.json +++ b/docs.json @@ -217,15 +217,6 @@ "knowledge-base/analytics" ] }, - { - "group": "Automations", - "pages": [ - "knowledge-base/automations/introduction", - "knowledge-base/automations/triggers-and-nodes", - "knowledge-base/automations/variables", - "knowledge-base/automations/monitoring" - ] - }, { "group": "Accounts", "pages": [ diff --git a/knowledge-base/automations/introduction.mdx b/knowledge-base/automations/introduction.mdx deleted file mode 100644 index e6cf6d0..0000000 --- a/knowledge-base/automations/introduction.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "Automations" -description: "Build flows that fetch, generate, and publish content on autopilot" -icon: "bolt" ---- - - - Automations are in **beta**. The building blocks below are stable, but expect new node types and refinements over time. - - -Automations let you wire together a **flow** that runs on its own: a trigger starts it, action nodes fetch data and generate content, and output nodes publish posts or call webhooks. Think of it as a visual pipeline for content that would otherwise be manual. - -A few things you can build: - -- Turn a blog or news **RSS feed** into a daily AI-written post. -- React whenever you **publish a post** and notify an external service. -- Pull data from any **HTTP API** and generate a post from it on a schedule. - -## How a flow works - -Every automation is a graph of **nodes** connected by lines: - - - - A schedule, or a post being published or scheduled. There is exactly one trigger per automation. - - - Fetch an RSS feed or HTTP endpoint, generate content with AI, branch on a condition, or wait. - - - Publish the generated post, or send an HTTP request from a [Webhook node](/knowledge-base/automations/triggers-and-nodes#output-nodes). For signed post-lifecycle notifications outside a flow, use [workspace webhooks](/knowledge-base/webhooks). - - - -Data flows **downstream**: each node can use the data produced by the nodes connected before it. See [Variables and expressions](/knowledge-base/automations/variables) for the full picture. - -## The editor - -Open an automation to land in the **Workflow** editor — a canvas where you drag nodes from the sidebar and connect them. Click any node to open its settings in that same panel. - -The detail screen has four tabs: - - - - The visual editor where you build and save the flow. - - - A log of every real run, with per-node detail. See [Monitoring](/knowledge-base/automations/monitoring). - - - Run health and output charts over a date range. - - - Rename, activate or pause, and delete the automation. - - - -## Build your first automation - - - - Go to **Automations** and click **New automation**. It opens in the Workflow editor with a schedule trigger already in place. - - - Click the trigger node and pick when it fires — a schedule, or a post event. See [Triggers and nodes](/knowledge-base/automations/triggers-and-nodes). - - - Drag nodes from the sidebar onto the canvas and connect them by dragging from one node's handle to the next. - - - In any text field, type `{{` to autocomplete the data available at that point in the flow. - - - Click **Run test** to execute the flow end-to-end with synthesized data before going live. - - - Click **Save**, then open the **Settings** tab and flip the status switch to activate. The automation now runs on its own. - - - -## Statuses - -An automation is always in one of three states: - -| Status | Meaning | -| --- | --- | -| **Draft** | Being built. It never runs. | -| **Active** | Live. The trigger fires and the flow runs. | -| **Paused** | Stopped. The trigger no longer fires until you reactivate it. | - - - Activating and pausing live in the **Settings** tab. You can pause anytime without losing your flow. - diff --git a/knowledge-base/automations/monitoring.mdx b/knowledge-base/automations/monitoring.mdx deleted file mode 100644 index 0c99f3a..0000000 --- a/knowledge-base/automations/monitoring.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "Testing and monitoring" -description: "Test runs, the invocations log, metrics, and lifecycle settings" -icon: "chart-line" ---- - -Once a flow is built, you can test it before going live and watch how it performs once it's running. - -## Testing - -Click **Run test** in the Workflow editor to execute the whole flow end-to-end and inspect what each node does. The result panel shows every node's **input** and **output** as it runs — the fastest way to confirm your expressions resolve correctly. - -There are two modes: - -| Mode | What it does | -| --- | --- | -| **Dry run** (default) | Runs every node, including AI generation, but **never publishes** a post or triggers external side effects. The generated content is shown but not saved. | -| **With real data** | Actually publishes posts and fires webhooks. Use it for a final end-to-end check. | - - - A **With real data** test really publishes and fires side effects. Use it deliberately. - - - - Test runs never appear in the Invocations log or Metrics — those report only on real, automatic executions. - - -## Invocations - -The **Invocations** tab is the run log: every time the live automation fires, it lands here, newest first. - -Each row shows: - -- **Timestamp** — when the run started -- **Run** — its ID (click to copy) -- **Status** — completed, failed, running, waiting, pending, or cancelled -- **Last message** — a summary and the number of steps it ran -- **Duration** — how long it took - -Click any row to expand it and see the **per-node breakdown** of that run. Use the **status filter** to narrow to failures, and the **search** box to find a run by ID. - - - Only real executions show up here. Tests you run from the editor are kept out so the log stays meaningful. - - -## Metrics - -The **Metrics** tab charts the automation's health and output over a date range you pick with the range picker. - -**Run health** - -- Total runs, completed, failed, in progress -- Success rate and average duration -- A chart of runs started, completed, and failed over time - -**Output** - -- Posts created by the automation -- A breakdown of those posts by platform - - - Like Invocations, Metrics count only real runs — test runs never inflate the numbers. - - -## Settings and lifecycle - -The **Settings** tab is where you operate the automation: - - - - Change the automation's name without touching the flow. - - - Flip the status switch to go live or stop. Pausing keeps the flow intact — the trigger simply stops firing until you reactivate. - - - In the **danger zone**, permanently remove the automation and its run history. This can't be undone. - - - -## Related - - - - The big picture and a build walkthrough. - - - Pass data between nodes. - - diff --git a/knowledge-base/automations/triggers-and-nodes.mdx b/knowledge-base/automations/triggers-and-nodes.mdx deleted file mode 100644 index 29433e0..0000000 --- a/knowledge-base/automations/triggers-and-nodes.mdx +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: "Triggers and nodes" -description: "Every building block you can drop into a flow" -icon: "diagram-project" ---- - -A flow is built from **nodes**. One trigger starts it; the rest fetch data, shape the flow, or deliver output. Drag nodes from the editor sidebar and connect them by dragging from a node's handle to the next node. - -## Triggers - -Every automation has exactly one trigger. It decides **when** the flow runs. - -| Trigger | Fires when | Provides | -| --- | --- | --- | -| **Schedule** | A cron-style schedule you set (every N minutes/hours/days, weekly, monthly, or a custom expression) | `trigger.event`, `trigger.fired_at` | -| **Post published** | One of your posts is published | `trigger.post.*` | -| **Post scheduled** | One of your posts is scheduled | `trigger.post.*` | - - - The trigger is created with the automation and can't be removed — you can only change its type. The schedule editor lets you pick an interval, time, weekdays, or a custom cron expression, and the timezone defaults to your workspace timezone. - - -## Source nodes - -Source nodes pull external data into the flow. Both expose two output handles — **has items** and **no items** — so you can branch on whether anything new came back. - - - - Reads an RSS/Atom feed from a **Feed URL** and exposes the matched item as `fetched.title`, `fetched.link`, `fetched.description`, and `fetched.pubDate`. - - TryPost remembers which items it has already seen, so the flow only runs for genuinely **new** entries. - - - Calls any HTTP endpoint. Configure the **URL**, **method** (GET/POST/PUT/PATCH/DELETE), authentication (none, bearer, basic, or API key), headers, and a body template. Auth tokens and passwords are stored encrypted. - - The JSON response becomes `fetched`, so you reference any field with `{{ fetched. }}`. Optional **items path**, **item key path**, and **item date path** settings let it walk a list response and dedupe items the same way the RSS node does. - - - - - **First run sets a baseline.** The first time a source node polls an existing feed or endpoint, it records what's already there and produces nothing — only items that appear *after* that trigger the flow. - - **New items fan out.** When a source node then finds several new items at once, each one runs the downstream nodes independently — five new feed entries produce five posts. A test run only ever processes the first item, so it stays predictable. - - -## Content node - - - Generates a post with AI and attaches it to one or more social accounts. - - - **Accounts** — which connected accounts and content types to post to. The most restrictive selected platform (smallest character limit) drives the generated copy so it fits everywhere. - - **Prompt** — your instruction. Reference upstream data with `{{ }}`, e.g. `Write a post about {{ fetched.title }}`. - - **Image count** — `0` for text-only (LinkedIn, X, Threads), `1` for a single image, or `2–10` for a carousel. The picker only offers counts the selected accounts support. - - **Use brand voice** — when off, the post stays faithful to the source instead of being rewritten in your brand persona. Useful for news curation. - - **Use brand visuals** — when off, generated images skip your brand colors and identity. - - Provides `generated.content` and `generated.post_url`. - - - - The Generate node uses the same content engine as **Create with AI** — see [AI features](/knowledge-base/ai-features) and [Brand profile](/knowledge-base/brand-profile). - - -## Flow nodes - -These shape the path the run takes. - - - - Branches the flow. Compares a **field** (any `{{ }}` expression) against a **value** using one of: `contains`, `not contains`, `equals`, `not equals`, `matches` (regex), `greater than`, or `less than`. The flow continues down the matching branch. - - - Pauses the flow for a **duration** in minutes, hours, or days before continuing. Useful for spacing out actions. - - - -## Output nodes - - - - Publishes the post created by an upstream Generate node. Choose a **mode**: - - | Mode | Result | - | --- | --- | - | **Now** | Publishes immediately | - | **Scheduled** | Schedules it, offset by N minutes from now (default 60) | - | **Draft** | Leaves it as a draft for you to review | - - - Sends an HTTP request to an external system. Configure the **URL**, **method**, headers, and a **payload template** where you can inject any `{{ }}` expression. - - This is a one-off call inside the flow — not a workspace [event webhook](/knowledge-base/webhooks). Posts this flow creates still emit workspace webhook events if you subscribed (`created_via` is `automation`). Use workspace webhooks when you want signed `post.published` / `post.failed` deliveries for every matching post. - - - Stops the automation at that point. Optional — a branch ends on its own when it has no more nodes. - - - -## What's next - - - - Pass data between nodes with `{{ }}`. - - - Test runs, the invocations log, and metrics. - - diff --git a/knowledge-base/automations/variables.mdx b/knowledge-base/automations/variables.mdx deleted file mode 100644 index a3cc61b..0000000 --- a/knowledge-base/automations/variables.mdx +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: "Variables and expressions" -description: "Pass data between nodes with double-brace expressions and reusable workflow variables" -icon: "code" ---- - -Automations move data between nodes with **expressions**. Wrap a path in double braces and TryPost replaces it at run time with the real value: - -```text -Write a short post about {{ fetched.title }} and link to {{ fetched.link }}. -``` - -Expressions work in **any text field** of any node — prompts, webhook payloads, HTTP bodies, condition fields, and more. - -## What data is in scope - -This is the rule that trips people up most: - - - A node can only use data from nodes connected **before** it (upstream). If a node isn't on the path leading into the current node, its data isn't available. - - -So a Generate node placed after a **Fetch RSS** node can use `{{ fetched.title }}`, but a node that runs *before* the fetch cannot — the data doesn't exist yet at that point in the flow. - - - In any field, type `{{` to open an autocomplete of exactly what's in scope at that node. Known references are highlighted; unknown ones are flagged so you catch typos before running. - - -## Expression reference - -Which expressions exist depends on which nodes run upstream. - -### Schedule trigger - -Available when the flow starts from a **Schedule** trigger. - -| Expression | Value | -| --- | --- | -| `{{ trigger.event }}` | The trigger event name | -| `{{ trigger.fired_at }}` | When the trigger fired | - -### Post trigger - -Available when the flow starts from a **Post published** or **Post scheduled** trigger. - -| Expression | Value | -| --- | --- | -| `{{ trigger.post.id }}` | The triggering post's ID | -| `{{ trigger.post.content }}` | Its content | -| `{{ trigger.post.status }}` | Its status | -| `{{ trigger.post.scheduled_at }}` | When it's scheduled | -| `{{ trigger.post.published_at }}` | When it was published | - -### Fetch RSS - -Available downstream of a **Fetch RSS** node. - -| Expression | Value | -| --- | --- | -| `{{ fetched.title }}` | The feed item's title | -| `{{ fetched.link }}` | Its link | -| `{{ fetched.description }}` | Its description | -| `{{ fetched.pubDate }}` | Its publish date | - -### HTTP Request - -Available downstream of an **HTTP Request** node. The whole JSON response is exposed as `fetched`, so you append whatever path you need: - -```text -{{ fetched.data.0.title }} -{{ fetched.user.name }} -``` - -| Expression | Value | -| --- | --- | -| `{{ fetched. }}` | Any field from the JSON response | - -### Generate - -Available downstream of a **Generate** node. - -| Expression | Value | -| --- | --- | -| `{{ generated.content }}` | The AI-generated post content | -| `{{ generated.post_url }}` | The generated post's URL | - -### Always available - -These work anywhere in any flow. - -| Expression | Value | -| --- | --- | -| `{{ variables.YOUR_KEY }}` | A workflow variable (see below) | -| `{{ now }}` | The current date and time | - -## Workflow variables - -Workflow variables are **reusable values** you define once and reference anywhere with `{{ variables.KEY }}`. They're scoped to a single automation. - -Use them for values you repeat across nodes or want to keep out of node fields — API keys, base URLs, account handles, a default hashtag. - - - - In the Workflow editor, switch to the **Variables** tab in the right sidebar. - - - Give it a **key** (letters, numbers, and underscores — e.g. `API_KEY`) and a **value**. - - - Use `{{ variables.API_KEY }}` in any field, in any node. - - - - - Variable values are **stored encrypted**. They're safe for secrets like API keys. - - -## See it in action - -The surest way to learn what's available is to run the flow: - - - Click **Run test** in the editor and open the result panel. Each node shows its exact **input** and **output**, so you can see precisely what every expression resolves to. See [Testing and monitoring](/knowledge-base/automations/monitoring). - diff --git a/knowledge-base/plans-and-billing.mdx b/knowledge-base/plans-and-billing.mdx index f107422..87d32c8 100644 --- a/knowledge-base/plans-and-billing.mdx +++ b/knowledge-base/plans-and-billing.mdx @@ -18,7 +18,7 @@ TryPost Cloud has one plan, priced per workspace. Every feature is included on e | Social accounts | One account on each network (your social set) | | Team members | Unlimited, with roles and approvals | | AI credits | 2,500 per month, pooled across your account | -| Included | Calendar, AI Copilot, automations, MCP server, REST API, analytics, signatures, labels | +| Included | Calendar, AI Copilot, MCP server, REST API, analytics, signatures, labels | Pricing is localized in some regions (for example, **R$60 / month** in Brazil). See the [pricing page](https://trypost.it/pricing) for current rates. diff --git a/knowledge-base/social-accounts.mdx b/knowledge-base/social-accounts.mdx index 87df830..4d5f233 100644 --- a/knowledge-base/social-accounts.mdx +++ b/knowledge-base/social-accounts.mdx @@ -97,7 +97,7 @@ If any of these detects a disconnected or expired account, the workspace owner r ## Reconnecting an account -A card that needs attention shows a **Reconnect** button. Reconnecting refreshes that specific card — it keeps its posts, its scheduling history, and its place in your automations. It never creates a second card. +A card that needs attention shows a **Reconnect** button. Reconnecting refreshes that specific card — it keeps its posts and its scheduling history. It never creates a second card. Because it is tied to one card, you have to authorize **the same account** you are reconnecting: diff --git a/knowledge-base/webhooks.mdx b/knowledge-base/webhooks.mdx index 77c1010..00368bf 100644 --- a/knowledge-base/webhooks.mdx +++ b/knowledge-base/webhooks.mdx @@ -6,7 +6,7 @@ icon: "webhook" Workspace webhooks POST a signed JSON payload to a URL you control whenever a subscribed post event fires. Use them to sync a CRM, trigger an internal job, or keep another system in step with TryPost. -They are **outgoing** event subscriptions for the workspace. They are not the [automation Webhook node](/knowledge-base/automations/triggers-and-nodes#output-nodes) (a one-off HTTP call inside a flow), and they are not inbound Telegram/Stripe webhooks. +They are **outgoing** event subscriptions for the workspace — not inbound Telegram/Stripe webhooks. ## Who can manage webhooks @@ -62,7 +62,7 @@ Publish now (dashboard **Post now**, REST `PUT` with `status=publishing`, or `pu Edits that do **not** change status send nothing: content, media, labels, platforms, or a new `scheduled_at` on a post that is already `scheduled`. [Duplicate](/knowledge-base/posts#duplicating-a-post) is a new post, so it fires `post.created`. A failed or published post cannot be republished in place — duplicate it and you will get a fresh lifecycle. -There are no events for comments, mentions, social-account disconnects, or team changes — those stay in [notifications](/knowledge-base/notifications). AI Create has no dedicated `post.ready` event; when the draft is saved you get `post.created` (`created_via` is `web`). Posts created by an [automation](/knowledge-base/automations/introduction) still fire these events (`created_via` is `automation`). Deleting a [workspace](/knowledge-base/workspaces) removes the webhooks with it and does **not** send `post.deleted` for each post. +There are no events for comments, mentions, social-account disconnects, or team changes — those stay in [notifications](/knowledge-base/notifications). AI Create has no dedicated `post.ready` event; when the draft is saved you get `post.created` (`created_via` is `web`). Deleting a [workspace](/knowledge-base/workspaces) removes the webhooks with it and does **not** send `post.deleted` for each post. ## Receive a delivery @@ -151,7 +151,7 @@ For every post event except `post.deleted`, `data` is the post at the moment of | `workspace_id` | Workspace UUID | | `user_id` | Author user UUID | | `status` | `draft`, `scheduled`, `publishing`, `published`, `partially_published`, or `failed` | -| `created_via` | `web`, `api`, `mcp`, `automation`, or `null` | +| `created_via` | `web`, `api`, `mcp`, or `null` | | `content` | Post body. May include HTML from the editor (e.g. `

…

`), or be an empty string | | `scheduled_at` / `published_at` / `created_at` / `updated_at` | ISO 8601, or `null` — not the `Y-m-d H:i:s` strings used by [`GET /posts`](/api-reference/endpoint/list-posts) | | `author` | `{ id, name }` only — no email — or `null` | @@ -303,9 +303,6 @@ List and update responses omit `signing_secret`. Create, get, and rotate return Five deliveries in a row exhausted their retries. Fix the endpoint, then set status back to **enabled**. - - Workspace webhooks fire on post lifecycle events and are always signed the same way. The [automation Webhook node](/knowledge-base/automations/triggers-and-nodes#output-nodes) is an HTTP step inside a flow — you pick the method, headers, and body template. - Seven days. Older rows are pruned daily. Deleting the webhook removes the remaining logs. @@ -328,12 +325,9 @@ List and update responses omit `signing_secret`. Create, get, and rotate return No. `post.scheduled` only fires when status becomes `scheduled`. Editing `scheduled_at` on an already-scheduled post is silent. - No. Workspace webhooks are always `POST` with `Content-Type`, `User-Agent`, and `X-Webhook-Signature`. For a custom request, use the [automation Webhook node](/knowledge-base/automations/triggers-and-nodes#output-nodes). + No. Workspace webhooks are always `POST` with `Content-Type`, `User-Agent`, and `X-Webhook-Signature`. No. Only the seven post lifecycle events. Comments, mentions, and account disconnects stay in [notifications](/knowledge-base/notifications). - - Yes. Create, schedule, publish, and delete still emit the matching events. `created_via` is `automation`. That is separate from the [automation Webhook node](/knowledge-base/automations/triggers-and-nodes#output-nodes). - diff --git a/self-hosting/configuration.mdx b/self-hosting/configuration.mdx index a86bd08..96eb525 100644 --- a/self-hosting/configuration.mdx +++ b/self-hosting/configuration.mdx @@ -136,7 +136,7 @@ BROADCAST_CONNECTION=reverb | Variable | Recommended | Why | |----------|-------------|-----| -| `QUEUE_CONNECTION` | `redis` | Horizon processes Redis queues (publishing, notifications, automations) | +| `QUEUE_CONNECTION` | `redis` | Horizon processes Redis queues (publishing, notifications, webhooks) | | `CACHE_STORE` | `redis` | Cache + `onOneServer()` schedule locks across instances | | `SESSION_DRIVER` | `database` | Durable sessions behind multiple app workers | | `BROADCAST_CONNECTION` | `reverb` | Real-time dashboard updates | @@ -551,7 +551,7 @@ TRYPOST_USER_AGENT="TryPost.it/1.0 (+https://trypost.it)" | Variable | Default | Description | |----------|---------|-------------| -| `TRYPOST_ALLOW_PRIVATE_NETWORK` | `false` | When `true`, allows HTTP requests from TryPost (RSS, [workspace webhooks](/knowledge-base/webhooks), URL media fetches, etc.) to private/internal network addresses. Keep `false` unless you intentionally need that for a private network install. | +| `TRYPOST_ALLOW_PRIVATE_NETWORK` | `false` | When `true`, allows HTTP requests from TryPost ([workspace webhooks](/knowledge-base/webhooks), URL media fetches, brand autofill, etc.) to private/internal network addresses. Keep `false` unless you intentionally need that for a private network install. | | `TRYPOST_USER_AGENT` | `TryPost.it/1.0 (+https://trypost.it)` | `User-Agent` sent on outgoing HTTP, including webhook deliveries and test pings. | ## Next Steps diff --git a/self-hosting/installation.mdx b/self-hosting/installation.mdx index 9d963e7..69a2001 100644 --- a/self-hosting/installation.mdx +++ b/self-hosting/installation.mdx @@ -69,7 +69,7 @@ FILESYSTEM_DISK=public |-------|-----| | `APP_KEY` | Already set by `key:generate` — encrypts sessions, cookies, encrypted data | | Database | Where posts, users, and Passport clients live. The block above is PostgreSQL; for MySQL use `DB_CONNECTION=mysql` on port `3306` — see [Database](/self-hosting/configuration#database) | -| Redis + queue/cache drivers | Horizon publishes posts and runs automations from Redis queues | +| Redis + queue/cache drivers | Horizon publishes posts and processes background jobs from Redis queues | | `BROADCAST_CONNECTION=reverb` | Live dashboard updates | | `FILESYSTEM_DISK=public` | Local media on disk (use `s3` / `r2` / `spaces` for object storage) | | `SELF_HOSTED=true` | Disables Stripe billing and public `/register` | @@ -175,9 +175,9 @@ This starts `php artisan serve`, a queue listener, log tail, and Vite. Open `htt | Process | Command | Purpose | |---------|---------|---------| | Web (PHP-FPM + Nginx) | see [Production](/self-hosting/production#nginx-configuration) | Serve HTTP | -| **Horizon** | `php artisan horizon` | Queues — publish posts, notifications, automations, webhooks | +| **Horizon** | `php artisan horizon` | Queues — publish posts, notifications, webhooks | | **Reverb** | `php artisan reverb:start` | WebSockets | -| **Scheduler** | cron → `php artisan schedule:run` | Due posts, token refresh, automations | +| **Scheduler** | cron → `php artisan schedule:run` | Due posts, token refresh, stuck-post recovery | Full Supervisor configs, Nginx (including Reverb `/app/` + `/apps/`), SSL, and caches: [Production setup](/self-hosting/production). diff --git a/self-hosting/production.mdx b/self-hosting/production.mdx index dd21615..332d42d 100644 --- a/self-hosting/production.mdx +++ b/self-hosting/production.mdx @@ -61,7 +61,6 @@ TryPost uses queues for critical background processing: - **Sending notifications** (email and in-app) - **Verifying social account connections** - **Processing analytics events** -- **Running automations** Without a running queue worker, scheduled posts will not be published. Use Supervisor to keep Horizon running. @@ -190,15 +189,11 @@ sudo certbot --nginx -d your-domain.com ## Scheduled Tasks (Cron) -TryPost uses Laravel's task scheduler for several recurring jobs. The scheduler **must** run every minute or scheduled posts won't publish, automations won't fire, expiring tokens won't refresh, and stuck posts won't recover. +TryPost uses Laravel's task scheduler for several recurring jobs. The scheduler **must** run every minute or scheduled posts won't publish, expiring tokens won't refresh, and stuck posts won't recover. | Command | Schedule | Purpose | |---------|----------|---------| | `posts:process-scheduled` | every minute | Dispatches `PublishPost` jobs for posts that are due | -| `automation:fire-schedule` | every minute | Fires time-based automation triggers | -| `automation:process-delays` | every minute | Advances automation runs waiting on delay nodes | -| `automation:recover-stuck-runs` | every 5 minutes | Recovers automation runs stuck mid-flight | -| `automation:prune-dry-runs` | every 10 minutes | Prunes dry-run automation history | | `social:refresh-expiring-tokens` | every 15 minutes | Refreshes OAuth tokens that are about to expire | | `social:recover-stuck-posts` | every 30 minutes | Detects posts stuck in `publishing` and retries or fails them | | `social:check-connections` | daily | Verifies every connected social account still has a valid token | @@ -217,7 +212,7 @@ Add this line: ``` - This is required. Without the cron job, scheduled posts will not be published automatically, automations will stall, and social tokens will expire silently. + This is required. Without the cron job, scheduled posts will not be published automatically and social tokens will expire silently. ## WebSocket Server (Reverb) @@ -275,9 +270,9 @@ Make sure all of these are in place in production: | **Storage link** | `php artisan storage:link` (once, if `FILESYSTEM_DISK=public`) | Local media URLs — skip for S3 / R2 / Spaces | | **Redis** | `QUEUE_CONNECTION=redis` + Redis up | Queues, cache, schedule locks | | **Mail** | SMTP or SendKit | Invites, password reset, alerts | -| **Horizon** | `php artisan horizon` (Supervisor) | Publishes posts, notifications, automations, and [webhooks](/knowledge-base/webhooks) | +| **Horizon** | `php artisan horizon` (Supervisor) | Publishes posts, notifications, and [webhooks](/knowledge-base/webhooks) | | **Reverb** | `php artisan reverb:start` (Supervisor) | Real-time WebSocket updates | -| **Scheduler** | cron → `schedule:run` every minute | Due posts, token refresh, automations | +| **Scheduler** | cron → `schedule:run` every minute | Due posts, token refresh, stuck-post recovery | If Horizon, Reverb, or the scheduler are not running, TryPost will not function correctly. Scheduled posts won't publish, notifications won't send, and the dashboard won't update in real time. diff --git a/self-hosting/upgrading.mdx b/self-hosting/upgrading.mdx index 92dceb6..3f7a052 100644 --- a/self-hosting/upgrading.mdx +++ b/self-hosting/upgrading.mdx @@ -27,7 +27,7 @@ This release adds a database constraint that a workspace cannot hold the same id **Why it matters:** earlier versions could store the same account more than once — the per-network guard was skipped on self-hosted installs, and Pinterest created a fresh row on every connect. Duplicates like that would block the new constraint, so the migration merges them first. -For each duplicated identity it keeps the **most recently created** account, moves that account's scheduled posts and automation targets onto the survivor, and deletes the rest. +For each duplicated identity it keeps the **most recently created** account, moves that account's scheduled posts onto the survivor, and deletes the rest. Merging can leave a post aimed at the same account twice, which would publish it twice. Those repeats are collapsed: From 554c55eddc775b3288d1071d3694c66b9c52d4b0 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sun, 6 Sep 2026 16:55:08 -0300 Subject: [PATCH 2/2] docs: keep webhooks in the production queue list Dropping the automations bullet left the queue list without the one remaining Horizon supervisor the docs describe elsewhere. installation.mdx and the production checklist both already say Horizon delivers webhooks. Co-Authored-By: Claude Opus 5 (1M context) --- self-hosting/production.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/self-hosting/production.mdx b/self-hosting/production.mdx index 332d42d..c9b9fb5 100644 --- a/self-hosting/production.mdx +++ b/self-hosting/production.mdx @@ -61,6 +61,7 @@ TryPost uses queues for critical background processing: - **Sending notifications** (email and in-app) - **Verifying social account connections** - **Processing analytics events** +- **Delivering [webhooks](/knowledge-base/webhooks)** and their retries Without a running queue worker, scheduled posts will not be published. Use Supervisor to keep Horizon running.