Maintained Open source Creator and maintainer 2026 - present

Postiz Support Bot

The Postiz support desk, as software. Discord for customers, Intercom for agents.

Every support request becomes a private Discord thread bridged to Intercom, so customers stay where the community is and agents stay in real support tooling. It also carries the inactivity automation Intercom cannot do on API-created conversations, and a full Stripe billing console.

What it is

The support desk behind Postiz, as software.

Every support request becomes a private Discord thread that is bridged to Intercom. Discord is the customer's channel because that is where the community already is. Intercom is the agents' channel because that is where support tooling actually lives. The bot is the thing that keeps those two truths from becoming two inboxes.

The split that makes it work

An earlier version of this had agents working tickets inside Discord, with slash commands for status, notes, reminders, escalation, canned replies and reports.

All of that was removed. Agents work in Intercom now, and the bot keeps four commands that Intercom genuinely cannot cover: setup, config, ticket search, and the billing console.

Deleting most of your own feature surface is not a comfortable release to ship. It was the right one. Every retired command was a worse version of something Intercom already did properly, and maintaining worse versions of other people's features is how a support bot turns into a support product nobody asked for.

The automation Intercom cannot do

Intercom's workflow triggers do not fire on conversations created through its API, which is every conversation this bridge creates. So the inactivity automation had to move here.

Bridged tickets get per-status reminder settings. A customer-idle nudge pings the customer in their Discord thread. An agent-idle nudge posts an internal note and reopens the Intercom conversation instead, because nagging the customer about the agent's silence is not the behaviour anyone wants.

Native Intercom conversations that were never bridged get their own sweeper, with agent-idle notes, customer-idle nudges, and auto-close after a set number of unanswered ones. Native tickets get notes only and are never auto-closed.

Billing

A full Stripe console sits inside Discord.

Customers get self-service refund and cancel, with guardrails: an amount cap, a per-24-hour velocity limit both globally and per user, and a minimum membership age. Staff get a much larger admin panel behind it.

Dispute and early-fraud-warning webhooks are registered programmatically rather than through the Stripe dashboard, so standing it up needs no console access. Refund-request tickets stay Discord-only and are never mirrored to Intercom.

Dispute evidence, drafted against the real source

Drafting dispute evidence is the one place an LLM earns its place here.

The bot spawns a coding CLI with its working directory pointed at a local clone of the Postiz source and documentation. Policy claims in the evidence are grounded in what the code and docs actually say, rather than in what the model remembers about a product it has never seen. A scheduler refreshes those snapshots by downloading the tarball and swapping it atomically, because the runtime image has no git binary in it.

Short dispute summaries run on a cheaper model through the direct API. Model choice and rate limits are configured at runtime, not at deploy.

Everything durable runs on Temporal

There is no in-process scheduler and no cron fallback. Long-lived per-ticket workflows carry reminders, auto-close, the reopen window and the Intercom outbox pump. Looping singletons handle knowledge-base refresh, snapshots, cleanup, disputes, the inactivity sweeper, and the SLA clock.

Turning Temporal off is a pause, not a bypass. The worker drains, background work stops, fire-and-forget signals keep landing server-side and process on resume, and synchronous actions like status changes and refunds fall back to running in process.

The database creates itself

The deployment environment cannot run the Prisma CLI, so the application builds and updates its own schema at boot through idempotent statements, and verifies the live columns against a manifest afterwards. Drift produces a warning by default and can be made fatal in development and CI.

It is not how anybody would choose to do migrations. It is what the constraint allowed, and making the drift check explicit is what keeps it honest.

Observability

Sentry for errors, spans and wide-event logs. An optional InfluxDB exporter carries billing events, dispute gauges, AI usage and cost per run, bridge health and a heartbeat, with Grafana dashboards on top. The Sentry release is the same six-character identifier as the Temporal worker deployment version, so an error and the worker that produced it can be lined up without guessing.

Almost every setting lives in a runtime config panel rather than in environment variables, because the deployment has no editable environment to change.