Plugin
Changelog
Every release of Webhook Actions — the free WordPress plugin.
v1.14.0 2026-06-03
- → NewActivity History — persistent audit log of every admin and API-token action across webhooks, tokens, settings, logs, queue, schemas, chains, and cron. Each entry records the actor (session user or API token with a name hint), the action type, a structured context diff (old → new values for updates), and a timestamp. Designed to trace automated and AI-assisted changes end-to-end
- → NewAI prompt and reasoning capture — REST requests carrying
X-FSWA-PromptorX-FSWA-Reasonheaders have those values stored in the activity log context and surfaced in the Activity view as a highlighted card above the change diff; intended for AI agents that perform admin actions via API tokens - → NewExternal Cron page *(Pro)* — dedicated admin page for managing the external cron trigger: enable/disable toggle, mode selector, configurable interval and batch-size sliders, a live heartbeat chart (line + bar combo), monitor status bar, and an alert banner when the last ping failed or is stale
- → New
fswa_cron_token_regeneratedaction hook — fires after the cron secret is regenerated, allowing integrations (e.g. Pro Uptime Kuma sync) to update their stored monitor URL - → Fixedcreated and deleted activity log entries for webhooks and tokens now include the full entity data (name, URL, scope, etc.) in context instead of an empty object
- → Fixedwebhook toggle events now correctly capture old and new
is_enabledstate; webhook, settings, and schema update events capture a full old/new diff - → Fixedchain and chain-link CRUD actions (create, update, delete, link add/remove) are now covered by Activity History
- → ImprovedSnippets (Pro) added to the Activity History filter list; Activity tab repositioned after External Cron in the navigation
- → DBadds
fswa_activity_logstable; idempotent, safe to run on existing installs
v1.13.1 2026-05-21
- → FixedReplay and Retry buttons on the single-webhook logs page (
#/webhooks/:id/logs) did nothing — the events emitted by the table were never handled. Both the row button and the Log Details panel button now work correctly, including the "Execute Now" flow and the replay success dialog - → Fixedbumped tested-up-to WordPress version to 7.0
v1.13.0 2026-05-18
- → NewWebhook Chains — a webhook completing successfully (2xx) can now trigger one or more downstream webhooks. Chains are first-class entities with names and links; each chained webhook receives the upstream response body, sent payload, and pre-mapping original payload as its starting
args, so the next step can map fields off the previous step's response (e.g. capture a HubSpot deal ID and pass it to a Create Line Items webhook). Replaces ad-hocwp_remote_postcalls in post-dispatch snippets with proper webhooks that get logs, retries, conditions, headers, and URL templates - → NewTriggers section on Edit Webhook now offers a "Use other Webhooks as triggers" toggle. When enabled the webhook is wired as a chain target — pick an existing chain or create a new one, then select which upstream webhooks should fire it (with a search box for filtering long lists). Defaults to synchronous execution so the response is available immediately
- → NewWebhooks list view groups webhooks by chain with a left accent border and chain icon; a webhook involved in multiple chains is rendered in each group. An "Unchained" section holds webhooks with no chain involvement
- → NewChain group headers now have inline Rename and Delete buttons. Deleting a chain shows an impact callout listing which downstream webhooks would become orphans, and a chain is automatically removed when its last link is deleted
- → NewOrphan badge — any webhook left with no triggers (after a chain or link deletion, for instance) shows a destructive-styled broken-link icon and "No trigger assigned" label so it stays visible and editable in the list
- → NewDeleting a webhook involved in any chain shows an enhanced confirmation modal listing the affected chains and downstream impact, then cascade-removes the chain links and their synthetic trigger rows
- → NewLogs and Queue views render chain-link triggers as human-readable pills (
Chain name ← Source webhook) instead of the rawfswa_chain_link:Nsynthetic name, and gain a "Filter by chain" dropdown that narrows the list to deliveries triggered by a specific chain - → NewREST endpoints
/fswa/v1/chains(CRUD) and/fswa/v1/chains/{id}/links(manage source→target edges). Cycles are rejected at save time across all chains. Both/logsand/queuelist endpoints now accept achain_idquery parameter - → Fixed
X-Event-IdandX-Event-Timestamprequest headers were emitted empty when Payload Mapping or Code Glue pre-dispatch reshaped the payload and dropped theeventblock. Headers now resolve from the log row first (single source of truth) and only fall back to the payload if needed - → Fixedpayload preview in the Payload Mapping editor could break the page layout when a captured payload string contained HTML (e.g. a chain-link trigger carrying an upstream HTML response body in
args.0.response.raw_body). String values are now properly HTML-escaped before being injected into the highlighted JSON preview — also closes a stored-XSS surface in the admin UI - → DBnew
fswa_chainsandfswa_chain_linkstables; idempotent, safe to run on existing installs
v1.12.2 2026-05-14
- → Fixed"Queue appears stuck" health banner staying visible when delivery logs were left in
pendingstate with no live queue row (e.g. legacy rows from older queue-status semantics, or worker crashes between updating queue and log state); the queue processor now reconciles such orphaned pending logs on every run and marks thempermanently_failed - → Improvedtrigger conditions UI — renamed the "Evaluate against" toggle to "Evaluate conditions against" and added an inline info tooltip explaining the Original (pre-mapping) vs Transformed (post-mapping) choice
- → Removedmisleading Pro upgrade badge from the conditions evaluate-against toggle — choosing between original and transformed payload for conditions has always been a free-plan feature
v1.12.1 2026-05-12
- → Docscorrected README to reflect that type casting (in both payload mapping and conditions) is a free-plan feature; removed misleading Pro markers
- → Docsadded WooCommerce → n8n step-by-step example showing conditional dispatch wired up via a Claude Code agent
- → Docsreformatted
fswa_webhook_urlPHP code sample so it renders as a single code block on the wordpress.org plugin page - → No code changes
v1.12.0 2026-05-12
- → New
fswa_webhook_payloadfilter — Pro-extensible enrichment of the outgoing payload before dispatch; receives the mapped payload, webhook id, trigger name, and pre-mapping original payload - → New
fswa_glue_post_dispatchaction — fires after every delivery with response code/body, mapped payload, webhook, and original pre-mapping payload; intended for Pro post-dispatch snippets - → New
fswa_webhook_urlfilter — Pro-extensible URL template expansion; passes the URL, post-glue payload, webhook, trigger, and original pre-mapping payload as fallback for dot-notation token resolution - → Newper-trigger
conditions_evaluate_onsetting (original / transformed) — choose whether conditions evaluate against the pre-mapping payload or the post-mapping/post-glue payload; segmented toggle in the trigger schema panel - → Newdual-resolution for custom headers and URL parameters — when a dot-notation path resolves to null in the post-glue payload, falls back to the pre-mapping original payload; matches existing condition resolution semantics
- → Newcollapsible Original Payload section in the Mapping editor — inspect the pre-glue/pre-mapping payload while authoring field mappings
- → Improved
object_containsoperator — also matches when the value is present at the current array level, not only nested; works for array-typed WooCommerce fields likemeta_dataandline_items - → Improveddelivery log writes —
request_payload,original_payload, andmapping_appliedare now refreshed after thefswa_webhook_payloadfilter mutates the payload - → Fixedcondition evaluation order — re-evaluates conditions after Code Glue pre-dispatch when
conditions_evaluate_onistransformed - → Fixedpre-glue filter application in synchronous mode — applied exactly once during the inline attempt instead of once before enqueue and again at send
v1.11.0 2026-05-06
- → New
array_containscondition operator — checks whether an array field contains a specified value; works with flat arrays and arrays of objects - → New
object_containscondition operator — checks whether an object field contains a specified key (optionally filtered to a specific property within nested objects using akey=parameter) - → New
stringifytype cast — JSON-encodes array and object field values into a string before comparison, enabling string-based operators on complex nested structures - → ImprovedFieldSelector — split navigate and select actions; added a dedicated "+" button to select non-leaf fields (arrays and objects) directly without drilling further into children
- → ImprovedConditionsEditor layout — responsive three-row design on small screens (field + delete on top row, cast + operator on second row, value on third);
object_containsexposes an inline property name input when a key filter is needed - → Delivery log detail messages now include the property key when
object_containsis matched against a specific property
v1.10.0 2026-05-03
- → Newper-webhook synchronous execution mode — when enabled, the webhook fires inline during the WordPress request that triggers it, bypassing the queue; a warning dialog explains the performance impact before enabling; dismissal can be stored permanently per-browser
- → First synchronous attempt runs blocking in the current request; retryable failures (5xx, transport errors) automatically fall back to the async queue starting at attempt 2 with standard exponential backoff; non-retryable failures (4xx) are marked permanently failed immediately
- → Newsync execution toggle to the Webhooks list view — enable or disable per webhook without opening the edit screen
- → NewRequest Headers and Query Parameters sections to delivery log details — inspect the exact headers and URL parameters sent with each delivery
- → Newcollapsible Request Payload and Original Payload sections in delivery log details — collapse state is persisted in browser storage so the panel opens in the same state on next visit
- → FixedGET and DELETE webhooks not including custom headers or URL parameters in deliveries
- → Newreplay support for skipped (condition-failed) log entries — re-evaluate a previously skipped event after changing the webhook's conditions
v1.9.0 2026-05-03
- → Newconfigurable HTTP method per webhook — choose GET, POST, PUT, PATCH, or DELETE (default: POST)
- → Newcustom request headers per webhook — define key/value pairs sent with every delivery; values support dot-notation paths resolved against the outgoing payload
- → NewURL query parameters per webhook — appended to the endpoint URL; for GET and DELETE requests, query params are the primary payload transport (no body); a full
?payload=fallback is used when no params are configured - → New
fswa_capture_payloadfilter — modify or enrich the payload stored as the captured example without affecting what is dispatched; designed for Pro extensions and custom PHP snippets - → New
fswa_webhook_responseaction — fires after every HTTP response is received per webhook; intended for Pro extensions to run custom logic against the response (parse body, trigger follow-up actions, store data) - → New
request_headersandrequest_urlcolumns to delivery logs — the exact headers sent and the fully resolved URL (with query params applied) are now stored and visible in the delivery log - → Improvedtest webhook drawer — defaults to "Captured + Mapping" payload source; result panel now shows HTTP method, fully resolved endpoint URL, sent headers, and request body
v1.8.0 2026-04-28
- → Newtype casting in Conditions — cast field values to number, string, or boolean before comparison; enables greater than / less than on numeric strings (e.g. WooCommerce price "100.50")
- → Newtype casting in Payload Mapping — cast field values before sending to external APIs
- → New
X-Webhook-Idrequest header — sent with every delivery; carries the webhook's stable UUID so downstream systems can identify which webhook configuration triggered the request when multiple webhooks share the same endpoint - → Fixedtest webhook result label — now reflects actual HTTP status: 2xx = Success, 3xx = Redirect, 4xx = Client Error, 5xx = Server Error (previously all completed deliveries showed green "Success")
v1.7.0 2026-04-27
- → New"Test Webhook" delivery with run-now and queue modes — test webhook delivery without triggering real WordPress events
- → Newconditional webhook dispatch — filter events by payload field values before dispatch; free plan includes one condition with AND match
- → Newfield selector with live preview in the Conditions editor to build conditions from real example payloads
- → Fixedattempt history timestamps displayed in browser local time
- → Renamed plugin to "Webhook Actions by Flow Systems"
- → NewWebhook Actions Pro integration tab for license management
v1.6.2 2026-04-05
- → Fixedgraceful handling of 409 responses when a queue job was already completed in a background process
- → Fixedmapping editor not supporting dot-containing keys (e.g. Gravity Forms sub-field IDs like
6.1)
v1.6.1 2026-03-28
- → Fixedschema API endpoints for triggers containing forward slashes (e.g.
ivyforms/form/before_submission) returning 404 on Apache — admin now uses double-encoding to pass through Apache's encoded-slash restriction
v1.6.0 2026-03-28
- → Newbuilt-in IvyForms integration — automatically normalizes IvyForms field objects and enriches submission payloads for
ivyforms/form/before_submissionandivyforms/form/after_submissionhooks - → NewIntegrationLoader to centralize third-party integration registration
- → Fixedforward slashes not being recognized in hook names during dynamic trigger discovery
- → Fixedpercent-encoded slashes in schemas REST route trigger param not being decoded correctly
- → Fixedtrigger name not being URL-encoded when building schemas API requests from the admin UI
v1.5.0 2026-03-23
- → Newbuilt-in CF7 to webhook integration — automatically sends CF7 submissions as structured webhook payloads (form id, title, fields, meta, uploaded files)
- → New
fswa_normalize_objectfilter for custom third-party object normalization - → New
get_properties()fallback in payload normalization to handle objects with private or protected properties - → Improvedhook registration to capture all hook arguments by default (PHP_INT_MAX accepted_args)
v1.4.0 2026-03-22
- → NewAction Scheduler support for queue processing (auto-detected, no configuration required)
- → Automatic migration from WP-Cron to Action Scheduler when available
- → Newoption to move admin menu under Tools for cleaner dashboard navigation
- → Newdynamic trigger discovery via static PHP source scan
- → Reduced triggers API responses size
- → Fixedinput focus styles in admin forms
v1.3.2 2026-03-15
- → Fixed
auth_headerfield being exposed to API tokens withoutfullscope — read and operational tokens now receive a permission notice instead
v1.3.1 2026-03-15
- → Fixedlog details dialog showing error message from the first attempt instead of the most recent one
- → New[REST API Reference](https://wpwebhooks.org/webhook-wordpress-plugin-api/) link to the plugin description
v1.3.0 2026-03-15
- → NewAPI token authentication for the REST API — create tokens with
read,operational, orfullscope; tokens are SHA-256 hashed at rest and accepted viaX-FSWA-Tokenheader,Authorization: Bearer, or?api_token=query param - → Newtoken expiry support with optional
expires_at; expired tokens are rejected at auth time and visually flagged in the admin panel - → Newtoken rotation — issues a new secret while preserving all other token fields; optionally updates expiry in the same request; revived expired tokens auto-extend to +30 days by default
- → New
PATCH /tokens/{id}endpoint for updatingexpires_atindependently of rotation - → New
fswa_api_tokensdatabase table (migration 1.3.0) - → Applied scope-based dual auth (
manage_optionssession OR valid token) to all existing REST controllers:readfor GET endpoints,operationalfor toggle/retry/replay,fullfor create/update/delete - → Fixedall admin UI date displays (logs, queue, schema panel) to show times in the user's local timezone instead of raw UTC
- → Fixeddate range filters (logs, queue) to correctly convert local picker values to UTC before querying
- → Improvedlog details panel — error message, response body, HTTP code, and duration now reflect the most recent attempt history entry rather than the top-level log fields
v1.2.1 2026-03-07
- → Fixedretry returning 500 when a log has multiple queue jobs (replay + original) —
findByLogIdnow returns the most recent job viaORDER BY id DESC - → Fixed
forceRetryrejecting jobs with statusfailed— restoredfailedto the allowed status list alongsidependingandpermanently_failed
v1.2.0 2026-03-07
- → Newpersistent delivery stats table (
fswa_stats) for long-term aggregation - → Newreplay button for successful log entries
- → New"Execute Now" button in replay dialog with auto-open log details
- → Newfull attempt history with response body, accordion UI, and next attempt countdown
- → Replaced browser
confirm()dialogs with modal confirmations - → Fixedqueue stats — removed stale
failedstatus, addedpermanently_failed - → Fixedretry eligibility check to use log status instead of queue job status
- → Fixed"Execute Now" button visibility to only show for pending jobs
v1.1.1 2026-03-01
- → Fixed
permanently_failedentries being excluded from total and error delivery statistics ingetStats(),getAllTimeStats(), andLogArchiver::aggregateStatsBeforeDeletion()
v1.1.0 2026-02-28
- → Newevent identity: each trigger dispatch generates a shared UUID and timestamp sent as
X-Event-Id/X-Event-Timestampheaders and embedded in the payload underevent.{id,timestamp,version} - → Newsmart retry routing: 5xx and 429 responses trigger an automatic retry with exponential backoff; 4xx and 3xx responses are immediately marked as permanently failed
- → New
permanently_failedstatus for non-retryable delivery failures - → Newattempt history: each delivery attempt is recorded as a JSON array on the log entry, visible in the admin timeline view
- → Newper-log retry and bulk retry REST endpoints (
POST /logs/{id}/retry,POST /logs/bulk-retry) - → New
event_uuidandtarget_urlfilter parameters to logs and queue REST endpoints - → Newdate range filtering (
date_from,date_to) to logs and queue list views with a shadcn-style calendar date/time picker - → Newhealth observability metrics: average attempts per event, oldest pending age, queue stuck detection, WP-Cron-only warning
- → New
queue.log_idcolumn linking queue jobs to their log entries - → Updated admin UI: permanently failed badge, attempt timeline, per-row retry button, bulk retry, observability warning banners, new filter inputs
- → Updated footer with a review prompt linking to WordPress.org
v1.0.1 2026-02-18
- → Fixedpreview freezing when mapping fields from objects with numeric string keys (e.g. WooCommerce line_items)
- → Fixedorphaned pending log entries caused by logPending() silently failing — queue jobs now carry mapping metadata and recover a proper log entry if the original ID was lost
- → Enhanced normalizeValue to handle Closure, DateTimeInterface, and Traversable types
- → Removedunnecessary WooCommerce hook patterns from trigger exclusions
- → Improvedlog details display with word break for long trigger names and dates
v1.0.0 2026-02-16
- → Initial release
- → Webhook dispatching from WordPress actions
- → Background processing with retry mechanism
- → Configurable webhook payloads
- → Logging of webhook deliveries
Ready Stop losing webhooks.
Stop losing webhooks.
Start logging them.
$ wp plugin install flowsystems-webhook-actions --activate