Skip to content

Send webhooks on post lifecycle events (create, update, delete, publish, fail) #1191

Description

@satputekuldip

🔖 Feature description

Implement webhook delivery for all post-related events so that any configured webhook URL receives an HTTP POST when something happens to a post or its data.

Events to support

  • post.created – A new post is created (draft or scheduled).
  • post.updated – An existing post is updated (content, schedule, etc.).
  • post.deleted – A post (or post group) is deleted.
  • post.published – A post is successfully published to the connected platform.
  • post.failed – Publishing fails (e.g. token refresh failure, platform error).

Payload shape

Each request is a POST with JSON body:

  • event – One of the event names above.
  • timestamp – ISO 8601 timestamp when the event was sent.
  • data – Event-specific payload (e.g. post id, content, integration, and for post.failed an error field).

Webhooks are filtered by organization and optionally by integration (existing “configured webhooks” behavior). Failed delivery or non-2xx responses should be logged and must not block the main flow (fire-and-forget with error handling and logging).

🎤 Why is this feature needed ?

  • Integrations and automation – Users (and tools like N8N, Make, Zapier) need to react to post lifecycle events (e.g. sync to CRM, notify Slack, run custom logic). Webhooks are the standard way to push these events.
  • Transparency – Knowing when a post was created, updated, published, or failed helps debugging, auditing, and building dashboards.
  • Alignment with product – The app already has a “Webhooks” section and copy (“get notified when something happens in Postiz via an HTTP request”). This feature makes that promise apply to post events specifically.

✌️ How do you aim to achieve this?

  1. Central sender
    In WebhooksService (or equivalent), add a method such as sendPostEvent(orgId, integrationId, event, data) that:

    • Loads webhooks for the org (filtering by integration when the webhook has integrations).
    • POSTs to each URL with { event, timestamp, data }.
    • Uses Promise.allSettled so one failure does not block others.
    • Catches errors, logs failures (and optionally non-2xx responses), and does not throw so callers are not failed.
  2. Call sites

    • post.created / post.updated – In the service that creates/updates posts (e.g. after a successful create/update), load the post payload (e.g. via getPostByForWebhookId or similar), then call sendPostEvent with post.created or post.updated. Wrap in try/catch and log on error; do not fail the API request.
    • post.deleted – Before or right after soft-deleting the post group, build a minimal payload (e.g. first post in group + integration), then call sendPostEvent with post.deleted. Same fire-and-forget and logging.
    • post.published – In the post publish workflow (e.g. after updatePost with releaseURL), call the webhook sender with the internal post id and event post.published (payload can come from getPostByForWebhookId or equivalent).
    • post.failed – Where the workflow sets the post state to ERROR (e.g. after changeState(..., 'ERROR', ...)), call the webhook sender with event post.failed and include the error message (e.g. in data.error).
  3. Orchestrator
    If webhook sending runs from Temporal (or similar), keep a single activity that: loads post by internal id, builds data, and calls the same sendPostEvent (or shared HTTP helper) so logic lives in one place and both backend and workflow can trigger the same events.

  4. Logging and robustness

    • Log when webhooks are loaded and when sending starts (event, org, number of URLs).
    • Log each delivery result: success (e.g. debug), non-2xx (warn with URL and status), and thrown errors (error with URL and message/stack).
    • Ensure no webhook failure (network, 4xx/5xx, or exception) causes the main operation (create/update/delete/publish) to fail.
  5. Payload consistency
    Use the same shape for post data across events (e.g. id, content, publishDate, releaseURL, state, integration summary) so consumers can rely on one schema; add error only for post.failed.

🔄️ Additional Information

No response

👀 Have you spent some time to check if this feature request has been raised before?

  • I checked and didn't find similar issue

Are you willing to submit PR?

Yes I am willing to submit a PR!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions