I second SamuelElh comment and YES cron is the way to go. BUT, which cron? The WordPress implementation of cron is a tricky implementation. How? Actually it is a cron fired by the visits your site gets, both (back-end and front-end), so, if your site is not getting a visitor every 10 minutes as suggested by Samuel, then your WordPress will be missing cron schedule and may not send the e-mails on time.
(Reference: https://codex.wordpress.org/Function_Reference/wp_schedule_event)
With that said, and if your site is getting enough hits to keep the cron going on time then it is as easy as adding:
To your Plugin page, this is hourly but change as you like:
register_activation_hook(__FILE__, 'cron_activation_function'); //to add cron to the cron table when plugin gets activated.
add_action('the_name_tag_of_your_cron_in_cron_table', 'the_cron_function_to_run');
register_deactivation_hook(__FILE__, 'cron_deactivation_function'); //to remove cron from the cron table when plugin gets deactivated.
function cron_activation_function()
{
if (!wp_next_scheduled('the_name_tag_of_your_cron_in_cron_table')) {
wp_schedule_event(time(), 'hourly', 'the_name_tag_of_your_cron_in_cron_table');
}
}
function cron_deactivation_function()
{
wp_clear_scheduled_hook('the_name_tag_of_your_cron_in_cron_table');
}
function the_cron_function_to_run()
{
//do what ever you want then send the emails
}
I hope this answers your question. Happy coding 🙂