Sending Reminder Emails

So what I’m doing here is sending an email the day before an event someone registered for via a Gravity Forms process I set up.

This is kind of an interesting pattern because it moves back and forth from the Gravity Forms API and uses a mix of Events Calendar functions, in addition to basic WP and PHP functions. This is one piece of a much larger registration pattern that I’ll have to document at some point.1

Gravity Forms has a reservations plugin but it felt really complex to me compared to what we2 wanted and it didn’t quite do what we wanted in some other ways. I want simplicity. I want to avoid a lot of options. Reminder emails are just standard reminder emails. They don’t need to be beautiful bespoke creations.

Where are we in time?

This function will run once a day via wp_cron and will be looking to alert people about what happens tomorrow. The first thing we’ve got to do to know what events are happening tomorrow is to figure out where we are in time today. We’ll do that using the PHP date function and we’ll add 86400 seconds to get tomorrow.


 $tomorrow = date("Y-m-d", time() + 86400);

Get the Events

We want to find all the events that occur on that day between 12:01AM and 11:59PM.  The events are created through the Events Calendar and that give us access to a custom function called tribe_get_events which takes start_date and end_date as variables. So this chunk gets us all of the events and start and end tomorrow.3


        //get current date and add 86400 seconds
	$tomorrow = date("Y-m-d", time() + 86400);
	$start = $tomorrow . ' 00:01';
	$end = $tomorrow . ' 23:59';

	//get Modern Tribe events that occur on current date +24 hrs from the events calendar
	$coming_events = tribe_get_events( [
					   'start_date'   => $start,
					   'end_date'   => $end,
					] );

I want to scoop up all the IDs of the events that meet these search parameters and put them in an array. Because I log that when people register via Gravity Forms, I’ll be able to filter the Gravity Forms entries for that form by the Event ID.

$event_ids = [];
	if($coming_events){		
		foreach ($coming_events as $key => $event) {		
				array_push($event_ids, $event->ID);
		}
	}

Get the registrants

Now we’re in the Gravity Forms API and using their GFAPI:get_entries function.

//if we have event ids, let's get our dear registrants
	if($event_ids){
		foreach ($event_ids as $key => $event_id) {
			//get the reservations from Gravity forms where the event ID matches
			$search_criteria = array(
					    'status'        => 'active',
					    'field_filters' => array(
					        'mode' => 'any',
					        array(
					            'key'   => '6',
					            'value' => $event_id
					        )
					    )
					);
			$event_name = get_the_title($event_id);//get title from the event
			$event_date = tribe_get_start_date($event_id, TRUE, null, TRUE);//get start date/time from the event
			$location = dlinq_event_email_location($event_id);//get the location if in person and/or online
			
			$reservations = GFAPI::get_entries($gf_workshop_registration_id, $search_criteria);
			foreach ($reservations as $key => $reservation) {
				$to_email = $reservation[3];
				$delete_key = $reservation[11];
				$delete_url = get_permalink($event_id).'?delete='.$delete_key;
				$delete_block = "<p>Use this link to cancel your reservation <a href='{$delete_url}'>{$delete_url}</a></p>";
								
				dlinq_send_reminder_email($to_email, $event_name, $event_date, $location, $delete_block);
			}
		}	

These two little functions just break apart a couple of the pieces regarding email sending so that thing doesn’t get totally out of control.

function dlinq_send_reminder_email($to_email, $event_name, $event_date, $location, $delete_block){
	$to = $to_email;
	$subject = "Reminder: You registered for {$event_name} on {$event_date}";
	$headers = array('Content-Type: text/html; charset=UTF-8','From: DLINQ <dlinq@middlebury.edu>');	
	$message = 'We look forward to seeing you! ' . $location . $delete_block;
	wp_mail( $to, $subject, $message, $headers);
}

function dlinq_event_email_location($event_id){
	$location = '';
	if(get_field('zoom_link',$event_id)){
		$zoom_link = get_field('zoom_link',$event_id);
		$location = "<br><br><p>Online at:</p><br><a href='{$zoom_link}'>{$zoom_link}</a>";
	} if (tribe_get_full_address($event_id)) {		
		$location .= "<br><br><p>In person at:</p><br>" . tribe_get_full_address($event_id);
	}
	return $location;
}

Testing Tips

To test this as I went through various iterations and a million changes, I added a little shortcode so I could var_dump everything to a page. I’d turn off the final mail function and just dump whatever variables I needed to see. I could also write it to a log but this usually feels a bit easier. I’ll just throw this shortcode on a page and refresh that page to run the function and see what’s what.

add_shortcode( 'test', 'dlinq_reminder_email' );

Two other things were important in troubleshooting something like this locally. One is that Local WP has a built in mail tool that lets you see all the emails zooming around regardless of whether they’re real or not. That’s pretty key. They also just moved from MailHog to MailPen. MailHog had an issue with email subjects not showing if they were UTF-8 encoded and over a certain number of characters. That led to me wasting a chunk of time thinking I needed to encode the subject differently. I eventually found out it was a bug on their end thanks to GitHub comments. As I went to figure out how to switch email clients in Local, I found the newest version did it already. That was a nice surprise.

The next piece was working through cron stuff in WordPress.4 The WP Crontrol plugin was really key for this. It’s a John Blackbourn creation. He’s done so many good things over the years that I actually remember his name when I see it on plugins.

Cron timer

Finally, we’ll set the wp_cron to run this every day at 8AM. I think we get enough traffic that it’ll be fine and it really doesn’t matter as long as runs at some point during the day. If it gets to be a problem, there’s a much more serious way to do this that I found.

//set the cron to run reminder emails function
if ( ! wp_next_scheduled( 'dlinq_reminder_email' ) ) {
    wp_schedule_event( strtotime('08:00:00'), 'daily', 'dlinq_reminder_email' );
}

add_action( 'dlinq_reminder_email', 'dlinq_reminder_email' );



1 Or should document at some point . . . if God’s willing and the blogging creek doesn’t rise.

2 We might be a stretch here. At least, compared to what I wanted.

3 We don’t run any

4 It also led to a small commenting side quest on the CogDogBlog. I tend to check out Alan’s site when I’m contemplating something like this just to see if he’s already done something similar. 99% of the time he has. The other 1% tends to tell me it’s a bad idea.

4 thoughts on “Sending Reminder Emails

  1. Your 99% claim is a gross exaggeration but nice to say. More than that, you might be the only person out there who engages in blog comment conversations.

    1. Well . . . maybe 98%.

      And we’ve got to do what we want done right? That’s what I’ve always liked about you. Do the thing you espouse. Like open licenses? Put it out there. Like cool things? Make them. Promote them. Still want non-corporate social media conversations? Have them.

      Time and various kinds of bandwidth intervene but get in where you fit in when you can.

Leave a Reply