Krom Automation is live. Save up to 50% on Krom Automation Pro.

Orders, emails, CRM syncs and alerts, all automated inside WordPress.

Buy Now! →
wprigel logo
  • Home
  • Products
    • krom-automation-icon

      Krom Automation

      Build visual workflows that respond to signups, orders, forms, and posts- automatically. Free plugin, no monthly fees.
    • commandify-logo-pink

      Commandify- Best Command Palette Plugin for WordPress

      Navigate, search, and manage everything on your site with a simple keyboard-first workflow.
    • pollify plugin logo

      Pollify- Ultimate Poll Creator Plugin for WordPress

      Build interactive polls, surveys & voting experiences in WordPress with the best Gutenberg-native poll plugin.
  • Docs
  • Blog
  • Contact Us
  • Login
Pricing
  • How to Post WordPress Posts to Discord Automatically

    You can post WordPress posts to Discord automatically by creating a webhook URL inside Discord, then connecting it to a WordPress automation workflow that fires on the “Post Published” trigger. The whole setup takes under 10 minutes, works on the free tier, and requires no custom code.

    What most tutorials skip is what happens after the happy path: a webhook call that times out, a post that fires to the wrong channel, or a category you never wanted syndicated. This guide covers the full setup and those edge cases, so you have something that actually holds up in production.

    We tested this in our own staging environment using WordPress 6.5 and a live Discord server with three channels. Everything below reflects what we saw on screen.

    What You Need Before You Start

    • A Discord server where you have Manage Webhooks permission on at least one channel.
    • WordPress 6.2 or higher with PHP 7.4 or higher.
    • An automation plugin that supports a Post Published trigger and an HTTP Request action. The free version of Krom Automation covers both out of the box.
    • Five to ten minutes for the initial setup. Conditional logic and multi-channel routing add another five.

    You do not need a Discord bot token for this approach. Webhooks are simpler, require no OAuth flow, and are sufficient for one-way notifications from WordPress to Discord. The bot-token approach adds complexity only when you need two-way interaction, such as reading Discord messages from WordPress, which is a different problem entirely.

    Step 1: Create a Discord Webhook URL

    Open Discord and go to the channel you want to receive WordPress posts. Click the gear icon next to the channel name to open Edit Channel. Navigate to Integrations, then Webhooks, and click New Webhook.

    Give the webhook a name that makes its source obvious, something like “WordPress Blog Posts”. Copy the webhook URL to your clipboard.

    It will look like https://discord.com/api/webhooks/[ID]/[TOKEN]. Store it somewhere safe; you will paste it into WordPress in the next step.

    Discord’s official documentation covers webhook creation in detail. See the Discord webhook reference for the full field reference if you need to customise the payload later.

    Step 2: Install Your Automation Plugin

    In your WordPress admin, go to Plugins > Add New and search for “Krom Automation”. Install and activate it.

    The plugin adds a Krom Automation menu item to your sidebar. No account creation is required and nothing is gated behind a paywall in the free version.

    If you have never built a workflow before, the how Krom Automation works overview explains triggers, actions and the visual canvas in about three minutes of reading. For the installation steps themselves, see how to install Krom Automation on WordPress.

    Step 3: Build the Workflow

    Go to Krom Automation > Workflows > Add New. You will land on a drag-and-drop canvas. The workflow starts with a trigger node and you connect action nodes to it.

    1. Add the trigger: Click the trigger node and select Post Published from the Post category. This fires every time a post transitions to published status, including scheduled posts that go live at their scheduled time.
    2. Add the action: Click the plus icon below the trigger to add an action. Select HTTP Request from the Integration category.
    3. Configure the HTTP Request: Set the method to POST. Paste your Discord webhook URL into the URL field.
    4. Set the Content-Type header: Add a header with the key Content-Type and the value application/json. Discord requires this for webhook payloads.
    5. Write the request body: Paste the JSON below into the body field, using merge tags to inject real post data.

    Here is the payload that produces a clean Discord notification with the post title and a direct link:

    {
      "content": "New post: **{{post_title}}** {{post_url}}"
    }

    Merge tags pull live data from the event that fired the trigger. {{post_title}} resolves to the actual title of the published post and {{post_url}} resolves to its permalink. For the full list of available variables, see the merge tags documentation.

    Save the workflow and toggle it to Active.

    Every other tutorial shows the webhook URL going in. None of them show what the payload looks like when it arrives in Discord, which is the part that determines whether anyone actually reads it.

    Step 4: Test Before You Go Live

    Before you publish a real post, use the built-in workflow simulator to run a dry test with zero side effects. Open the workflow, click Simulate, and choose a recent post as the sample data. The simulator walks through each node and shows you exactly what payload would be sent to Discord, without actually sending it.

    See the testing workflows with the simulator documentation for the full walkthrough. Once the simulation looks right, publish a draft post and watch your Discord channel for the notification. It should arrive within a few seconds on a standard host.

    Conditional Logic: Post Only Specific Categories

    The basic workflow fires for every published post. If you run a site with ten post types or twenty categories, you almost certainly do not want all of them going to Discord. Here is how to add a filter.

    Between the trigger and the HTTP Request action, add a Condition node. Conditions create a Yes path and a No path. Set the condition to check whether the post category equals the category you want to syndicate, for example “News” or “Product Updates”.

    Connect the HTTP Request to the Yes path only. Posts in other categories reach the No path and exit the workflow without sending anything.

    You can stack multiple conditions to route different categories to different Discord channels. Each channel needs its own webhook URL and each path gets its own HTTP Request action with the matching URL. The conditions and branching documentation shows how to build multi-path workflows step by step.

    For the visual canvas itself, the visual workflow builder guide explains how to connect nodes, navigate the canvas, and rearrange your layout as the workflow grows.

    Failure Handling: What Happens When the Webhook Call Fails

    This is the section no other guide covers. Discord webhooks return a non-200 status code for several real-world reasons: the webhook was deleted from the Discord server, the server is temporarily unavailable, or your host’s outbound HTTP is blocked on certain ports. Without failure handling, you lose the notification silently and never know.

    Krom Automation handles this in two ways. First, failed executions are logged in the execution history with a full per-step audit trail, so you can see which workflow step failed and what error code Discord returned. Second, the plugin sends an email notification to the site admin when an execution fails, and retries automatically with configurable backoff.

    Failure scenario What you see What to do
    Discord webhook was deleted HTTP 404 in execution log Generate a new webhook URL in Discord and update the workflow
    Incorrect Content-Type header HTTP 400, Discord returns “Invalid JSON” Confirm the header is set to application/json exactly
    Rate limit hit (Discord allows 30 requests per 60 seconds per webhook) HTTP 429, retry-after header present Add a delay node before the HTTP Request to space out bulk publishes
    Host blocks outbound HTTP on port 443 cURL error or timeout in execution log Contact your host; most managed WordPress hosts allow outbound HTTPS by default
    Malformed merge tag in the payload HTTP 400 or empty field in Discord message Run the simulator first to preview the resolved payload before activating

    The send a webhook when a WordPress post is published post goes deeper on the HTTP Request action and payload structure if you want to build a richer embed rather than a plain text message.

    Silent failures are the worst kind. A workflow that fails 20 percent of the time looks identical to a working one until you check the execution log. That log is the reason execution history matters more than the feature list suggests.

    Richer Discord Embeds vs. Plain Text Messages

    The basic payload sends a plain text line. Discord also supports rich embeds with a title, description, URL, thumbnail image and colour strip. To use an embed, change the payload body to this structure:

    {
      "embeds": [{
        "title": "{{post_title}}",
        "url": "{{post_url}}",
        "description": "{{post_excerpt}}",
        "color": 5814783
      }]
    }

    The color field accepts a decimal integer. The value 5814783 is a mid-blue.

    Convert any hex colour to decimal before inserting it. The {{post_excerpt}} merge tag pulls the post excerpt, which you can set manually in the WordPress post editor or leave blank to let WordPress auto-generate one from the first paragraph.

    Keep the embed description under 200 characters. Discord truncates longer descriptions in the channel preview, which makes the notification harder to read at a glance.

    Webhook-Only vs. Bot Token: Which Should You Use?

    Dimension Webhook approach Bot token approach
    Setup time Under 10 minutes 30 to 60 minutes including Discord Developer Portal registration
    Direction WordPress to Discord only (one-way) Both directions, bot can read and write
    Permissions required Manage Webhooks on one channel Bot must be invited to the server with specific permission scopes
    Rate limit 30 requests per 60 seconds per webhook 50 requests per second globally, per bot
    Maintenance burden Low. Webhook URL is static until deleted. Medium. Bot token must be rotated if compromised.
    Suitable for Publishing notifications, content alerts Interactive commands, two-way sync, moderation bots

    For the use case in this article, publishing a WordPress post to a Discord channel, the webhook approach is correct. It is simpler, requires fewer permissions, and there is no token to manage. The bot token approach is worth the extra complexity only when you need Discord to do something back toward your WordPress site.

    Does This Work for WooCommerce Products?

    Yes. The free version of the plugin includes both an Order Created trigger and an Order Completed trigger. You can notify a Discord channel whenever a WooCommerce order comes in, with the order total and customer name in the payload, using exactly the same HTTP Request action and the same webhook setup described above.

    For product-level events, such as notifying a Discord channel when a product goes back in stock or when a subscription renews, those require Pro triggers. The WooCommerce Subscriptions integration documentation lists the available triggers and what data each one exposes as merge tags.

    If you also send post notifications to Slack, the same workflow pattern applies. The messaging integrations overview covers Discord, Slack, Twilio and Telegram side by side.

    Timing: How Fast Does a Post Appear in Discord?

    On a standard shared host with WP-Cron running normally, the notification reaches Discord within 2 to 5 seconds of publish. The HTTP Request action runs in the background via Action Scheduler, so the publish action itself is not blocked or slowed down.

    On very low-traffic sites where WP-Cron only fires when a visitor loads a page, there can be a delay if no one visits the site for several minutes after publishing. The fix is to disable WP-Cron’s default behaviour and run it as a real server cron job instead.

    The WordPress developer documentation on hooking WP-Cron into the system task scheduler covers this setup. This is worth doing on any site where timing reliability matters.

    Also Worth Knowing About

    Pollify is wpRigel’s poll, survey and quiz plugin for WordPress. It builds natively inside the block editor as real Gutenberg blocks, so there are no shortcodes to paste and no separate interface to configure. It is worth knowing about if you gather community feedback on the same site you are syndicating to Discord.

    Commandify is a command palette for the WordPress admin. Press Cmd or Ctrl plus K to search content, jump to any settings screen, and run admin actions without clicking through menus. It is the only WordPress command palette with real WooCommerce order, product and customer commands built in.

    Frequently Asked Questions

    Is there a free way to auto-post WordPress posts to Discord without a paid plugin?

    Yes. The free version of Krom Automation includes the Post Published trigger and the HTTP Request action, which is everything you need for this setup.

    There is no run cap, no trial period, and nothing behind a paywall in the free version. Download it free from the WordPress.org plugin directory.

    How do I post only specific categories from WordPress to Discord?

    Add a Condition node between the Post Published trigger and the HTTP Request action. Set the condition to check the post category and connect the HTTP Request to the Yes path only. Posts in other categories exit the workflow without triggering the webhook call.

    Why is my WordPress post not showing up in Discord after I publish?

    Check the execution log in Krom Automation first. The most common causes are a deleted or incorrect webhook URL (Discord returns 404), a missing Content-Type header (Discord returns 400), or a WP-Cron delay on low-traffic sites. The execution log shows the exact HTTP status code Discord returned, which narrows the problem immediately.

    Can I send posts to multiple Discord channels?

    Yes. Add separate HTTP Request action nodes for each channel, each with its own webhook URL. Use Condition nodes to route different post categories to different channels, or duplicate the HTTP Request action to send the same post to two channels simultaneously.

    Does this work with scheduled posts or only with immediately published posts?

    Both. The Post Published trigger fires whenever a post transitions to published status, including scheduled posts that go live at their set time. There is no separate trigger needed for scheduled content.

    If you also notify subscribers by email when a post goes live, the email subscribers when a new WordPress post is published post shows how to combine both notifications in a single workflow using parallel action nodes.

    Try Krom Automation free on WordPress.org

    The wpRigel Team

    November 11, 2026
    Krom Automation, User Engagement
  • How to Send a Webhook When a WordPress Post Is Published

    The cleanest way to send a webhook when a post is published in WordPress is to hook into the transition_post_status action and fire an HTTP POST using wp_remote_post(). If you want retry logic, execution logs and a visual editor instead of code, a workflow plugin handles all of that in about five minutes. This tutorial covers both paths, including the failure-handling gap that every other guide skips.

    We tested both approaches on WordPress 6.5 with PHP 8.2. The code path works on any host.

    The plugin path works on shared hosting too, because it queues requests through Action Scheduler rather than firing them synchronously during the publish request. That difference matters more than most tutorials admit.

    Before you choose a path, it helps to understand what can go wrong. When WordPress publishes a post, the browser is waiting. If your webhook fires synchronously during that same request and the receiving endpoint takes three seconds to respond, the editor hangs for three seconds.

    If the endpoint is down, the webhook fails silently with no log and no retry. Neither the code snippets on most blogs nor the basic plugin guides address this, so we will.

    Which Approach Is Right for You?

    SituationBest pathWhy
    One webhook, one destination, no retry neededCode snippetZero plugin overhead, deployed in under 10 minutes
    Multiple webhooks or multiple post typesWorkflow pluginConditional logic without stacking if statements
    Need retry on failure or execution logsWorkflow pluginAutomatic retry with backoff; per-step audit trail
    Sending to Slack, Discord or a CRMWorkflow pluginNative integrations replace hand-rolled JSON formatting
    Shared hosting with no server cronWorkflow pluginAction Scheduler decouples execution from the publish request
    Client site, no code deploymentsWorkflow pluginNon-developers can edit triggers without touching functions.php

    Path 1: The Code Approach

    The correct hook is transition_post_status, not publish_post. The difference is important: publish_post fires on every save to a published post, including updates. transition_post_status lets you check the previous status, so you can fire only on the transition from any status to publish for the first time.

    Add this to your theme’s functions.php or, better, a site-specific plugin so it survives theme changes. The WordPress developer documentation for transition_post_status covers all the parameters.

    add_action( 'transition_post_status', 'my_send_publish_webhook', 10, 3 );
    
    function my_send_publish_webhook( $new_status, $old_status, $post ) {
        // Fire only on the first publish, not on updates
        if ( $new_status !== 'publish' || $old_status === 'publish' ) {
            return;
        }
    
        // Restrict to a specific post type if needed
        if ( $post->post_type !== 'post' ) {
            return;
        }
    
        $payload = wp_json_encode( array(
            'post_id'       => $post->ID,
            'title'         => get_the_title( $post ),
            'url'           => get_permalink( $post ),
            'thumbnail_url' => get_the_post_thumbnail_url( $post, 'full' ),
            'published_at'  => get_the_date( 'c', $post ),
            'categories'    => wp_get_post_categories( $post->ID, array( 'fields' => 'names' ) ),
        ) );
    
        wp_remote_post( 'https://your-endpoint.example.com/hook', array(
            'body'        => $payload,
            'headers'     => array( 'Content-Type' => 'application/json' ),
            'timeout'     => 5,
            'blocking'    => false, // Non-blocking: does not hold up the editor
        ) );
    }

    Setting blocking to false is the most important line in that snippet. With blocking => false, WordPress fires the request and immediately moves on.

    The editor does not hang while waiting for a response. The trade-off is that you get no response body and no way to detect failure at the point of sending.

    Non-blocking solves the latency problem and creates the reliability problem. You cannot have both without a queue.

    Firing Only on First Publish, Not on Every Edit

    The $old_status === 'publish' check is what prevents the webhook from firing again every time the post is edited after it goes live. Without that guard, updating the title six months later fires the webhook again, which breaks most downstream integrations. This is the most common cause of duplicate webhook deliveries, and it is not mentioned in most tutorials.

    Restricting to a Post Type or Category

    To fire only for a specific post type, change $post->post_type !== 'post' to match the post type slug you want, for example !== 'product' or !== 'news'. To fire only for posts in a specific category, add a check after the post type guard:

    $categories = wp_get_post_categories( $post->ID );
    if ( ! in_array( 42, $categories ) ) { // 42 is your category term ID
        return;
    }

    What the Code Path Does Not Give You

    • No retry: if the endpoint returns a 500 or times out, the webhook is lost with no record of the attempt.
    • No logs: you have no way to see which posts triggered the webhook, what was sent, or whether it arrived.
    • No dry-run testing: you must publish a real post to test, which pollutes your site with test content.
    • No visual editing: changing the payload or the endpoint means editing PHP code and redeploying.

    For a single low-stakes webhook to a reliable endpoint, those limitations are acceptable. For anything more critical, the next path is worth the five minutes of setup.

    Path 2: The No-Code Workflow Approach

    Krom Automation is a visual workflow plugin for WordPress. It includes a Post Published trigger and an HTTP Request action in the free version, so this entire workflow costs nothing.

    Execution runs through Action Scheduler, which means the webhook fires after the publish request completes, not during it. That solves the synchronous timing problem without any code.

    Install the free plugin from the WordPress.org plugin directory. If you have not installed it before, the installation guide walks through the first activation steps.

    Step 1: Create a New Workflow

    Go to Krom Automation in your WordPress admin sidebar and click Add New Workflow. You will see a blank canvas with a prompt to add a trigger. Click the trigger node to open the trigger selector panel on the right.

    Step 2: Set the Trigger to Post Published

    In the trigger panel, choose Post from the category list, then select Post Published. You will see configuration options appear below the trigger selector:

    • Post type: choose Post, Page, or any custom post type registered on your site.
    • Category filter: leave blank to fire for all categories, or enter one or more category slugs to restrict.
    • Run once per post: this toggle is on by default and prevents the workflow from firing again if the post is later updated. Leave it on.

    The full list of available triggers and their configuration options is documented in the free triggers reference.

    Step 3: Add an HTTP Request Action

    Click the plus icon below the trigger node to add an action. Choose Integration from the action categories, then select HTTP Request. The action panel opens with these fields:

    • URL: paste your destination endpoint URL here.
    • Method: select POST.
    • Headers: add Content-Type: application/json.
    • Body: paste your JSON payload here, using merge tags for dynamic values.

    Step 4: Build the Payload with Merge Tags

    Merge tags pull live data from the trigger event into any action field. In the body field, build your payload like this:

    {
      "post_id": "{{post.id}}",
      "title": "{{post.title}}",
      "url": "{{post.permalink}}",
      "thumbnail_url": "{{post.thumbnail_url}}",
      "published_at": "{{post.published_date}}",
      "author": "{{post.author_name}}"
    }

    The merge tags documentation lists every available variable for post triggers, including custom field values and taxonomy terms. Click the {} merge tags button in any field to browse available tags without memorising them.

    Step 5: Add Conditional Logic (Optional)

    If you want the webhook to fire only when a post meets additional conditions, such as being in a specific category or having a certain custom field value, click the branching icon on the action node to add a condition. The conditions and branching documentation covers the full logic options. Connect the HTTP Request action to the Yes path and the workflow ends on the No path with no action taken.

    Step 6: Test with the Workflow Simulator

    Before going live, click the Simulate button in the top toolbar. The simulator runs the workflow with real post data and shows you exactly what would have been sent to your endpoint, including the resolved merge tag values, without actually firing the HTTP request. This is covered in the workflow simulator documentation.

    Once the simulated payload looks correct, toggle the workflow to Active and publish a test post. The execution log will show the request status, the response code from your endpoint, and each step’s outcome.

    A webhook that fails silently is worse than no webhook at all. At least when nothing is configured, you know nothing is running.

    What Happens When the Endpoint Is Down

    This is the question every other guide skips. When you fire a webhook synchronously in PHP and the endpoint returns a 503, the request fails and nothing happens.

    You will not know unless you are actively watching server logs. For teams sending post data to a CRM, a Slack channel, or a build pipeline, that silent failure can go unnoticed for days.

    The workflow plugin approach handles this differently. Failed HTTP Request actions are logged in the execution history with the response code and error message.

    Automatic retry kicks in with configurable backoff, so a temporary outage at the endpoint does not lose the event. Email notifications alert you when a workflow fails, and the analytics dashboard shows a failed execution count so trends are visible at a glance.

    If you are using the code path and need similar reliability, you can defer the webhook using wp_schedule_single_event() to push it off the publish request and onto the next WP-Cron pass. The WordPress developer reference for wp_schedule_single_event explains the parameters. This adds async behaviour but still gives you no retry logic or logs without building them yourself.

    Sending to Slack or Discord

    For Slack and Discord, the HTTP Request action works with their incoming webhook URLs. Format the payload to match the channel’s expected structure. Slack expects a JSON body with a text key or a blocks array.

    Discord expects a content key. The messaging integrations documentation shows the exact payload structure for both platforms.

    If you also want to notify email subscribers when a post is published, our guide on emailing subscribers when a new post is published covers that workflow alongside the webhook setup.

    Common Failure Modes and Fixes

    SymptomLikely causeFix
    Webhook fires on every post edit, not just first publishUsing publish_post hook without status guardSwitch to transition_post_status and check $old_status !== 'publish'
    Webhook fires twice for the same postTwo hooks registered, or autosave triggering the actionAdd a transient lock: set a transient keyed to post ID, skip if it exists
    Editor hangs after clicking PublishSynchronous wp_remote_post() with slow endpointSet blocking => false or switch to queued execution via plugin
    Webhook body arrives empty at destinationContent-Type header missing, endpoint expects form dataAdd Content-Type: application/json header; confirm endpoint accepts JSON
    Webhook never fires on a staging siteWP-Cron disabled or Action Scheduler not runningConfirm DISABLE_WP_CRON is not set to true in wp-config.php
    Thumbnail URL returns false in payloadPost has no featured image setUse a fallback: get_the_post_thumbnail_url( $post, 'full' ) ?: ''

    What Gets Sent: A Reference Payload

    This is the payload structure we use in production for a standard blog post notification. It covers the fields most downstream services actually need.

    {
      "post_id": 1842,
      "title": "How to Configure Redis on WordPress",
      "url": "https://example.com/configure-redis-wordpress/",
      "thumbnail_url": "https://example.com/wp-content/uploads/redis-cover.jpg",
      "excerpt": "A short plain-text excerpt from the post.",
      "author_name": "Sakil",
      "published_at": "2026-04-14T09:00:00+00:00",
      "categories": ["Performance", "Hosting"],
      "tags": ["redis", "caching", "server"]
    }

    Custom fields can be added to this payload using the get_post_meta() function in code, or via post meta merge tags in the workflow builder. If your destination service requires HMAC signature verification for security, that is a Pro feature covered in the incoming webhook receiver documentation.

    Most webhook tutorials give you a snippet that works in development and fails quietly in production. The gap is always retry logic and observability, not the initial send.

    Also Worth Knowing About

    Pollify is wpRigel’s poll, survey and quiz plugin for WordPress. It builds polls as native Gutenberg blocks, so there are no shortcodes to paste and no separate admin interface to learn. If you are publishing content and want to gather reader feedback inline, it fits into the same post-publish workflow.

    Commandify is a command palette for the WordPress admin. Press Cmd or Ctrl plus K to jump anywhere in the dashboard, search posts, users and products, and run admin actions without navigating menus. It is the only WordPress command palette with real WooCommerce order, product and customer commands built in.

    Next Steps

    If you are starting with the code path, copy the snippet above, replace the endpoint URL, and publish a test post on a staging site first. If you need retry logic, failure notifications or the ability to test without publishing real content, the free plugin is the faster path and costs nothing to try. The step-by-step workflow builder guide covers the full setup from first trigger to active workflow in one place.

    Try Krom Automation free on WordPress.org

    Frequently Asked Questions

    Why is my WordPress publish webhook firing multiple times for the same post?

    The most common cause is using the publish_post hook without checking whether the post was already published. Every time the post is updated after going live, that hook fires again.

    Switch to transition_post_status and add an $old_status === 'publish' guard to skip anything that was already in the published state. A second cause is autosave or revision saves triggering the same action, which a transient lock keyed to the post ID will prevent.

    How do I send a webhook only for specific post types or categories?

    In the code path, add a $post->post_type check inside the callback and return early if the type does not match. For category filtering, use wp_get_post_categories() and check whether the returned term IDs include your target. In the workflow builder, the Post Published trigger has a post type selector and a category filter field built into the trigger configuration panel, so no code is needed.

    What happens to the webhook if the receiving endpoint is down?

    With a plain PHP snippet and blocking => false, the request is sent and forgotten. If the endpoint returns an error or is unreachable, the event is lost with no log.

    With a queued workflow plugin, the failed attempt is logged with the response code, automatic retry runs with backoff, and an email notification is sent after a configurable number of failures. For any integration where losing the event matters, the queued approach is the correct one.

    How do I add the post thumbnail URL and custom fields to the webhook payload?

    In the code path, use get_the_post_thumbnail_url( $post, 'full' ) for the thumbnail and get_post_meta( $post->ID, 'your_field_key', true ) for custom fields, then include both in the array passed to wp_json_encode(). In the workflow builder, thumbnail URL and post meta values are available as merge tags. Click the {} merge tags button in the HTTP Request body field to browse all available variables for the Post Published trigger.

    Can I test a WordPress publish webhook without publishing a real post?

    With the code path, no. You must publish a real post or temporarily hook into a different action for testing.

    With the workflow plugin, the built-in simulator runs the full workflow against real post data and shows the resolved payload and simulated action output without firing the HTTP request or touching any external service. This means you can verify the payload structure before the workflow goes active.

    The wpRigel Team

    November 9, 2026
    Krom Automation
  • How to Email Subscribers When a New WordPress Post Is Published

    You can automatically email subscribers when a new WordPress post publishes by using a workflow automation plugin to connect the Post Published trigger to a Send Email action. The whole setup takes under 15 minutes and requires no code. The harder problem, which almost no tutorial covers, is making sure those notification emails actually reach the inbox instead of the spam folder.

    This tutorial walks through the complete setup: collecting subscribers, building the notification workflow, customising the email, and verifying deliverability. We tested this on a self-hosted WordPress 6.5 site running PHP 8.2. The steps below reflect exactly what you will see on screen.

    Before diving into the steps, one orientation note. This tutorial focuses on self-hosted WordPress.org sites.

    WordPress.com has a built-in follower notification system under Settings Discussion that works without any plugin. If you are on WordPress.com, that is the place to start, as documented in the WordPress.org documentation.

    What You Need Before Starting

    • A self-hosted WordPress site running WordPress 6.2 or higher and PHP 7.4 or higher.
    • A way to collect subscriber emails. A contact form, a subscription block, or a user registration flow all work. The workflow listens for whichever event you choose.
    • An SMTP plugin or transactional email service. WordPress’s native wp_mail function uses PHP mail, which most hosts do not authenticate properly. Without SMTP, your notification emails will land in spam at a rate that makes the whole feature pointless. More on this in the deliverability section below.
    • Krom Automation installed and active. The free version on the WordPress.org plugin directory includes the Post Published trigger and Send Email action you need for this exact workflow.

    If you have not installed the plugin yet, follow the installation guide first. It takes about two minutes.

    Step 1: Decide How You Are Collecting Subscribers

    Your notification workflow needs a list of people to email. How that list is built determines which approach works best for you.

    The three most common patterns on WordPress are:

    • Registered WordPress users. Anyone who has created an account on your site. The Send Email action can target all users or a specific role. No separate list management needed.
    • Form submissions stored as user meta or in a custom table. A subscriber enters their email via a form, and your workflow stores that email somewhere queryable. This is the most flexible pattern but requires a bit more setup.
    • An email marketing platform list. Subscribers sign up via Mailchimp, MailerLite, ConvertKit or similar. Your post notification goes out through that platform, not through WordPress directly. This is the most deliverability-safe option because those platforms handle authentication on your behalf.

    For this tutorial we focus on the native WordPress approach: emailing registered users when a post publishes. If you want to sync subscribers to an external list first, the Mailchimp integration documentation and the MailerLite integration documentation cover that path in detail.

    Step 2: Build the Post Notification Workflow

    Go to WordPress Admin Krom Automation Workflows and click New Workflow. You will land on the visual canvas. The canvas uses a drag-and-drop interface where every workflow starts with a trigger node on the left and connects to action nodes on the right.

    2a. Set the Trigger

    Click the trigger node and choose Post Published from the trigger list. You will see a configuration panel slide in on the right side of the screen. Set the following:

    • Post Type: Post (or whichever post type you publish to).
    • Category filter: Leave blank to fire on every new post, or select one or more categories if you only want to notify subscribers about specific topics. A site publishing in five categories but only wanting to alert subscribers about one of them should set this filter here rather than adding conditional logic later.
    • Status transition: The trigger fires when post status changes to “publish”. This means scheduled posts that go live automatically will also trigger the workflow, which is usually what you want.

    For a full reference of what this trigger passes downstream, including all available merge tags, see the free triggers reference.

    2b. Add the Send Email Action

    Click the plus icon after the trigger node and add a Send Email action. The configuration panel shows four fields:

    • To: Enter the email addresses of your subscribers, or use a merge tag that resolves to a list. For registered users with the Subscriber role, you can build a simple query. For small lists under 500 addresses, entering a distribution list address here is the most practical approach.
    • Subject: Use merge tags to make it dynamic. A subject like New post: {{post_title}} takes two seconds to write and performs meaningfully better than a generic “New post from our blog”.
    • Body: Write the email body here. Include {{post_title}}, {{post_excerpt}} and {{post_url}} at minimum. These pull the live post data at the moment the workflow executes.
    • From name and From email: Set these explicitly. Leaving them as WordPress defaults means the email comes from “WordPress” at your domain, which looks unprofessional and hurts open rates.

    Merge tags are covered in full in the merge tags documentation. Every post field you can imagine is available: title, excerpt, URL, featured image URL, author name, publish date and more.

    A subject line with the actual post title gets clicked. A subject line that says “New post from our blog” gets ignored. The merge tag takes two seconds to add.

    2c. Configure Run Once Per Post

    Open the workflow settings panel and enable Run Once Per Entity. This prevents the workflow from firing multiple times if a post is accidentally saved to draft and re-published.

    Without this setting, a post updated from draft to publish twice sends two notification emails to every subscriber. Enable it on every notification workflow.

    For a complete walkthrough of workflow settings including pausing, notes and import/export, see the workflow settings documentation.

    2d. Test Before Activating

    Use the built-in Workflow Simulator before switching the workflow live. The simulator runs the workflow in dry-run mode: it processes the trigger, evaluates conditions and steps through every action, but sends no actual emails and makes no database changes. You will see exactly what the email would contain, including which merge tags resolved and which did not.

    The simulator documentation shows you how to supply a test post ID so the dry run uses real data. Once every field looks correct, activate the workflow using the toggle at the top of the canvas.

    Step 3: Fix Deliverability (The Step Everyone Skips)

    This is the section that determines whether any of the above actually works. We have seen sites with a perfectly configured notification workflow where subscribers reported never receiving emails. Every single time, the root cause was deliverability, not the workflow itself.

    WordPress sends email via PHP’s mail() function by default. Most shared hosts do not configure DKIM or SPF records for mail sent this way, which means receiving mail servers treat it as suspicious. Gmail, Outlook and Apple Mail all apply aggressive spam filtering to unauthenticated email from web servers.

    The Deliverability Checklist

    Work through these in order. Skipping ahead to item 3 without completing item 1 wastes time, because unauthenticated mail gets filtered regardless of content quality.

    1. Add SPF and DKIM records to your domain’s DNS. SPF tells receiving servers which IP addresses are allowed to send email for your domain. DKIM adds a cryptographic signature to each email that proves it was not tampered with in transit. Both records live in your domain’s DNS panel. Your hosting provider or email provider should document exactly what values to add. Without these two records, skip the rest of this list and fix this first.
    2. Install an SMTP plugin and connect a transactional email service. Services like Amazon SES, Postmark, Mailgun or SendGrid handle authentication correctly and maintain sending reputation over time. Free tiers on most of these services cover thousands of emails per month, which is enough for most WordPress blogs. The SMTP plugin (WP Mail SMTP is widely used, as is FluentSMTP) replaces the PHP mail function with an authenticated API call to your chosen service.
    3. Set a consistent From address that matches your domain. Sending from a Gmail or Yahoo address while your site lives at yourdomain.com is an instant spam signal. The From email in your workflow’s Send Email action must use your own domain.
    4. Add a plain-text version of the email. HTML-only emails score worse on spam filters. Most SMTP plugins handle this automatically if you configure them to, but verify it in your email testing tool.
    5. Test deliverability before your first real send. Mail-tester.com gives your email a deliverability score out of 10 and shows exactly which checks passed or failed. Run a test email through it before activating your workflow. Aim for 9 or above. A score below 7 means subscribers on Gmail will likely never see your notifications.

    The WordPress documentation on plugin basics does not cover email deliverability because it is an infrastructure concern, not a WordPress concern. That is precisely why every plugin tutorial skips it and why subscribers end up not receiving emails.

    A perfectly configured workflow sending to spam is indistinguishable from a broken workflow. Fix authentication before you blame the plugin.

    Step 4: Handle Category-Specific Notifications

    Some sites publish across multiple topics and want to let subscribers opt in to specific categories. A reader interested in tutorials should not receive every product announcement. This is a filtering problem, and there are two ways to solve it.

    Option A: Separate workflows per category. Build one workflow for each category with the category filter set on the Post Published trigger. This is the simplest approach and requires no conditional logic. The downside is that managing 8 categories means 8 workflows to maintain.

    Option B: One workflow with conditional branching. Use a single Post Published trigger and add Yes/No branches based on the post’s category. Each branch routes to a Send Email action targeting the appropriate subscriber segment.

    This is cleaner at scale but requires understanding how conditions work. The conditions and branching documentation walks through the exact logic.

    Either option works. Choose Option A if you have fewer than 5 categories and a small team. Choose Option B if you are building this for a large publication where workflow sprawl becomes a maintenance burden.

    Step 5: Add a Delay for Scheduled Posts

    If you schedule posts to go live at a specific time, consider adding a short delay between the Post Published trigger and the Send Email action. A 5-minute delay gives you a window to catch a typo or pull the post back before every subscriber has already received the notification.

    Add a Delay node between the trigger and the action on the canvas. Set it to 5 minutes.

    If you need to cancel the send, deactivate the workflow before the delay expires. The delays and scheduling documentation covers how queued actions behave when a workflow is paused mid-execution.

    What to Do When Subscribers Do Not Receive the Email

    If the workflow ran but subscribers report not receiving anything, work through this in order:

    • Check the execution log first. Go to Krom Automation Logs and find the execution for the post in question. The log shows every step with a pass or fail status. If the Send Email step shows a failure, the error message will identify whether the problem is authentication, a bad recipient address, or a timeout from your SMTP provider.
    • Check the spam folder. Ask a subscriber to check spam before assuming the email was never sent. If it is landing in spam, the problem is deliverability (see Step 3), not the workflow.
    • Verify the From address. An unrecognised From address is the fastest route to spam. Check that the From email in your workflow matches the domain you authenticated in DNS.
    • Check WP-Cron. Krom Automation runs actions via Action Scheduler, which depends on WP-Cron. On very low traffic sites, WP-Cron can fire late if no page loads occur during the scheduled window. Configure a real server cron job to call wp-cron.php on a fixed schedule (every minute is standard). Your host’s control panel or a system cron entry handles this. The WordPress Cron documentation explains the difference between WP-Cron and system cron.
    • Check the Run Once setting. If the workflow is set to Run Once Per Entity and the post was previously published (even briefly), the workflow will not fire again. This protects against duplicates but can confuse troubleshooting. The execution log will show a “skipped” entry with the reason.

    Connecting to an External Email List

    The native Send Email action works well for smaller lists and internal notifications. For lists above roughly 2,000 subscribers, or for sites that want subscriber management features like unsubscribe handling, bounce processing and open rate tracking, connecting to an email marketing platform is the right choice.

    The workflow structure changes slightly. Instead of a Send Email action, you trigger a campaign in your external platform by adding or tagging a contact when a post publishes. The platform then handles delivery to your full list using its own authenticated infrastructure.

    Documentation for the platforms we support:

    • Mailchimp integration: subscribe, tag, and sync WordPress users automatically.
    • ConvertKit integration: subscribers, tags, sequences, and forms.
    • MailerLite integration: subscribe, unsubscribe, and manage groups.
    • FluentCRM integration: contacts, tags, and lists for teams running CRM inside WordPress.

    These integrations are Pro features. The free plugin handles Send Email natively with no external platform required.

    Past 2,000 subscribers, managing bounces and unsubscribes inside WordPress becomes a part-time job. An external platform earns its cost at that point.

    What This Workflow Looks Like in Practice

    Here is the complete workflow structure for a site that publishes tutorials and wants to email all registered subscribers within 5 minutes of each new post going live:

    Node Type Configuration Why it matters
    1 Trigger: Post Published Post type: Post, Category: Tutorials Fires only when a tutorial publishes, not every post type
    2 Delay 5 minutes Gives a window to cancel if the wrong post goes live
    3 Action: Send Email To: subscriber list, Subject: New tutorial: {{post_title}} Dynamic subject increases open rate versus generic subject

    Should You Build This Yourself or Use a Dedicated Newsletter Plugin?

    This is the honest trade-off table most tutorials do not include. The right answer depends on your list size and what you value.

    Factor Workflow automation approach Dedicated newsletter plugin
    Setup time Under 15 minutes for a simple notification 30 to 60 minutes including list import and template setup
    Subscriber management Manual or via user roles, no built-in unsubscribe UI Built-in subscribe/unsubscribe, list segmentation, GDPR tools
    Bounce and complaint handling Depends on your SMTP provider’s dashboard Automatic bounce and complaint processing
    Open and click tracking Not included in the native Send Email action Included in most newsletter plugins
    Best for list size Under 500 subscribers or internal team notifications 500 or more, or any list with public signup
    Works alongside other automations Yes, the same workflow engine handles all site events Depends on the plugin’s integration capabilities

    For sites where the goal is a simple “subscribers get an email when a post goes live” and the list is small, the automation approach is faster and adds no extra plugin to maintain. For sites building a real newsletter operation with segmentation and analytics, a dedicated newsletter plugin or external platform is the more sustainable choice, and the automation layer connects the two.

    Other Tools Worth Knowing About

    Pollify is wpRigel’s poll, survey and quiz plugin. It is built as native Gutenberg blocks, which means creating a poll inside a post works exactly like adding a paragraph.

    No shortcodes to paste, no separate interface to configure. If you are sending post notifications to subscribers, embedding a quick poll in those posts is a natural way to drive engagement back to the site.

    Commandify is a command palette for the WordPress admin. Press Cmd or Ctrl plus K and you can jump to any screen, search any content, or run admin actions without navigating menus.

    It is the only WordPress command palette with real WooCommerce order, product and customer commands built in. For teams managing a lot of content, it cuts the time spent clicking around the backend considerably.

    Next Steps

    The workflow itself is straightforward. The two things that determine whether it actually works are deliverability configuration (Step 3 above) and choosing the right approach for your list size (the trade-off table above). If you are starting fresh, complete the DNS authentication steps before activating the workflow.

    If you are troubleshooting an existing setup, start with the execution log in Krom Automation and check mail-tester.com before changing anything else. For a broader look at what automation can handle on a WordPress site, the overview of how Krom Automation works is a useful next read.

    Try Krom Automation free on WordPress.org

    Frequently Asked Questions

    Why are my subscriber notification emails going to spam?

    The most common cause is unauthenticated email. WordPress sends via PHP mail by default, which most hosts do not sign with DKIM or list in an SPF record.

    Install an SMTP plugin, connect a transactional email service, and verify your DNS records. Test your setup at mail-tester.com before activating the workflow.

    Can I send post notifications to registered WordPress users instead of an external list?

    Yes. The Send Email action lets you specify recipient addresses directly, including addresses you retrieve from registered users.

    For small sites where all subscribers have WordPress accounts, this is the simplest approach. For public subscriber lists, you need a form-based signup flow and a way to store those email addresses.

    How do I filter notifications so subscribers only get emails for specific categories?

    Set the Category filter on the Post Published trigger. The trigger only fires when a post in the selected category publishes.

    For multiple subscriber segments with different category preferences, either build separate workflows per category or use conditional branching inside a single workflow. The conditions and branching documentation covers the branching approach.

    Will the workflow fire if I schedule a post to publish automatically at a future time?

    Yes. The Post Published trigger fires whenever a post’s status transitions to “publish”, whether that happens immediately or via a scheduled publish. If you add a 5-minute delay node after the trigger, you have a short window to cancel the email send by deactivating the workflow before the delay expires.

    Does this work for custom post types, not just standard posts?

    Yes. When configuring the Post Published trigger, the Post Type field includes all public post types registered on your site. Select the custom post type you want to monitor and the trigger behaves identically to a standard post trigger.

    The wpRigel Team

    November 6, 2026
    Krom Automation, Marketing
  • How to Send a Coupon After a Customer’s First WooCommerce Order

    WooCommerce has no native trigger for a customer’s first order, so you need a workflow plugin to detect it and send the coupon automatically. The setup takes under 15 minutes and works without writing any code.

    This tutorial covers the complete workflow: detecting whether an order is genuinely a first purchase, generating a coupon, sending it by email, and preventing it from being shared or used by someone else. We also cover a lightweight developer hook at the end for shops that want zero extra plugins.

    Before we get into the steps, two decisions shape everything else: when to send (immediately or delayed) and unique versus generic codes. A generic code like WELCOME10 is easy to share and leaks across forums within days. A unique, single-use code tied to the customer’s email is worth the extra setup time.

    Does WooCommerce Handle This Natively?

    No. The WooCommerce core documentation covers coupons and email templates, but there is no built-in condition for “this customer has zero previous orders.” Every approach requires either a plugin or custom code.

    The core “Order Completed” email does let you attach a static coupon code as text, but it fires on every order, not just the first. That means a customer on their tenth purchase would still receive a first-order coupon if you configure it that way.

    A generic coupon code shared in a Facebook group costs you full margin on every order it touches. A unique single-use code costs you margin once, on the customer it was meant for.

    What You Need Before You Start

    • WooCommerce installed and running with at least one completed order to test against
    • A workflow plugin that supports a first-order condition (covered below)
    • A coupon action that can create a unique code per customer, not just insert a static string
    • An email action that can embed that generated coupon code into the message body using merge tags
    • A test customer account with zero previous orders, so you can verify the condition fires correctly

    The WooCommerce coupon documentation explains usage restrictions you can set at the coupon level, including email restriction. We will use that in Step 4.

    Step-by-Step: Build the Workflow

    Step 1. Install and activate the plugin

    Install Krom Automation from the WordPress.org plugin directory through Plugins Add New. Activate it.

    You will see a new Krom Automation menu item in your WordPress admin. No licence key is needed for the free version.

    Once active, go to Krom Automation Workflows and click New Workflow. You will land on the visual canvas. If this is your first workflow, the step-by-step workflow guide in the documentation covers canvas navigation in detail.

    Step 2. Set the trigger to Order Completed

    Click the trigger node on the canvas and choose Order Completed from the WooCommerce section. This fires every time an order moves to the Completed status, which is what you want as the entry point. You can see a full list of available triggers in the free triggers reference.

    At this stage the workflow fires on every completed order. The next step narrows it to first-time customers only.

    Step 3. Add a condition to check order count

    Add a Condition node after the trigger. Set it to check whether the customer’s total order count equals 1.

    The Yes path continues to the coupon creation. The No path does nothing (leave it empty or connect it to a Stop node).

    This is the critical gate. Without it, every customer who completes any order receives the coupon. The conditions and branching documentation shows the exact fields and operators available for this check.

    One important note: “Order Completed” fires after payment, not at checkout submission. That means the order count at the moment the trigger fires will already include the current order. So “equals 1” correctly identifies a customer whose very first order just completed.

    Step 4. Create the coupon

    On the Yes path, add a Create Coupon action. Configure it as follows:

    • Discount type: Percentage or fixed, your choice. We use 15% as a worked example.
    • Coupon code: Use a merge tag to generate a unique code per customer, for example WELCOME-{{order.id}} or a random string pattern. The merge tags documentation lists every available variable.
    • Usage limit: Set to 1. This ensures the code can only be redeemed once, by anyone.
    • Allowed emails: Add {{customer.email}} as a merge tag. WooCommerce will reject the coupon if the email at checkout does not match, which prevents sharing.
    • Expiry date: Set to 30 days from now. A deadline increases redemption rates. Without one, customers save the code and forget it.
    • Minimum spend: Optional. Setting a floor (say $30) protects margin on small repeat orders.

    Step 5. Add a delay (optional but recommended)

    Send the coupon immediately and it arrives inside the order confirmation email window, where it competes for attention. A delay of 2 to 3 days lets the product arrive first, so the coupon lands when the customer is thinking about their next purchase rather than waiting for the current one.

    Add a Delay node between the Create Coupon action and the Send Email action. Set it to 2 days. The delays and scheduling documentation covers all available units including hours, days and weeks.

    Step 6. Send the email

    Add a Send Email action. Use merge tags to personalise the subject and body:

    • To: {{customer.email}}
    • Subject: Your exclusive discount, {{customer.first_name}}
    • Body: Write a short message and embed {{coupon.code}} to display the unique code the previous action generated

    Keep the email to three short paragraphs. State the discount amount, the expiry date, and the minimum spend if you set one. Ambiguity here costs you redemptions.

    Step 7. Test before activating

    Use the workflow simulator to run a dry test with no side effects before you go live. The simulator documentation explains how to pass in a sample order and inspect what each node would do. Check that the condition resolves to Yes for a customer with one order and No for a customer with two or more.

    When the test passes, enable the workflow and place a real test order using a fresh customer account. Confirm the coupon appears in WooCommerce Coupons with the correct email restriction, and that the email arrives on schedule.

    Running the simulator before activating takes two minutes. Discovering the condition was inverted after 400 real orders have fired takes considerably longer to unpick.

    What the Condition Check Actually Prevents

    The order-count condition does one thing that email restriction alone does not: it stops the workflow from firing at all for repeat customers. Email restriction at the coupon level stops redemption, but the email still sends, which looks like a mistake to the customer. Catching it in the workflow condition means no email, no coupon, no confusion.

    Three scenarios worth testing explicitly:

    • Guest checkout, then account creation: The order count is attached to the email address. If the customer checks out as a guest and then creates an account with the same email, WooCommerce links the history. The condition will count the guest order.
    • Refunded first order: A refund does not remove the order from the count. If this matters for your store, add a second condition checking order status is not Refunded.
    • Multiple orders on the same day: On very high-volume flash sales, two orders can complete within seconds. The run-once-per-entity setting prevents the workflow from firing twice for the same customer. Enable it in workflow settings.

    Timing: When Should the Coupon Email Arrive?

    Send timingBest forRisk
    Immediately after orderDigital products, instant deliveryLost in the confirmation email batch
    2 to 3 days after orderPhysical goods with standard shippingRequires a delay node and reliable WP-Cron
    After order status changes to DeliveredShops using shipping tracking pluginsRequires a Pro trigger tied to status change

    The 2 to 3 day delay is the most common setup we see for physical goods. The customer has the product in hand, the purchase satisfaction is fresh, and the coupon arrives before competing stores have a chance to retarget them. For digital products, immediate delivery makes more sense because there is no shipping window to work with.

    One caveat on delays: delays run through WordPress Cron. On low-traffic sites that go hours between visits, WP-Cron fires late.

    If your store gets fewer than a few hundred visits a day, configure a real server cron job to call wp-cron.php on a schedule. The WordPress developer documentation on WP-Cron covers this setup.

    Cost Comparison: Which Approach Fits Your Setup

    ApproachUpfront costYear 1 costUnique codesVisual builder
    Krom Automation free$0$0Yes, via merge tagsYes
    Krom Automation Pro (1 site)$69/year$69YesYes, with email builder
    AutomateWooIncluded with WooCommerce paid plansVaries by planYesNo, list-based rules
    Custom code (developer)Developer time (est. 1 to 3 hours)Maintenance burdenRequires extra codeNo

    The free tier covers everything in this tutorial. Pro adds the visual email builder for designing the coupon email without touching HTML, plus a Schedule trigger and an incoming webhook receiver if you want to extend the workflow further.

    The Developer Shortcut: No Plugin Required

    If you manage your own site and want zero additional plugins, this hook handles the detection. Add it to your theme’s functions.php or a site-specific plugin:

    add_action( 'woocommerce_order_status_completed', function( $order_id ) {
        $order    = wc_get_order( $order_id );
        $customer = new WC_Customer( $order->get_customer_id() );
    
        if ( $customer->get_order_count() !== 1 ) {
            return;
        }
    
        // Create coupon
        $coupon_code = 'WELCOME-' . strtoupper( wp_generate_password( 8, false ) );
        $coupon      = new WC_Coupon();
        $coupon->set_code( $coupon_code );
        $coupon->set_discount_type( 'percent' );
        $coupon->set_amount( 15 );
        $coupon->set_usage_limit( 1 );
        $coupon->set_email_restrictions( [ $order->get_billing_email() ] );
        $coupon->set_date_expires( strtotime( '+30 days' ) );
        $coupon->save();
    
        // Send email
        WC()->mailer()->emails['WC_Email_Customer_Processing_Order']
            ->trigger( $order_id ); // Replace with a custom email class for production
    } );

    This is a starting point, not production-ready code. The email line needs replacing with a custom WC_Email class that includes the coupon code in the body.

    If that scope is comfortable for your team, this route avoids a plugin entirely. If it is not, the visual workflow approach is faster and easier to maintain.

    What None of the Tutorials Tell You

    Most guides stop at “configure the plugin and send the email.” Three things that actually affect whether the coupon converts into a second purchase:

    • Subject line specificity wins. “Here’s your discount” gets ignored. “Your 15% off expires in 30 days, [Name]” tells the customer exactly what they have and when it expires. That specificity drives opens.
    • The minimum spend floor matters more than the discount percentage. A 10% coupon with a $50 minimum on a store whose average order value is $45 will almost never redeem. The floor needs to sit below the average order value or you are optimising for a transaction that rarely happens.
    • Coupon visibility on the thank-you page doubles as a channel. Email is not the only delivery point. Adding the coupon code to the WooCommerce thank-you page via a custom hook means customers see it immediately, before email even arrives. The delay approach and the thank-you page approach are not mutually exclusive.

    The minimum spend floor is the detail most store owners skip. Set it above your average order value and the coupon looks generous but almost never redeems.

    Other Tools Worth Knowing About

    If you are running a WooCommerce store alongside other automation needs, two other wpRigel tools are worth a look. Commandify is a command palette for the WordPress admin.

    Press Cmd or Ctrl plus K to search orders, customers and products without clicking through menus. It is the only command palette with real WooCommerce order and customer management built in, which makes post-purchase admin significantly faster.

    Pollify builds polls, surveys and quizzes as native Gutenberg blocks. If you want to collect feedback from customers after their first purchase, a post-order survey embedded on the thank-you page or in the follow-up email is a natural companion to the coupon workflow.

    If your store runs WooCommerce Subscriptions alongside standard orders, the WooCommerce Subscriptions integration documentation shows how subscription-specific triggers work alongside the standard Order Completed trigger covered here.

    Frequently Asked Questions

    Does the Order Completed trigger fire for guest checkouts?

    Yes. The trigger fires regardless of whether the customer has an account. The order count check uses the billing email to look up history, so guest orders are included in the count as long as the same email address was used.

    How do I make sure the coupon can only be used by the original customer?

    Set the Allowed Emails field in the Create Coupon action to the customer’s email address using the {{customer.email}} merge tag. WooCommerce will block any checkout that uses a different email address. Combined with a usage limit of 1, the code is effectively single-use and non-transferable.

    What happens if the customer’s first order gets refunded?

    The order remains in the count even after a refund, so the workflow fires as expected. If you want to withhold the coupon for refunded first orders, add a second condition checking that the order status is not Refunded before the Create Coupon action runs.

    Can I send the coupon on the thank-you page instead of by email?

    The workflow approach described here sends by email. Displaying the coupon on the thank-you page requires a custom hook using woocommerce_thankyou or a page builder that supports order data. You can run both in parallel: create the coupon in the workflow, display it immediately on the thank-you page via a hook, and then send the email reminder 2 days later.

    Will this work if I use a custom order status instead of Completed?

    The Order Completed trigger fires specifically on the WooCommerce “Completed” status. If your store uses a custom status as the final step, use the Post Status Changed trigger instead and filter to your custom status. The order count condition logic stays the same.

    Next Steps

    The workflow in this tutorial takes under 15 minutes to build, but the decisions around discount amount, timing and minimum spend have a bigger effect on your second-purchase rate than the technical setup does. Start with a 15% discount, a 30-day expiry and a minimum spend set $5 below your average order value.

    Run it for 60 days, check how many coupons were created versus redeemed in the execution logs, and adjust from there. For more automation ideas once this workflow is live, the article on changing a user role after a WooCommerce purchase shows how to combine the same trigger with a different action to unlock member pricing automatically.

    Try Krom Automation free on WordPress.org

    The wpRigel Team

    November 4, 2026
    Krom Automation, WooCommerce
  • How to Change a User Role After a WooCommerce Purchase

    You can change a WordPress user role automatically when a WooCommerce order reaches “Completed” status, either with a visual workflow builder that takes about five minutes to configure, or with a code snippet targeting the woocommerce_order_status_completed hook. Neither approach requires a dedicated membership plugin.

    This tutorial covers the full picture: assigning a role tied to a specific product, handling guest purchasers who have no WordPress account yet, and revoking a role when an order is refunded or cancelled. Those last two scenarios are the ones most guides skip, and they are where broken setups cause the most support tickets.

    Work through the options in the order they appear here. The no-code path takes less time and gives you execution logs from day one. The code path gives you full control with zero additional plugins, but requires a place to store snippets safely.

    What You Are Actually Trying to Solve

    The motivating use case is almost always one of these three things:

    • Membership access: a customer buys a “Premium Member” product and should move from the default customer role to a custom premium_member role that unlocks restricted content.
    • VIP tier: a customer spends over a threshold (say $200 in a single order) and earns a vip role that unlocks a wholesale price list.
    • Course or community access: a customer buys a course bundle and should be elevated to a role that a LearnDash group or BuddyBoss community recognises as enrolled.

    All three follow the same logic: an order event fires, you check a condition, and you call WordPress’s wp_update_user() or WP_User::set_role() with a new role slug. The difference is which condition you check and what happens when the purchase is reversed.

    A role change with no revocation path is a promise you will eventually break. Build the cancellation branch at the same time you build the assignment branch.

    Option A: No-Code Workflow (Recommended Starting Point)

    Krom Automation’s free tier includes both the Order Completed trigger and the Change User Role action, along with conditional branching to filter by product ID. Installation takes under two minutes from the WordPress.org plugin directory. If you want to understand how the builder works before you start, the triggers, actions, and workflows overview explains the mental model clearly.

    Step 1: Install and Open the Workflow Builder

    Go to Plugins Add New, search for “Krom Automation”, install and activate. A new Krom Automation menu appears in your sidebar.

    Click it, then click New Workflow. You will land on a drag-and-drop canvas with an empty start node.

    Step 2: Set the Trigger to “Order Completed”

    Click the start node and choose WooCommerce Order Completed from the trigger panel on the right. This fires once per order, after WooCommerce moves the order status to completed.

    It does not fire for processing or pending, which matters if your product is digital and auto-completes immediately. Refer to the free triggers reference for the exact data fields each trigger exposes.

    Step 3: Add a Condition to Filter by Product

    Click the + button below the trigger node and add a Condition block. Set it to check whether Order Line Items Product ID contains your target product’s ID. The canvas splits into a Yes path and a No path.

    Everything on the Yes path runs only for orders that contain that product. The conditions and branching documentation shows every available operator, including “contains any of” for matching multiple product IDs at once.

    Step 4: Add the “Change User Role” Action

    On the Yes path, add an action node. Choose User Change User Role. Set the User field to the merge tag {{order.customer_id}} and the New Role field to your target role slug, for example premium_member.

    Save. The merge tags documentation lists every dynamic variable available from the Order Completed trigger.

    Step 5: Test Before Going Live

    Click the Simulate button in the top toolbar. The simulator runs the workflow with a real order ID you supply, shows you what each step would do, and exits without writing any changes to the database.

    This dry-run capability catches configuration mistakes before they touch live user data. The workflow simulator documentation explains how to supply test data for each trigger type.

    Once the simulation shows the correct role slug in the action output, toggle the workflow to Active and place a test order. Check the execution log under Krom Automation Logs to confirm the action ran and the user record updated.

    Option B: Code Snippet

    If you prefer not to add a plugin, the following snippet handles the same assignment. Add it to a site-specific plugin or use a snippet manager like WPCode. Never paste custom PHP into functions.php on a theme you did not build, because a theme update will erase it.

    add_action( 'woocommerce_order_status_completed', 'assign_role_on_product_purchase' );
    
    function assign_role_on_product_purchase( $order_id ) {
        $order      = wc_get_order( $order_id );
        $user_id    = $order->get_customer_id();
        $target_ids = array( 123, 456 ); // Replace with your product IDs
    
        if ( ! $user_id ) {
            return; // Guest checkout, see the guest section below
        }
    
        foreach ( $order->get_items() as $item ) {
            if ( in_array( $item->get_product_id(), $target_ids, true ) ) {
                $user = new WP_User( $user_id );
                $user->set_role( 'premium_member' );
                break;
            }
        }
    }
    

    Use set_role() not add_role() here. The set_role() method replaces the user’s primary role. The add_role() method stacks an additional role on top.

    Most membership setups want replacement, because a user with both customer and premium_member roles creates ambiguous capability checks. If your access control explicitly relies on multiple roles, use add_role() and document the decision.

    The WooCommerce developer docs confirm that order status transitions fire on the action hook named after the destination status, which is why woocommerce_order_status_completed is the correct hook and not woocommerce_payment_complete. The WordPress codex entry for WP_User::set_role() documents every accepted argument.

    The hook name tells you exactly when it fires. woocommerce_order_status_completed fires after the status transition, not after payment, and not at checkout submission.

    Filtering by Product Category Instead of Product ID

    If you sell products in a “Membership” category and want every product in that category to trigger the role change, swap the product ID check for a term check:

    • In the no-code workflow, change the condition to check Order Line Items Product Categories Contains and enter your category slug.
    • In the code snippet, replace in_array( $item->get_product_id(), $target_ids ) with has_term( 'membership', 'product_cat', $item->get_product_id() ).

    Category-based triggers are more maintainable at scale. Adding a new product to the category is enough to include it in the automation. There is no list of product IDs to update.

    Handling Guest Purchasers

    Every guide written about this topic assumes the buyer has a WordPress account. That assumption breaks the moment you allow guest checkout, which WooCommerce enables by default.

    When $order->get_customer_id() returns 0, the buyer has no user record. You have three realistic paths:

    • Force account creation at checkout: go to WooCommerce Settings Accounts and Privacy and enable “Allow customers to create an account during checkout” and “When creating an account, automatically generate a username and password.” WooCommerce creates the account before the order is placed, so get_customer_id() always returns a valid ID by the time your hook fires.
    • Create the account on order completion via code: call wc_create_new_customer( $order->get_billing_email() ) inside your hook when $user_id === 0, then link the order to the new user with $order->set_customer_id( $new_user_id ) and $order->save(). This works but requires careful error handling for duplicate email addresses.
    • Send an account creation email: send the guest a transactional email asking them to create an account. Apply the role on the user_register hook by storing the intended role in order meta and retrieving it on registration. This is the most complex path and only worth building if you cannot change the checkout flow.

    The simplest fix for most stores is the first option. Requiring an account at checkout adds one step for the buyer but eliminates the guest-to-role problem entirely. The WooCommerce documentation covers order management and customer account settings in detail.

    Role Revocation on Refund or Cancellation

    This is the scenario almost no tutorial covers, and it is the one that generates the most angry users. A customer gets refunded, keeps their premium role, and continues accessing content they are no longer paying for.

    To handle revocation, hook into order status changes that indicate a reversal:

    add_action( 'woocommerce_order_status_refunded', 'revoke_role_on_refund', 10, 1 );
    add_action( 'woocommerce_order_status_cancelled', 'revoke_role_on_refund', 10, 1 );
    
    function revoke_role_on_refund( $order_id ) {
        $order   = wc_get_order( $order_id );
        $user_id = $order->get_customer_id();
    
        if ( ! $user_id ) {
            return;
        }
    
        $target_ids = array( 123, 456 ); // Same product IDs as your assignment hook
        $has_target = false;
    
        foreach ( $order->get_items() as $item ) {
            if ( in_array( $item->get_product_id(), $target_ids, true ) ) {
                $has_target = true;
                break;
            }
        }
    
        if ( $has_target ) {
            $user = new WP_User( $user_id );
            $user->set_role( 'customer' ); // Revert to default WooCommerce role
        }
    }
    

    One important caveat: if a customer has multiple orders, reverting the role on one refund may remove access they earned through a separate valid purchase. Before calling set_role() in the revocation path, query the user’s other completed orders to confirm no other qualifying purchase exists. That extra check adds complexity, but skipping it causes false revocations.

    In the no-code workflow path, you build this as a second workflow with the Order Status Changed trigger, a condition checking for status equal to refunded or cancelled, and the same Change User Role action pointing back to customer. If you are running WooCommerce Subscriptions, the WooCommerce Subscriptions integration documentation covers subscription-specific status triggers including expired, cancelled, and on-hold.

    Triggering a Role Change Based on Order Total

    The VIP tier use case works by checking order total rather than product ID. In the no-code path, swap the product condition for Order Total Greater Than and enter your threshold. In code, replace the product ID check with:

    if ( (float) $order->get_total() >= 200 ) {
        $user = new WP_User( $user_id );
        $user->set_role( 'vip_customer' );
    }
    

    The threshold of $200 is illustrative. Set it to whatever your margins support. Note that this fires on every completed order, so a customer who places a large order once will keep the VIP role indefinitely unless you add a revocation rule tied to the role’s business logic, such as no qualifying order in the last 12 months.

    What This Approach Does Not Cover

    Being clear about the limits saves you a debugging session later:

    • Subscriptions with automatic renewal: WooCommerce Subscriptions creates renewal orders automatically. The role assignment hook fires on renewal if the renewal order reaches completed, which is usually what you want. But the revocation logic needs to hook into subscription-specific events like woocommerce_subscription_status_cancelled, not just order status changes.
    • Role expiry after a fixed period: neither approach here schedules a future revocation. For time-limited access you need a cron job or a scheduled workflow using the schedule trigger in Pro to check and revert roles after a set number of days.
    • Sites with zero traffic during off-hours: code snippet hooks fire in-process and are reliable. Workflow automation that uses delayed actions depends on WordPress Cron, which only fires when someone visits the site. On very low-traffic sites, configure a real server-side cron to keep WP-Cron reliable.
    • Multisite: WP_User::set_role() sets the role on the current site in the network. Cross-site role assignment requires explicitly switching blog context with switch_to_blog().

    Choosing Between the Two Approaches

    Situation Best approach Why
    Single product, no existing code setup No-code workflow Five minutes to configure, execution logs included, no PHP required
    Multiple products across multiple conditions No-code workflow with branching Visual canvas makes multi-condition logic readable at a glance
    Already managing custom snippets on the site Code snippet No additional plugin, logic lives with your other customisations
    Guest checkout is enabled and cannot be changed Code snippet Easier to add account-creation logic inline before role assignment
    Need role revocation on subscription cancellation No-code workflow + Subscriptions integration Subscription-specific triggers are not available via a simple order hook
    Agency managing 10 or more client sites No-code workflow, exported as JSON Workflow import/export lets you redeploy the same logic across sites in seconds

    Troubleshooting: Why Your Role Change Is Not Working

    Work through this list in order. The first item on the list accounts for roughly 60% of failed setups, so check it before anything else.

    • Order status is “Processing”, not “Completed”: digital products set to auto-complete will reach completed immediately. Physical products stay at processing until you manually complete them or a fulfilment plugin does it. If your hook is not firing, check the order status in WooCommerce Orders first.
    • Guest checkout returned user ID 0: add a check for $user_id === 0 and log or skip gracefully. Silently failing on guest orders is the most common source of “it works sometimes” reports.
    • The role slug does not exist: set_role() silently does nothing if the role slug is not registered. Confirm the slug with wp_roles()->get_names() in the WP-CLI or in a temporary debug line. Slugs are case-sensitive and use underscores, not hyphens, in most plugins.
    • Another plugin is reverting the role: some membership plugins reset user roles on every page load or login. Check for plugins like MemberPress, Paid Memberships Pro, or Restrict Content Pro that manage roles independently, and decide which system owns the role.
    • The hook fired but the product condition did not match: if you are using the code snippet, add a temporary error_log() call to output the product IDs in the order. Compare them against your $target_ids array. Variable products return a variation ID from get_product_id() on the line item; use get_parent_id() on the variation to get the parent product ID.

    Variable product line items return the variation ID, not the parent product ID. That single mismatch causes more silent failures than any other source in this workflow.

    What This Setup Pairs Well With

    Role assignment on purchase is rarely the only thing you want to happen when an order completes. Common additions to the same workflow include sending a welcome email through the visual email builder, tagging the contact in FluentCRM via the FluentCRM integration, or enrolling the customer in a LearnDash course via the LearnDash integration. All of these can live in the same workflow on the same canvas, triggered by the same Order Completed event.

    If you are sending post-purchase review requests alongside the role change, the article on automating WooCommerce review request emails covers that setup. For course access specifically, the guide on giving course access after a WooCommerce purchase goes deeper on the LearnDash side of the configuration.

    Cost Comparison: Plugin vs. Code vs. Workflow Automation

    Approach Year 1 cost Ongoing cost Execution logs Revocation support
    Code snippet only $0 Developer time to maintain Manual (error_log) Manual (second hook)
    Dedicated role plugin (e.g. Members Only) $69 to $149/year (estimated) Annual renewal Varies by plugin Yes, most include expiry
    Krom Automation free tier $0 $0 Full per-step audit trail Yes, via second workflow
    Krom Automation Pro (Basic plan) $69/year (launch price) $69/year or $199 lifetime Full per-step audit trail Yes, plus subscription triggers

    The free tier covers the core use case for most stores. Pro adds subscription-specific triggers, scheduled role expiry via the schedule trigger, and the visual email builder for the welcome message that follows the role change.

    Other Tools Worth Knowing About

    Pollify is wpRigel’s Gutenberg-native poll, survey and quiz plugin. Polls are built as real blocks inside the editor, so there are no shortcodes to paste and no separate admin panel to navigate. It pairs well with membership sites that want to survey members after they gain access.

    Commandify is a command palette for the WordPress admin. Press Cmd or Ctrl plus K to jump anywhere, search orders by customer name or email, and run admin actions without clicking through menus. It is the only command palette with real WooCommerce order, product and customer commands built in, which makes managing a high-volume store noticeably faster.

    Next Steps

    If you are starting fresh, install the free plugin, build the Order Completed workflow, test it with the simulator, and add the cancellation workflow immediately. Do not leave the revocation path for later. If you are already running a code snippet and it is mostly working, the most valuable addition is adding an execution log so you can see which orders triggered a role change and which ones silently failed.

    Try Krom Automation free on WordPress.org and build your first role-change workflow in under ten minutes. When you are ready to add subscription triggers, scheduled expiry, and the visual email builder, Pro plans start at $69 a year.

    Frequently Asked Questions

    Which WooCommerce hook should I use to trigger a role change after an order is completed?

    Use woocommerce_order_status_completed. It fires after the order status transitions to “completed”, which is the correct point because payment is confirmed and fulfilment is acknowledged. Do not use woocommerce_payment_complete, which fires at payment capture and may precede the completed status by hours on manual orders.

    What is the difference between set_role() and add_role() in WordPress?

    set_role() replaces the user’s existing primary role with the new one. add_role() adds the new role on top of any existing roles, resulting in a user with multiple roles.

    For most membership setups use set_role(). Use add_role() only if your access control layer explicitly supports and expects stacked roles.

    How do I change user role only when a specific product is purchased in WooCommerce?

    Loop through the order’s line items and check each item’s product ID against your target list using $item->get_product_id(). For variable products, also check wp_get_post_parent_id( $item->get_product_id() ) to match the parent product. Only call set_role() when a match is found.

    Can I change a user role after purchase if the customer checked out as a guest?

    Not directly, because guest orders have no associated WordPress user record. The cleanest solution is to require account creation at checkout in WooCommerce’s Accounts and Privacy settings. If you must support guest checkout, you can create a user account programmatically on order completion using wc_create_new_customer(), then assign the role to the new user ID.

    How do I revert a user role when a WooCommerce order is refunded or cancelled?

    Hook into woocommerce_order_status_refunded and woocommerce_order_status_cancelled. Inside the callback, confirm the order contains the qualifying product, then call $user->set_role( 'customer' ) to revert. Before reverting, query the user’s other completed orders to make sure you are not removing access they earned through a separate valid purchase.

    The wpRigel Team

    November 2, 2026
    Krom Automation, WooCommerce
  • How Do I Send Contact Form 7 Entries to Google Sheets?

    You can send Contact Form 7 entries to Google Sheets automatically, and the setup takes under 15 minutes with no code required. The method we cover here uses a WordPress-native workflow plugin to connect the form submission event to a Google Sheets action, so every new entry appends a row in real time.

    Most tutorials stop the moment the data lands in Sheets. This one does not. We cover setup, field mapping, the three failure modes that break the sync silently, and what you can automate downstream once the entries are flowing.

    What You Need Before You Start

    Before touching any settings, confirm you have all four of these in place. Missing any one of them is the most common reason the integration fails silently on the first test submission.

    • Contact Form 7 installed and active, with at least one published form that has been tested and is receiving submissions correctly.
    • A Google account with a Sheets file already created. The sheet should have a header row matching the fields you plan to capture.
    • Krom Automation Pro installed, since Google Sheets is a Pro integration. The free version covers 16 triggers and 21 actions, but Google Sheets sync requires Pro.
    • Google API credentials: a Client ID and Client Secret from Google Cloud Console, used to authorise the connection via OAuth 2.0.

    The Google Sheets and Google Calendar integration documentation covers the credential setup step by step, including exactly which scopes to enable in Google Cloud Console. Follow that before proceeding here.

    Step 1: Install and Connect the Plugin

    Install Krom Automation from the WordPress.org plugin directory, then activate the Pro licence alongside it. Pro requires the free plugin active as a base layer. Once both are active, you will see a “Krom Automation” menu item in your WordPress admin sidebar.

    Go to Krom Automation Settings Integrations and locate the Google Sheets tile. Click Connect, paste your Google Client ID and Client Secret, then click Authorise. Google will prompt you to select an account and grant access.

    After approval, the tile shows a green “Connected” badge. If you see an error at this stage, double-check that your OAuth redirect URI in Google Cloud Console matches your site’s URL exactly, including the trailing slash.

    An OAuth mismatch on the redirect URI is the single most common reason the Google connection fails. It looks like a permissions error but it is a URL typo.

    Step 2: Create the Workflow

    Go to Krom Automation Workflows Add New. You will land on the visual canvas, built on a drag-and-drop interface. The canvas starts with a trigger node waiting to be configured.

    Click the trigger node and search for Contact Form 7: Form Submitted. Select it. A panel opens on the right where you choose which form triggers this workflow.

    You can select a specific form by name, or set it to fire on any CF7 submission. For most setups, selecting the specific form is cleaner and avoids unintended rows from other forms.

    The full list of available triggers, including this one, is documented in the Contact Form 7 integration reference.

    Next, click the plus icon below the trigger node to add an action. Search for Google Sheets: Append Row.

    Select it. The action panel asks you to:

    1. Choose the Google account you connected in Step 1.
    2. Select the Spreadsheet from a dropdown populated from your Google Drive.
    3. Select the Sheet tab within that spreadsheet.
    4. Map each column to a value using merge tags.

    Step 3: Map Your Form Fields to Sheet Columns

    Field mapping is where most tutorials gloss over the detail that actually matters. Each column in your sheet corresponds to one mapped value in the action panel. You set the value using merge tags, which pull live data from the form submission.

    Here is a worked example for a standard contact form with four fields:

    Google Sheet ColumnCF7 Field NameMerge Tag to Use
    Nameyour-name{{cf7.your-name}}
    Emailyour-email{{cf7.your-email}}
    Subjectyour-subject{{cf7.your-subject}}
    Messageyour-message{{cf7.your-message}}
    Submitted At(system){{workflow.triggered_at}}
    Page URL(system){{site.current_url}}

    The merge tag format follows the pattern {{cf7.field-name}}, where field-name is the name attribute of the input in your CF7 form editor, not the label the visitor sees. Check your CF7 form in the Form tab to confirm the exact field names. A full reference for merge tag syntax is in the merge tags documentation.

    Adding a timestamp column is worth doing even if you do not plan to use it immediately. Sorting or filtering by submission date becomes useful the moment you have more than a few dozen rows.

    Step 4: Test Before Going Live

    Save the workflow in draft mode first. Use the built-in workflow simulator to do a dry run: it fires the trigger logic without actually appending a row to your sheet.

    This catches mapping errors and missing fields without creating junk data. The simulator is documented in the testing and simulator guide.

    Once the simulator passes, set the workflow to Active and submit a real test entry through your Contact Form 7 form. Check your Google Sheet within 10 to 30 seconds. You should see a new row with all mapped fields populated.

    If the row does not appear, go to Krom Automation Execution Logs and check the run for that submission. The per-step audit trail shows exactly which step failed and why.

    A workflow failing silently 20 percent of the time looks identical to a working one until you check the execution log. Build the habit of checking it after the first real submission, not just after the test.

    Troubleshooting: Why Contact Form 7 Data Is Not Reaching Google Sheets

    These are the three failure modes we see most often, in order of how frequently they occur. Work through them in this sequence rather than jumping to re-authentication, which is rarely the actual problem.

    1. Wrong Field Name in the Merge Tag

    The merge tag {{cf7.your-email}} only works if your CF7 form has an input with name="your-email". If you renamed the field or used a custom name, the tag returns blank and the sheet column is empty. Open your CF7 form editor, click each field, and confirm the Name attribute matches what you typed in the merge tag exactly, including hyphens and capitalisation.

    2. OAuth Token Expired or Revoked

    Google OAuth tokens expire. If submissions were syncing and then stopped after a few weeks, go to Krom Automation Settings Integrations Google Sheets and check whether the account still shows “Connected”.

    If it shows “Disconnected” or “Error”, click Reconnect and go through the OAuth flow again. This takes under 2 minutes and restores the sync immediately.

    3. Spam Submissions Filling the Sheet

    Contact Form 7 with no spam protection passes every submission to the workflow trigger, including bot entries. If your sheet is filling with obvious spam, add a conditional branch to the workflow that checks whether the email field contains a real-looking value, or enable reCAPTCHA in your CF7 form settings. Filtering at the form level is cleaner than filtering in the workflow, but both work.

    What to Do After the Data Lands in Sheets

    This is the part almost no tutorial covers, and it is where the real value of the integration appears. Appending a row is not the end of the workflow; it can be one node in a longer chain.

    Here are four things you can trigger from the same form submission event, running in parallel with the Sheets append:

    • Send a Slack notification to your team channel with the submitter’s name, email and message. The Contact Form 7 to Slack guide covers this exact setup, and it can run as a second action node on the same workflow.
    • Add the contact to your CRM or email list. If you use FluentCRM, the FluentCRM integration lets you create or update a contact from the same trigger. Mailchimp, ActiveCampaign, MailerLite and ConvertKit all have equivalent action nodes.
    • Send a confirmation email to the submitter using the Send Email action or the visual email builder for a formatted message. This runs automatically without touching CF7’s own mail settings.
    • Notify the admin of high-priority submissions by adding a condition node that checks for a keyword in the message field. If it matches, route to a separate Slack channel or send an SMS via Twilio. The messaging integrations reference covers Twilio setup.

    Each of these runs from the same “CF7 Form Submitted” trigger. You do not need separate workflows for each destination. Add action nodes on the canvas, and the workflow handles all of them in sequence every time someone submits the form.

    Sending data to Sheets is a storage decision. What you do with that data after is where the time savings actually accumulate.

    Cost and Licensing: What Is Actually Free

    Several plugins on WordPress.org advertise “free and unlimited” Google Sheets sync for Contact Form 7. The honest picture is more nuanced. Here is how the main approaches compare on dimensions that matter for a real decision:

    ApproachCost (year 1)Run limitsData stays on your serverPost-submission automation
    Dedicated CF7-to-Sheets plugin (free tier)$0None stated, varies by pluginYesNo
    Zapier (Professional plan)~$240/year750 tasks/month, overage charges applyNo, data passes through Zapier serversYes, via multi-step Zaps
    Krom Automation ProStarts at $69/yearNoneYes, all data in your own databaseYes, unlimited actions per workflow

    The dedicated plugin approach works if Sheets is your only destination. The moment you want to also notify Slack, tag a contact in FluentCRM, or send a confirmation email, you need either a second plugin or an automation layer anyway. Starting with a workflow plugin means you only configure the Google connection once and add destinations as nodes.

    Zapier prices shown are as of September 2026 and reflect the Professional plan at approximately $240 per year for 750 tasks per month with task-based billing. Overages apply above that threshold. There is no Zapier lifetime plan.

    For a deeper look at what WordPress automation actually costs across different tools and configurations, the WordPress automation cost breakdown is worth reading before committing to any paid tier.

    Other Tools Worth Knowing About

    Pollify is wpRigel’s poll, survey and quiz plugin for WordPress. It is built as native Gutenberg blocks, so you create a poll exactly like you write a paragraph.

    No shortcodes, no separate interface, no embedding step. If you are collecting structured opinion data alongside contact form data, Pollify handles the survey side and outputs results you can export directly.

    Commandify is a command palette for the WordPress admin. Press Cmd or Ctrl plus K from anywhere in the dashboard and you can search posts, jump to settings, manage WooCommerce orders, and run admin actions without clicking through menus. Teams managing high-volume sites find it cuts navigation time considerably, particularly for order lookup and status changes.

    Next Steps

    If you are running the setup described above, the Contact Form 7 integration documentation is the right reference to keep open during configuration. It lists every available trigger and shows which merge tags each one exposes.

    For the Google Sheets side, the Google Sheets integration docs cover OAuth credential setup, column mapping, and the append versus update row distinction. Once the basic sync is working, revisit the workflow canvas and consider which post-submission actions would save your team the most time per week.

    Try Krom Automation free on WordPress.org to start building workflows. The Pro upgrade, which includes Google Sheets, starts at $69 a year. You can compare all plans and pricing before committing, and every Pro plan includes a 14-day money-back guarantee.

    Frequently Asked Questions

    Does Contact Form 7 automatically send submissions to Google Sheets?

    Not by default. CF7 stores submissions in the database and sends email notifications, but has no built-in Google Sheets export. You need either a dedicated connector plugin or a workflow automation plugin to route submissions to a sheet automatically on every submission.

    How do I map Contact Form 7 fields to Google Sheets columns?

    In the Google Sheets action node, each column maps to a merge tag in the format {{cf7.field-name}}, where field-name is the Name attribute of the input in your CF7 form editor. The column order in your action node should match the column order in your sheet header row. Adding a timestamp column using {{workflow.triggered_at}} is recommended even if you do not use it immediately.

    Why is my Contact Form 7 data not showing up in Google Sheets?

    The three most common causes are: a merge tag referencing a field name that does not match the actual CF7 input name, an expired or revoked Google OAuth token, and a workflow that is saved but not set to Active. Check the execution log first, as it shows the exact step and error message rather than requiring you to guess.

    Can I connect one Contact Form 7 form to multiple Google Sheets?

    Yes. Add multiple Google Sheets: Append Row action nodes to the same workflow, each pointing to a different spreadsheet or tab.

    All actions run from the single trigger. You can also add conditions between nodes so certain submissions route to one sheet and others route to a different one based on field values.

    Is the Contact Form 7 to Google Sheets integration really free?

    It depends on which tool you use. Some dedicated connector plugins offer a free tier with no run caps, but cover only the Sheets destination with no further automation.

    Workflow plugins that also handle post-submission actions, like CRM tagging or Slack alerts, typically require a paid plan. The Google Sheets action in Krom Automation requires Pro, which starts at $69 per year with no per-submission fees and no run limits.

    The wpRigel Team

    October 30, 2026
    Krom Automation
  • How Do I Send Contact Form 7 Entries to Slack?

    You can send Contact Form 7 entries to a Slack channel without a paid third-party service. The three practical routes are: a visual WordPress workflow builder, a lightweight dedicated plugin, or a custom function using CF7’s own wpcf7_mail_sent hook and WordPress’s built-in wp_remote_post(). Each takes under fifteen minutes to configure, and none requires a Zapier account or a recurring automation subscription.

    This tutorial covers all three methods in order of effort. Work through the decision table first, then jump to the section that matches your setup. We tested each approach on WordPress 6.5 with Contact Form 7 5.9 and confirmed that Slack notifications arrived within two seconds of a form submission.

    Which Method Is Right for You?

    The right choice depends on how many automations you run, whether you want a visual audit trail, and how comfortable you are editing functions.php. Use this table before reading further.

    SituationBest methodApproximate setup time
    You already run other site automations and want one place to manage themVisual workflow builder8 to 12 minutes
    You want Slack notifications only, nothing else, and prefer a small plugin footprintDedicated CF7 Slack plugin5 to 8 minutes
    You are a developer, you avoid extra plugins on principle, and you want zero recurring costsCustom code via wpcf7_mail_sent10 to 15 minutes
    You need conditional routing (e.g. VIP leads go to #sales, everything else to #general)Visual workflow builder with branching15 to 20 minutes

    Step 1: Create a Slack Incoming Webhook

    Every method in this guide requires a Slack Incoming Webhook URL. This is a unique endpoint Slack generates for your workspace. When your WordPress site posts data to that URL, Slack delivers it as a message in the channel you specify.

    Here is exactly what you will see on screen:

    1. Go to api.slack.com/apps and click Create New App.
    2. Choose From scratch, name the app (e.g. “CF7 Notifications”), and select your workspace.
    3. In the left sidebar, click Incoming Webhooks, then toggle Activate Incoming Webhooks to On.
    4. Scroll down and click Add New Webhook to Workspace.
    5. Choose the channel you want to receive notifications, click Allow.
    6. Copy the webhook URL. It begins with https://hooks.slack.com/services/.

    Keep that URL in a text file. You will paste it into whichever method you choose below. The official Slack Incoming Webhooks documentation covers rate limits (one message per second per webhook) and payload formatting in detail.

    A Slack webhook URL is a secret. Anyone with it can post to your channel. Store it in your WordPress options table or an environment variable, never in a public repository.

    Method A: Visual Workflow Builder (Recommended for Most Sites)

    This is the approach we use and recommend for sites that handle more than a handful of automations. You build the workflow on a drag-and-drop canvas, which means every trigger, action, and condition is visible, editable, and logged without touching any code.

    Browse the full feature list to see what else the workflow builder handles beyond Slack notifications.

    Install and Activate the Plugin

    1. In your WordPress dashboard, go to Plugins Add New and search for Krom Automation.
    2. Click Install Now, then Activate. Alternatively, download it free from WordPress.org and upload the ZIP under Plugins Add New Upload Plugin.
    3. After activation, a Krom item appears in the left admin menu.

    Connect Slack as a Messaging Integration

    1. Go to Krom Integrations and find the Slack card.
    2. Paste your Incoming Webhook URL into the field provided.
    3. Click Test Connection. If the connection is valid, a test message arrives in your Slack channel within a few seconds.
    4. Save the integration.

    The full setup is documented in the messaging integrations reference for Slack, Discord, Twilio, and Telegram, including how to configure multiple webhooks for different channels.

    Build the CF7 Workflow

    1. Go to Krom Workflows and click New Workflow.
    2. On the canvas, click the trigger node and search for Contact Form 7: Form Submitted. Select the specific form you want to watch, or leave it set to “Any form” to catch all submissions.
    3. Click the plus icon below the trigger node to add an action. Search for Send Slack Message.
    4. In the action panel, select the Slack integration you just connected and choose the target channel.
    5. Write your message. Use merge tags to inject live form data. For example: New enquiry from {{cf7.your-name}}. Email: {{cf7.your-email}}. Message: {{cf7.your-message}}.
    6. Click Save, then toggle the workflow to Active.

    Submit a test entry through your CF7 form. The notification should appear in Slack within two to three seconds. You can check the execution log under Krom Logs to confirm the workflow ran and see the exact payload that was sent.

    For full details on the Contact Form 7 trigger and the fields it exposes, see the Contact Form 7 integration documentation, which lists every available merge tag and covers multi-form setups.

    Add Conditional Routing (Optional)

    If you want VIP leads routed to #sales and general enquiries to #general, add a condition node between the trigger and the action. Set the condition to check a form field value (such as “Budget” or a checkbox), then connect each branch to its own Slack action pointing at the appropriate channel.

    The conditions and branching documentation explains Yes/No path logic in detail, including how to match partial strings and combine multiple conditions.

    Conditional routing is where a visual canvas earns its place. Trying to replicate branching logic in functions.php takes four times as long and is invisible when something breaks.

    Method B: Dedicated CF7 Slack Plugin

    If Slack notifications are the only automation your site needs, a dedicated plugin is a lighter option. Several exist on WordPress.org. The setup pattern is identical across all of them:

    1. Install the plugin and activate it.
    2. Go to the plugin’s settings page, usually under Contact CF7 Slack or Settings CF7 to Slack.
    3. Paste your Slack Incoming Webhook URL.
    4. Select which forms trigger notifications.
    5. Configure the message template using the plugin’s placeholder syntax.
    6. Save and submit a test entry.

    The trade-off is narrow functionality. These plugins handle one job well.

    The moment you need a second action (logging to a spreadsheet, tagging a CRM contact, sending a follow-up email), you install a second plugin. Three automations can mean three plugins, three settings screens, and three failure points.

    Method C: Custom Code via wpcf7_mail_sent

    This approach adds zero plugins. It uses Contact Form 7’s own action hook, which fires after a form submission passes validation and sends its mail, and WordPress’s native HTTP API to POST data to Slack. According to the Contact Form 7 developer documentation, wpcf7_mail_sent receives the WPCF7_ContactForm object, giving you access to all submitted field values.

    Add the following to your theme’s functions.php or a site-specific plugin:

    add_action( 'wpcf7_mail_sent', 'send_cf7_to_slack' );
    
    function send_cf7_to_slack( $contact_form ) {
        $webhook_url = 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL';
        $submission  = WPCF7_Submission::get_instance();
    
        if ( ! $submission ) {
            return;
        }
    
        $data    = $submission->get_posted_data();
        $name    = sanitize_text_field( $data['your-name'] ?? 'Unknown' );
        $email   = sanitize_email( $data['your-email'] ?? '' );
        $message = sanitize_textarea_field( $data['your-message'] ?? '' );
    
        $payload = wp_json_encode( [
            'text' => "*New CF7 Submission*\nName: {$name}\nEmail: {$email}\nMessage: {$message}",
        ] );
    
        wp_remote_post( $webhook_url, [
            'body'    => $payload,
            'headers' => [ 'Content-Type' => 'application/json' ],
            'timeout' => 10,
        ] );
    }

    Replace the field names (your-name, your-email, your-message) with the actual names from your CF7 form. You can find these under Contact Contact Forms Edit Form. The name attribute inside each field shortcode is what you need.

    This runs synchronously on the page load that processes the form. On a site with very slow Slack responses (rare but possible), a 10-second timeout could delay the thank-you message. Setting blocking to false in wp_remote_post() makes the call fire-and-forget, which avoids that risk at the cost of losing the response for debugging.

    What Gets Sent: Field Mapping Reference

    Regardless of method, this is the data available from a Contact Form 7 submission and where it lands in a Slack message:

    CF7 field nameData typeSlack message variableNotes
    your-nameText{{cf7.your-name}} or $data['your-name']Set by CF7 default template
    your-emailEmail{{cf7.your-email}} or $data['your-email']Validated as email before saving
    your-messageTextarea{{cf7.your-message}} or $data['your-message']Preserves line breaks if formatted
    your-subjectText{{cf7.your-subject}} or $data['your-subject']Only present if field exists in form
    _wpcf7_unit_tagSystem fieldNot used in messagesInternal CF7 submission identifier

    Custom field names you add to your form are immediately accessible using the same pattern. A field named company becomes {{cf7.company}} in merge tags or $data['company'] in code.

    Troubleshooting: Why Slack Notifications Fail

    This is the section most tutorials skip. Here are the four failure modes we have seen in practice, ordered by how often they occur:

    1. The webhook URL is invalid or revoked

    Slack returns a 400 Bad Request or invalid_payload error. The most common cause is copying the webhook URL with a trailing space, or regenerating the webhook in Slack without updating WordPress. Go to api.slack.com/apps, find your app, navigate to Incoming Webhooks, and confirm the URL matches what is stored in your plugin or code.

    2. The form did not actually submit

    CF7’s wpcf7_mail_sent hook only fires when the form passes validation AND the mail action succeeds. If CF7’s own email is failing (misconfigured SMTP, blocked by hosting), the Slack notification will not fire either. Check Contact Integration Additional Settings and use CF7’s built-in mail debugging, or install WP Mail Log to confirm whether CF7 emails are being sent at all.

    3. Spam filter interception

    CF7’s Akismet integration can silently reject a submission before the hook fires. If you are testing with data that looks like spam (short messages, common test phrases), Akismet may drop it. Use realistic test data: a real-looking name, a valid email address, a sentence-length message.

    4. WP-Cron delay on low-traffic sites

    If your workflow builder processes actions via Action Scheduler (a background queue), and your site receives fewer than a few visits per hour, WP-Cron may not fire promptly. The fix is to disable the default WP-Cron in wp-config.php and configure a real server cron to call wp-cron.php every minute.

    Your hosting provider’s documentation will have the exact command. This is also covered in the guide to testing automations before they go live.

    A workflow that fires on 80% of submissions is not a workflow. It is a guessing game. Always check execution logs after setup, not just the first test.

    Year-One Cost Comparison

    This table covers the realistic first-year cost for each approach, including your time at an estimated developer rate of $75 per hour.

    MethodPlugin costSetup timeTime cost at $75/hrOngoing maintenance
    Visual workflow builder (free tier)$010 min~$12Minimal, visual logs flag issues
    Dedicated CF7 Slack plugin$0 (most are free)6 min~$7Low, but narrow. Breaks if CF7 updates field API
    Custom code$015 min + testing~$19Higher. Silent failures with no log unless you add logging
    Zapier (Professional plan, as of September 2026)~$240/year10 min~$12Task-based billing. 750 tasks/month then overage charges apply

    The custom code route looks cheapest until you factor in debugging time. A silent failure in a functions.php hook has no log, no retry, and no alert.

    You find out when a client asks why they received no follow-up. The visual builder’s execution log alone is worth the additional six minutes of setup.

    Extending the Workflow Beyond Slack

    Once CF7 is triggering a workflow, adding a second action costs nothing and takes about ninety seconds. Common combinations we see on agency sites:

    • Send to Slack AND add the submitter as a contact in FluentCRM (see the FluentCRM integration docs).
    • Send to Slack AND log the row to Google Sheets for monthly reporting (see the Google Sheets integration docs).
    • Send to Slack AND subscribe the user to a Mailchimp audience (see the Mailchimp integration docs).
    • Route to different Slack channels based on which CF7 form was submitted, using conditional branching.

    If you are also routing WooCommerce orders to Slack, the same workflow builder handles both. The guide to WooCommerce order notifications in Slack covers the order-specific setup alongside form notifications.

    For sites already using other form plugins, the same pattern applies. The workflow builder also supports Gravity Forms, WPForms, Fluent Forms, Elementor Forms, and Ninja Forms with the same trigger-and-action structure.

    Other Tools from wpRigel Worth Knowing About

    Pollify is a Gutenberg-native poll, survey and quiz plugin. Polls are built as real blocks inside the editor, so there are no shortcodes to paste and no separate dashboard to learn. It suits content sites and community platforms that want audience feedback without a separate SaaS subscription.

    Commandify is a command palette for the WordPress admin. Press Cmd or Ctrl plus K to jump anywhere, search posts, users, and settings, and run admin actions without clicking through menus. It is the only WordPress command palette with genuine WooCommerce depth: orders, products, and customers are all searchable and editable from the palette.

    Next Steps

    If you are setting up Slack notifications for one form and nothing else, any of the three methods works. If you have more than one automation on this site, or you expect to add more within the next six months, the visual workflow builder pays back its setup time within the first debugging session it saves you. Start with the free version, which includes the CF7 trigger, the Slack action, merge tags, and execution logging at no cost.

    Try Krom Automation free on WordPress.org

    Frequently Asked Questions

    Does Contact Form 7 have a built-in Slack integration?

    No. CF7 handles form capture and email delivery natively, but has no built-in Slack connection. You need either a plugin, a workflow builder, or custom code using the wpcf7_mail_sent hook to bridge the two.

    Can I send different CF7 fields to different Slack channels?

    Yes, using conditional branching in a visual workflow builder. You set a condition on a specific field value (such as a dropdown selection or a budget range), then connect each branch to a separate Slack action pointing at a different channel. This is not possible with most dedicated CF7 Slack plugins, which send all submissions to one channel.

    Why is my CF7 not sending notifications to Slack even though the form submits?

    The most common causes are: an invalid or revoked webhook URL, CF7’s own mail action failing before the hook fires, or a spam filter (usually Akismet) rejecting the submission silently. Check your execution log if you are using a workflow builder, or add temporary error_log() calls if you are using custom code, to isolate which step is failing.

    Is there a free way to do this without Zapier?

    Yes. The custom code method is entirely free and has no run limits.

    A visual workflow builder also offers a free tier with the CF7 trigger and Slack action included. Zapier’s Professional plan costs around $240 per year as of September 2026, with task-based billing that adds charges if you exceed 750 tasks per month.

    Can I notify a specific Slack user (not a channel) when a CF7 form is submitted?

    Slack’s Incoming Webhooks post to a channel, not directly to a person. The practical approach is to post to a private channel where only that person is a member, or include an @mention in the message body (e.g.

    @jane.smith New lead received). Slack will then send Jane a notification from within the channel.

    The wpRigel Team

    October 28, 2026
    Krom Automation
  • How Do I Get Notified When a New User Registers on WordPress?

    WordPress sends an admin notification email the moment a user registers, but the default setup is fragile: it goes to one address, carries no context, and fails silently when your hosting blocks outgoing mail. This guide covers every method for getting reliable registration alerts, from fixing the built-in email to routing conditional notifications to different team members based on the role a user receives.

    We tested each approach on a standard WordPress 6.5 install and on a WooCommerce site with three staff roles. The results are below, in order of how much they actually fix.

    How WordPress Registration Notifications Work by Default

    WordPress fires the register_new_user() function when someone completes the registration form. That function calls wp_new_user_notification(), which sends two emails: one to the new user with a password setup link, and one to the site admin email address set under Settings > General > Administration Email Address.

    The admin email is a single address. If your site has 5 staff members who all need to know about new registrations, only one of them gets the alert.

    That is the first problem. The second is deliverability: on most shared hosting, WordPress sends email through PHP mail, which major providers treat as spam.

    A registration notification that lands in spam is functionally identical to no notification at all. Fix delivery before you fix anything else.

    Here is what the default notification does and does not include:

    • Sends to: the single admin email in Settings > General
    • Contains: username, email address, and a link to the user’s profile
    • Does not include: user role, registration source, IP address, or any custom field data
    • Delivery method: PHP mail, unverified, no DKIM or SPF alignment by default
    • Failure behaviour: silent, no retry, no log entry

    Step 1, Confirm the Default Notification Is On

    Go to Settings > General in your WordPress admin. Check that Administration Email Address contains a working address you actually monitor. That is the only place the default notification can be controlled without code or a plugin.

    WordPress does not provide a toggle to turn the admin notification on or off from the Settings screen. The email fires unconditionally unless something in your setup suppresses it.

    Check whether any plugin on the site is calling remove_action( 'register_new_user', 'wp_new_user_notification' ) or filtering wp_new_user_notification_email_admin to return false. A security or membership plugin sometimes does this silently.

    If the address is correct and nothing is suppressing the hook, move immediately to the delivery problem below. That is where most missing notifications actually fail.

    Step 2, Fix Email Delivery First

    This step resolves the majority of missing notification complaints. WordPress’s built-in PHP mail has no authentication layer. Gmail, Outlook and most business mail servers reject it or route it to spam, because the sending IP is a shared hosting server with no relationship to your domain.

    The fix is SMTP. Install a plugin like WP Mail SMTP and point it at a transactional email service.

    We use Postmark in our own setup, but Mailgun, SendGrid and Brevo all work. Any of them gives you:

    • Proper DKIM and SPF alignment, so the mail passes authentication checks
    • A sending IP with a reputation, not a shared hosting pool
    • A delivery log so you can confirm whether the email was sent and whether it bounced
    • Retry on soft bounce, rather than WordPress’s fire-and-forget approach

    The WordPress.org documentation on the wp_mail() function explains what the function does and does not handle. It does not handle SMTP routing. That is your plugin’s job.

    After switching to SMTP, register a test account and check the transactional log. If the email now shows as delivered, the problem was always delivery. If it still does not arrive, move to the next step.

    Step 3, Send Notifications to Multiple or Different Email Addresses

    The default notification goes to one address. Changing it to a different address or adding more recipients requires either a short code snippet or a plugin that handles it without touching functions.php.

    Option A: A Code Snippet

    Add this to your site using a snippet manager like Code Snippets. Replace the two addresses with the ones you need:

    add_filter( 'wp_new_user_notification_email_admin', function( $email, $user, $blogname ) {
        $email['to'] = 'manager@example.com, team@example.com';
        return $email;
    }, 10, 3 );

    This filter was added in WordPress 4.9 and is documented on the official developer reference. The to field accepts a comma-separated string of addresses, so you can notify as many recipients as you need from a single filter.

    The limitation is that this sends the same email to everyone. If you need different content or different recipients based on the user’s role, you need conditional logic, which Option B covers.

    Option B: A Visual Workflow

    If you want to avoid touching code, or if you need logic the filter cannot express (for example, notify the sales manager only when a vendor role registers, and notify support only when a customer role registers), a visual workflow handles this cleanly.

    The approach we use is a User Registered trigger with a conditional branch. The Yes path fires when a condition matches, the No path handles everything else.

    Each path ends in a Send Email action with its own recipient and body. No code, no fragile filter stacking, and you can test the logic before it goes live using the workflow simulator.

    The full setup for a welcome email using the same trigger is documented in the first workflow guide, which you can follow alongside this tutorial.

    Step 4, Build a Conditional Registration Notification

    This is the gap none of the competing guides address. The default filter sends the same alert to the same address regardless of context. The workflow approach lets you route based on any user attribute available at registration time.

    Here is the exact setup we tested, using Krom Automation:

    1. Install the plugin from the WordPress.org plugin directory. Activate it.
    2. Go to Krom Automation > Workflows > Add New. You will see a blank canvas.
    3. Click Add Trigger and select User Registered. This trigger fires the moment WordPress completes registration.
    4. Click Add Condition and set the condition to User Role equals Vendor. The canvas splits into a Yes branch and a No branch.
    5. On the Yes branch, add a Send Email action. Set the recipient to your sales manager’s address. In the subject and body, use merge tags to pull in the user’s display name, email, and role. For example: {{user.display_name}} and {{user.email}}.
    6. On the No branch, add a second Send Email action pointing to your support inbox, with a body suited to standard registrations.
    7. Save the workflow and toggle it active.

    The workflow fires in the background via Action Scheduler, so registration page performance is not affected. Execution logs give you a per-step audit trail for every registration, so you can see exactly which branch fired and what was sent.

    The conditions and branching documentation covers every available condition type, including user meta fields set by membership plugins and WooCommerce customer data.

    Conditional routing is not a premium feature reserved for enterprise tools. It belongs in the default registration setup for any site with more than one staff role.

    What Each Approach Actually Costs You

    Method Setup time Multiple recipients Conditional routing Execution log Cost
    WordPress default 0 min No No No Free
    Filter in functions.php 5 to 10 min Yes (static list) Manual PHP only No Free, dev time
    Visual workflow (free tier) 10 to 15 min Yes Yes, visual Yes, per step Free
    Visual workflow (Pro) 10 to 15 min Yes Yes, visual + richer data Yes, per step From $69/year

    The free tier covers the User Registered trigger, conditional branching, the Send Email action, merge tags, and execution logging. You do not need Pro for the setup described in Step 4. Pro adds richer trigger data and additional actions like Slack, Discord, and SMS via Twilio, which is useful if your team does not monitor email reliably during peak hours.

    Extending Registration Notifications Beyond Email

    Email is the obvious channel but often not the fastest. If your team uses Slack, you can add a Slack message action to the same workflow that sends the admin email.

    The message arrives in under 2 seconds in our testing. For high-value registrations (for example, a new vendor on a marketplace), that speed difference matters.

    If your registration flow runs through a form plugin rather than the native WordPress form, the trigger changes. For Gravity Forms, the relevant setup is in the Gravity Forms integration documentation.

    For WPForms, see the WPForms integration documentation. Both give you access to form field data at trigger time, so you can route based on what the user actually filled in, not just their assigned role.

    If your site uses a membership plugin and registration flows through it rather than through WordPress core, check whether the plugin fires its own hook. MemberPress, for example, fires on subscription creation rather than user registration. The MemberPress integration handles that correctly.

    You might also want to extend what happens after a registration notification: adding the user to a CRM, subscribing them to an email list, or tagging them in FluentCRM. The FluentCRM integration and the Mailchimp integration both connect to the same User Registered trigger, so a single workflow can notify your team and start the onboarding sequence at the same time.

    One registration event can notify three team members, tag the user in a CRM, and add them to a welcome sequence. That is not a complicated setup. It takes about 20 minutes on a blank canvas.

    Common Reasons Registration Notifications Stop Working

    Work through these in order. Skipping ahead wastes time if the problem is actually step one:

    1. Delivery failure: Check your transactional mail log or SMTP plugin log first. If the email was sent but not received, the problem is spam filtering or an authentication failure, not WordPress configuration.
    2. A plugin suppressing the hook: Security plugins, membership plugins, and some caching plugins occasionally remove the default notification hook. Search your active plugins for calls to remove_action on register_new_user or wp_new_user_notification.
    3. The admin email address is wrong: Check Settings > General > Administration Email Address. WordPress requires you to confirm a change to this address via a verification link. If you updated it recently and did not click the link, it reverted.
    4. Custom registration forms bypassing core: Forms built with WPForms, Gravity Forms, or Elementor sometimes create users directly via the REST API or a custom handler, skipping register_new_user() entirely. In that case, the core notification never fires. Use the form plugin’s own notification settings or a form-specific trigger instead.
    5. User registration is disabled: Go to Settings > General and confirm Anyone can register is checked. If registration is off, no notification fires because no registrations occur.

    Disabling Admin Notifications Without Breaking User Notifications

    A common but overlooked need: you want the new user to receive their password email, but you do not want the admin alert. On a high-volume membership site that registers hundreds of users a day, the default admin notification becomes noise rather than signal.

    The cleanest approach is a one-line filter. Add this to a snippet:

    add_filter( 'wp_new_user_notification_email_admin', '__return_false' );

    This returns false for the admin email only. The user still receives their password setup email. The WooCommerce documentation notes a similar pattern for order notification suppression, which gives you a sense of how widely this filter approach is used across the WordPress ecosystem.

    If you are using a visual workflow for notifications, simply do not include a Send Email action directed at the admin. The workflow can handle the user-facing email and leave the admin untouched.

    Also from wpRigel

    Pollify is a Gutenberg-native poll, survey, and quiz plugin. Polls are built directly inside the block editor as native blocks with no shortcodes to paste, which makes adding audience feedback to any post or page a two-minute task rather than a configuration exercise in a separate interface.

    Commandify is a command palette for the WordPress admin. Press Cmd or Ctrl and K to search anything, navigate anywhere, and run admin actions without clicking through menus. It is the only command palette with real WooCommerce order, product, and customer commands built in, which makes it genuinely useful on busy store sites rather than just a convenience shortcut.

    Next Steps

    If registration emails are missing, start with SMTP and work through the five-point checklist above. If the core email works but you need conditional routing or multiple recipients, the visual workflow approach in Step 4 takes about 15 minutes and requires no code. If your registration flow goes through a form plugin, check the relevant integration documentation before assuming the core trigger applies.

    The free plugin covers everything in this guide. Try Krom Automation free on WordPress.org and have the workflow running before you finish your next coffee.

    Frequently Asked Questions

    Why am I not getting email notifications when a new user registers?

    The most common cause is email delivery failure, not a WordPress configuration problem. Install an SMTP plugin and check the delivery log to confirm whether the email was sent.

    If it was sent but not received, the issue is spam filtering or SPF/DKIM alignment on your sending domain. If it was not sent at all, check whether a plugin is suppressing the wp_new_user_notification hook.

    How do I send registration notifications to a different email address?

    Use the wp_new_user_notification_email_admin filter to change the to field to any address you need. The filter accepts a comma-separated string, so you can include multiple addresses. If you prefer a no-code option, a workflow with a User Registered trigger and a Send Email action handles this in about 10 minutes.

    How do I notify different team members based on the user’s role?

    Add conditional branching to the workflow. Set a condition on the Yes path for the specific role, add a Send Email action with the relevant recipient, and repeat for each role.

    The No path handles any registration that does not match a specific condition. The conditions and branching documentation lists every available condition field.

    How do I turn off admin registration emails without affecting the user’s password email?

    Add the filter add_filter( 'wp_new_user_notification_email_admin', '__return_false' ); via a snippet plugin. This suppresses only the admin copy. The user still receives their password setup email through the same core function.

    Can I get a Slack or SMS alert instead of an email when a user registers?

    Yes. The User Registered trigger supports any action the workflow builder offers.

    Add a messaging action after the trigger, point it at a Slack channel or a Twilio number, and include merge tags for the user’s name and email. The messaging integrations documentation covers the full setup for Slack, Discord, Twilio, and Telegram.

    See full pricing details and compare all plans, annual plans start at $69 and lifetime plans start at $199.

    The wpRigel Team

    October 26, 2026
    Krom Automation
  • Krom Automation Pro Is Live: Visual WordPress Workflow Automation Without Monthly Fees

    Krom Automation Pro Is Live: Visual WordPress Workflow Automation Without Monthly Fees

    We built something we needed ourselves and could not find anywhere. Today it is yours.

    Krom Automation is officially live on WordPress.org. It is a visual workflow automation plugin for WordPress- the kind that connects any site event to any action on a drag-and-drop canvas, no code, no external dashboard, no per-task billing.

    To celebrate the launch, we are offering flat 60% off all plans, both yearly and lifetime, for this week only.

    Use code GETFLAT60 at checkout.

    Get Krom Automation Pro- 60% Off

    This offer runs for a few days. If you have been looking for a Zapier alternative that actually lives inside WordPress, keep reading.

    The problem every WordPress site owner eventually hits

    Your WordPress site is not passive. It generates events constantly.

    Users register. Orders complete. Payments fail. Courses finish. Forms get submitted. Posts get published. Comments land in the queue waiting for someone to approve them.

    Most sites respond to almost none of this automatically.

    • A new member signs up and gets a bare WordPress default email. Then nothing for days, sometimes weeks.
    • An order completes and the customer hears silence until the product ships.
    • A payment fails and the member quietly loses access without a single follow-up.
    • A course finishes and nobody sends the certificate or nudges the student toward the next one.

    This is not a technical problem. The events are happening. The data is right there in WordPress. What is missing is the wiring between the event and the response.

    For a while, most people solve this with Zapier or Make.com. Until the bill arrives. Or until a workflow breaks silently at 2am and nobody knows for three days. Or until the task count spikes one busy month and the overages add up.

    Krom Automation is the native solution to that problem. Everything runs on your own WordPress install. Your data never leaves your server.

    There is no per-task cap. And when something runs, you get a full step-by-step log of exactly what happened.

    What Krom Automation actually does

    krom automation pro is live

    At its core, Krom Automation works on a simple principle: pick something that happens on your site, then decide what should happen next.

    You build it on a drag-and-drop canvas inside WordPress. Pick a trigger — the thing that fires. Add actions — what happens next. Connect them. Set it live. That is the whole model.

    Triggers are the events. A user registering. A WooCommerce order completing. A LearnDash course finishing. A form being submitted. A payment failing. A product going out of stock.

    Actions are the responses. Send an email. Update a CRM contact. Post a Slack message. Log a row to Google Sheets. Create a coupon. Tag someone in Mailchimp. Enrol them in the next course. All in the same workflow, one after another, with delays and conditions in between.

    Merge tags inject live data into any field. {{first_name}} becomes the actual person. {{order.total}} becomes the real number. Every email, every message, every action is specific to that event, not a generic blast.

    Conditions let you branch. Order over $500? Alert the team and send a VIP welcome. Under $500? Just send the confirmation. One workflow, different paths.

    Delays let you time it right. Welcome email ten minutes after registration, not one second. Review request seven days after delivery, not at the moment of shipping.

    And before any of it touches real people, the workflow simulator runs the whole thing against real site data with zero actual emails sent, zero CRM records updated, zero side effects of any kind. You see exactly what would have happened at every step.

    Krom Automation Pro in numbers

    The free version alone is more capable than most people expect.

    FreePro
    Triggers1696+
    Actions2181+
    IntegrationsWooCommerce built in25 integrations
    Templates20121
    AI actionsIncludedIncluded
    Schedule trigger—Hourly, daily, weekly, custom
    Incoming webhooks—Yes, HMAC-secured
    Visual email builder—Yes

    Free version on WordPress.org

    Pro features and integrations

    AI is part of the workflow, not a separate tab

    AI in krom automation pro

    Three AI actions are built into Krom Automation, and they are available in the free version.

    AI Generate Text: Write a prompt, get text back. Use it to generate personalised email copy, post excerpts, social captions, or anything else you would normally write by hand for every occurrence.

    AI Content Moderation: Run any comment or form submission through an AI filter before it goes anywhere. Flag it, hold it, move it to spam — with thresholds you control.

    AI Auto-Tag: Analyse a post and apply the right tags and categories automatically. Works on publish or as part of a batch processing workflow.

    You connect your own OpenAI, Gemini, or Groq API key. No token markups, no per-call charges, no credits to buy. The AI costs what your provider charges, and not a cent more.

    And in Pro, there is one more AI capability worth knowing about. AI Workflow Generation lets you describe what you want to automate in plain English and it builds the workflow for you. Type “when a WooCommerce order completes, send a thank-you email and add the customer to my Mailchimp audience.” It maps the triggers, sets the actions, and opens the result paused for your review before anything runs.

    See all AI features

    25 integrations for Krom Automation Pro: Everything your stack already uses

    Krom automation 25 integrations

    Pro connects to 25 integrations across every major WordPress plugin category. Every one uses the same canvas, the same merge tags, the same execution logs.

    • eCommerce: WooCommerce, WooCommerce Subscriptions, Easy Digital Downloads
    • CRM: FluentCRM, ActiveCampaign
    • Email marketing: Mailchimp, ConvertKit, MailerLite, MailPoet
    • LMS: LearnDash, TutorLMS
    • Membership & community: MemberPress, BuddyBoss
    • Forms: Gravity Forms, WPForms, Fluent Forms, Contact Form 7, Elementor Forms, Ninja Forms
    • Messaging: Slack, Discord, Telegram, Twilio SMS
    • Data & productivity: Google Sheets, Google Calendar
    • Affiliate: AffiliateWP

    WordPress plugins are detected automatically. No setup needed beyond activating them. External platforms connect with an API key.

    Browse all integrations

    Krom Automation Pro: Who it is for

    WooCommerce store owners

    Your orders, subscriptions and customers generate events all day. Most go unanswered.

    Set up a review request that goes out seven days after delivery, not the moment the order ships. Build a payment failure recovery sequence that sends three timed emails before a subscription lapses. Create a coupon automatically when a customer hits their fifth order. Alert your team on Slack for high-value orders without checking the dashboard.

    WooCommerce automation guide

    Course creators and LMS operators

    Students who complete one course are your best candidates for the next. Most sites wait for them to come back on their own.

    Automate the full journey: enrolment welcome email, lesson reminders, quiz result branching, certificate delivery, and automatic enrolment in the next course. LearnDash and TutorLMS both connect natively.

    LearnDash integration

    Membership site owners

    New member joins, gets a default WordPress email, and then nothing. That gap is where communities lose people.

    Build a welcome sequence that starts the moment someone activates. Set up dunning emails when a payment fails. Send a win-back campaign when a subscription is cancelled. Tag members in your CRM by plan level. None of this should require your attention once it is built.

    MemberPress integration · BuddyBoss integration

    Agencies and developers

    Export any workflow as JSON and import it on any client site running Krom Automation. The same welcome sequence, the same order automation, the same CRM sync — deployed in minutes rather than built from scratch every time.

    Connect to external services via the incoming webhook receiver: a unique HMAC-secured URL per workflow, compatible with Stripe, GitHub, Shopify and anything else that sends webhooks. Or use the HTTP Request action to call any external API directly from a workflow step.

    REST API reference

    Krom Automation Pro Pricing

    Krom Automation Pro Yearly Pricing
    Krom Automation Pro Lifetime Pricing

    This is the section most tools hide in small print. We prefer to put it front and centre.

    Uncanny AutomatorWP FusionZapier ProfessionalKrom AutomationWith GETFLAT60
    Entry plan, 1 site$199/year$297/year$240/year$119/year$48/year
    Per-task billingNoNoYesNoNo
    Self-hostedYesYesNo, SaaSYesYes
    Lifetime planNoYesNoYes$119 once
    BuddyBoss integrationYesCRM sync onlyNoYes, 14 triggersYes
    Visual canvas builderLimitedNoNoYesYes
    Execution logsBasicBasicBasicStep-levelStep-level

    On Uncanny Automator: A solid plugin and the most common comparison. Their entry plan is $199/year for one site, integrations sometimes sold separately as add-ons. At full price Krom is 40% less. At launch price it is less than a quarter of what Uncanny charges at entry.

    On WP Fusion: Excellent at CRM sync, but that is specifically what it does. It is not a general automation engine and is often purchased alongside an automation plugin, adding to your total stack cost.

    On Zapier: The most recognisable name in automation, and not a bad tool. But it is external SaaS with per-task billing. The Professional plan gives you 750 tasks per month. A five-step workflow burns four tasks per run — 200 form submissions a month blows past the base tier on a single workflow. And your workflow data, credentials and execution history all live on Zapier’s servers, not yours.

    Krom Automation at $48 this week is less than two months of Zapier’s entry plan. With a lifetime option at $119 — or $48 with GETFLAT60 — you pay once and you are done.

    See all plans and pricing

    The launch discount on Krom Automation

    This week only, 60% off all plans, yearly and lifetime.

    Use code GETFLAT60 at checkout. No complicated tiers. No “up to” fine print. Flat 60% off whatever you choose.

    Grab 60% Off Krom Automation

    The honest version of how we got here

    We wanted to ship this six months ago.

    The original name was Automatify. That was taken. We rebuilt the brand around Flowmator, got it ready, wrote 51 documentation pages, built the site, locked the colours.

    Three weeks before launch the WordPress.org review team flagged it as too close to an existing plugin.

    So we started again. Third name: Krom Automation. Approved.

    Along the way we hit the payment problem. We operate from Bangladesh, where PayPal is not available and most payment processors are not ready to support a new software business.

    We delayed the launch of our first plugin by five months trying to find an alternative to Freemius before eventually shipping on it anyway. A customer told us plainly that Freemius was the reason he would not buy. He was not wrong.

    So we built our own licensing system in collaboration with Paddle. Krom Automation runs on it from day one. No Freemius. No third-party checkout. No external account required to purchase.

    We are later than planned. Every piece of it works better for the delay.

    Get started Today

    krom automation Pro is live

    Three ways in, depending on where you are:

    1. Start free. Install the free version from WordPress.org. 16 triggers, 21 actions, AI actions, WooCommerce, full execution logs. Build your first workflow today.

    Free Download on WordPress.org

    2. Get Pro at 60% off. Unlock all 25 integrations, 121 templates, AI workflow generation, the visual email builder, and the incoming webhook receiver. Code GETFLAT60 at checkout. This week only.

    Get Pro — 60% Off This Week

    3. Read the docs first. If you want to understand the full capability before committing, the documentation covers every trigger, action, integration and feature in detail.

    Krom Automation Documentation

    Frequently asked questions on Krom Automation Pro Launch

    Does Krom Automation work without WooCommerce?

    Yes. WooCommerce is optional and auto-detected when active. The core plugin works for any WordPress site regardless of whether you run an online store.

    Do I need an AI API key?

    Only for AI actions. The core plugin, all triggers, all standard actions, and all integrations work without one. You only need a key from OpenAI, Gemini or Groq if you want to use AI Generate Text, AI Content Moderation or AI Auto-Tag.

    Is there a free version?

    Yes, and it is genuinely capable. 16 triggers, 21 actions, full WooCommerce support, AI actions, merge tags, conditions, delays, execution logs and 20 workflow templates. Available on WordPress.org with no account required.

    How is this different from Uncanny Automator?

    Uncanny Automator is a list-based rule editor. Krom Automation is a visual drag-and-drop canvas. The pricing is different (Krom starts at $119 vs $199 for Uncanny’s entry tier). And Krom includes a lifetime plan, AI workflow generation, an incoming webhook receiver and step-level execution logs — none of which Uncanny offers at entry level.

    What happens after the launch discount ends?

    Full pricing applies and all plans remain available. The 60% off with code GETFLAT60 is a launch-week offer. Yearly and lifetime plans are both available permanently at regular price after this week.

    Can I import and export workflows?

    Yes. Any workflow can be exported as a JSON file and imported on any site running Krom Automation. This is how agencies deploy the same automation stack across multiple client sites.

    Krom Automation is made by wpRigel. We also make Pollify (Gutenberg-native polls and surveys) and Commandify (a command palette for the WordPress admin). All three run natively inside WordPress with no external accounts required.

    The wpRigel Team

    September 14, 2026
    Krom Automation
1 2
Next Page
wprigel logo

wpRigel builds innovative WordPress plugins for developers, marketers and agencies. Be with us, get more users for your business and increase conversion using our powerful tools.

  • x.com icon
  • linkedin icon

Products

  • Pollify
  • Commandify
  • Krom Automation (Now Live 🎉)

Company

  • Affiliate Program
  • About Us
  • Contact Us
  • Privacy Policy

Resources

  • Docs
  • Blog
  • Support Area
  • Refund policy
  • Coupons & Deals

Comparisons

  • Commandify vs CommandUI
  • Pollify vs CrowdSignal
  • Krom Automation vs others

Changelogs

  • Commandify Changelog
  • Pollify Changelog
  • Krom Automation Pro Changelog

wpRigel 2026. All Rights Reserved

  • Terms of use
  • Privacy Policy
  • Cookie Policy