How to notify the admin about something that happened during a cron job

I’ve done something similar flagging content ingestion issues. I would caution against sending emails from a cron unless it’s in a digest form from a specified interval of time as you’ll get email fatigue pretty quickly.

I created a queue of sorts in a separate post type that linked to the the flagged post or just raised a flag for an issue that had no post. From there, editors can resolve an issue (delete it) or mark it as expected (set to custom post_status of ‘expected’) so the issue does not keep recurring if rules are setup to catch other posts of like issue.

Though I’m not able to give you the codebase for the proprietary plugin, here are the steps I took:

1. Create a post type for content flags

2. Redirect new manual posts to edit.php and remove submenu item for adding posts

We only want cron to create these posts and not users.

add_action( 'init', 'redirect_new_flag_post' );
function redirect_new_flag_post (){
  global $pagenow;
  if( $pagenow === 'post-new.php' && isset( $_GET['post_type'] ) && $_GET['post_type'] === 'YOUR_POST_TYPE' ){
    wp_redirect( '/wp/wp-admin/edit.php?post_type=YOUR_POST_TYPE' );
    die();
  }
}
add_action( 'admin_menu', 'remove_flag_menu_items' );
function remove_menu_items (){
    remove_submenu_page( 'edit.php?post_type=YOUR_POST_TYPE', 'post-new.php?post_type=YOUR_POST_TYPE' );
}

3. Create custom columns for edit.php for your custom post type. Take a look at this post for more information.

  • Flagged Post Title
  • Flagged Post URL
  • Flagged by
  • Date
  • Actions (Mark as Resolved (Trash), Whitelist as Expected (Set to ‘expected’ post_status)) – I created buttons with associated AJAX calls

4. Add meta boxes to your custom post type

Flagged Post Information

  • Post Title
  • URL
  • Post Type
  • Date
  • Flagged by (which cron process)
  • Message – This can describe why the post was flagged
  • Raw Data (Entire object that was to be ingested)

Resolution Actions

  • I removed all WP post actions via CSS to only show my resolution actions
  • Mark as Resolved (Delete it)
  • Mark as Whitelisted (Set it to Private)

5. Create an admin notice on the flagged post

  • Check if you’re on the correct post type
  • Check if a flag exists that points to that post
  • If so, create an error admin notice that warns the editor that there is a flag and link back to the content flag post for resolution.
  • Use the admin_notices hook to output your message

6. Create Flag model class

  • Add new flag – This can be called from your cron code
  • Resolve flag (delete)
  • Set expected (set post_status to ‘expected’)
  • Clear expected

You can create a class similar to this:

class Flags{
    public function add( $post_id, $title, $desc, $meta_data = array(), $flagger="cron" ){
        // Deduplicate flag
        // Insert flag
    }

    public function resolve( $post_id ){
        // Delete post via ID
    }

    public function save( $post_id ){
        // Set post_status to 'expected'
    }

    public function clear_saved( $post_id ){
        self::resolve( $post_id );
    }
}

7. Flag content from your cron script

Within your script, you can define a control structure to identify posts that should be flagged (i.e. post wasn’t inserted properly, content is missing from the origin CMS, etc…). Those posts should get flagged using your Flag class:

Flags::add(
    $post_id,
    'Lorem Ipsum',
    'This is why this post is getting flagged',
    array( 'raw_data' => $content_object )
);

8. Create email digest

I would create separate cron script to query the latest content flags and send a digest to the administrator at intervals. It would be valuable to the administrator to receive a link to the issue, see the raw data, and be able to resolve the issues manually instead of trying to debug without any data.

9. Garbage Collection

This approach has worked will for us, but beware content flags can pile up quickly if you’re ingesting a lot of data. You’ll need to run a garbage collection script for old flags if you see that your admin is not resolving the issues. You might also need to identify patterns of too stringent of rules for adding content flags if they get ignored consistently.