Writing Personalized Scheduled Emails with WordPress

There are many options for sending out email newsletters. Recently, I was reviewing various options for sending out my CaptainCore updates. At first I was tempted to just grab entries from my Gravity Forms and send out a regular email with everyone BCC’d. However I foresee how that will quickly become problematic when manually maintaining a list of subscribers.

That said, I really just want to write a simple email to a small group of folks combined with the ability to schedule them. So after some trial and error I came up with a hacked together solution using WordPress and a few free/paid plugins.

Idea #1: Why not just write my emails as scheduled private blog posts?

Well it turns out you can’t schedule a private post. As soon as a post is marked private, it’s published. Next…

Idea #2: How about a private custom post type?

Totally! A custom post type can be scheduled and posted publicly without displaying on the frontend of the website. That works good enough for my use case.

A recipe for an out-of-the-box WordPress email machine.

To begin we’ll need a few ingredients. 

  • Custom Post Type – Can be called anything like. For my example I called it Email Supporters.
  • Plugins: Code Snippets, Gutenberg, Gravity Forms & Gravity Forms User Registration Add-On, Mailgun, Better Notifications for WordPress.

 Directions – No recipe comes without directions.

  • Step 1 – Start by activating Code Snippets and inserting the Custom Post Type. Feel free to use my custom post type, shown below, or generate your own. A few gotchas when generating your own post type. Make sure you enable REST API and revisions otherwise you’ll have issues with Gutenberg.
// Register Custom Post Type
function captaincore_emails_post_type() {

	$labels = array(
		'name'                  => _x( 'Emails', 'Post Type General Name', 'captaincore' ),
		'singular_name'         => _x( 'Email', 'Post Type Singular Name', 'captaincore' ),
		'menu_name'             => __( 'Email Supporters', 'captaincore' ),
		'name_admin_bar'        => __( 'Email', 'captaincore' ),
		'archives'              => __( 'Item Archives', 'captaincore' ),
		'attributes'            => __( 'Email Attributes', 'captaincore' ),
		'parent_item_colon'     => __( 'Parent Email:', 'captaincore' ),
		'all_items'             => __( 'All Emails', 'captaincore' ),
		'add_new_item'          => __( 'Add New Email', 'captaincore' ),
		'add_new'               => __( 'Add New', 'captaincore' ),
		'new_item'              => __( 'New Email', 'captaincore' ),
		'edit_item'             => __( 'Edit Email', 'captaincore' ),
		'update_item'           => __( 'Update Email', 'captaincore' ),
		'view_item'             => __( 'View Email', 'captaincore' ),
		'view_items'            => __( 'View Emails', 'captaincore' ),
		'search_items'          => __( 'Search Email', 'captaincore' ),
		'not_found'             => __( 'Not found', 'captaincore' ),
		'not_found_in_trash'    => __( 'Not found in Trash', 'captaincore' ),
		'featured_image'        => __( 'Featured Image', 'captaincore' ),
		'set_featured_image'    => __( 'Set featured image', 'captaincore' ),
		'remove_featured_image' => __( 'Remove featured image', 'captaincore' ),
		'use_featured_image'    => __( 'Use as featured image', 'captaincore' ),
		'insert_into_item'      => __( 'Insert into item', 'captaincore' ),
		'uploaded_to_this_item' => __( 'Uploaded to this item', 'captaincore' ),
		'items_list'            => __( 'Items list', 'captaincore' ),
		'items_list_navigation' => __( 'Items list navigation', 'captaincore' ),
		'filter_items_list'     => __( 'Filter items list', 'captaincore' ),
	$args = array(
		'label'                 => __( 'Email', 'captaincore' ),
		'description'           => __( 'Email Description', 'captaincore' ),
		'labels'                => $labels,
		'supports'              => array( 'title', 'editor', 'revisions' ),
		'hierarchical'          => false,
		'public'                => true,
		'show_ui'               => true,
		'show_in_menu'          => true,
		'menu_position'         => 5,
		'menu_icon'             => 'dashicons-email',
		'show_in_admin_bar'     => true,
		'show_in_nav_menus'     => false,
		'can_export'            => true,
		'has_archive'           => true,
		'exclude_from_search'   => true,
		'publicly_queryable'    => false,
		'capability_type'       => 'page',
		'show_in_rest'          => true,
	register_post_type( 'captaincore_emails', $args );

add_action( 'init', 'captaincore_emails_post_type', 0 );
Gravity Forms with User Registration
Gravity Forms with User Registration
  • Step 4 – Configure Better Notifications for WordPress to send a formatted email when new custom post types are published.

With that completed you now have a WordPress email machine. Simply write your emails as posts and schedule them for delivery. The emails will be sent to your list of subscribers with all of your special formatting and personalization. If you want to add further customization, I’d recommend taking a look at some of the paid addons for Better Notifications: https://betternotificationsforwp.com/store/.