3

I have a node of content type task which has a field reminder date. When the node is saved or updated, I want to schedule sending an email to list of users on reminder date.

I have used the Rules module for that, like so:

  • Rules events:
    • after node is saved
    • after node is updated
  • Rules conditions:
    • node is of type task
    • data comparison: site current date greater than reminder date
  • Rules actions:
    • add a variable
    • field list of users(it is entity reference field user is the entity)
    • new. variable members to email
    • added a loop
    • to variable members to mail
    • add action to loop : send mail

The problem encountered is as follows: if I set current date equal to reminder date, then the email is never sent. But when I set a reminder date greater than current date, the mail notification is not sent on the reminder date. I.e. after the current date becomes greater than reminder date, even if the cron is run, the mail is not sent.

I think I need to use Rules Scheduler for that, right? How can I go about it?

I also saw a Using fields for setting evaluation time, which mentions these steps:

  • Using flags to load user lists in Rules
  • Scheduling a rules component from a triggered rule
  • Some words about rescheduling the evaluation if the event date should change
  • Using conditions to make fields available in Rules configuration
  • Using a date field to set evaluation time
  • Adding an offset to the evaluation (-1 day)
  • Verifying the configuration by executing the action set manually

How can I implement this?

I also tried the Date Reminder module but it has a limitation that you can send email only if you manually enter the email address or it will send only to drupal user.

  • do you want to send an email on node creation(update) or send an email when reminder time greater then current time? – xurshid29 Jan 25 '14 at 8:22
  • I want to send email on when current time is greater than reminder time by 1 or 2 seconds. – harshal Jan 25 '14 at 8:52
  • the problem is when node is created and reminder time is set.if the reminder time is greater than current time then the email is not sent even when cron is run. – harshal Jan 25 '14 at 9:02
1

My approach is something like this (without Rules module):

  1. assuming that we've installed Elysia Cron module and configured.
  2. configured Crontab
  3. SwiftMailer library exists in our module directory (or you can register it by Libraries module)

Implementation of Elysia Cron api;

function MY_MODULE_cronapi($op, $job = NULL) {
  $items['my_custom_task'] = array(
    'description' => '',
    'rule' => '*/10 * * * *',
    'callback' => 'my_custom_task',
    'arguments' => array(),
  );

  return $items;
}

// example business logic, change this with Yours
function my_custom_task() {

  $node_query = db_select('node', 'n');
  $node_query->join('field_data_field_reminder', 'fdfr', 'n.nid = fdfr.entity_id');
  $node_query->join('field_data_field_sent', 'fdfs', 'n.nid = fdfs.entity_id');
  $node_query->fields('fdfr', array('field_reminder_value'));
  $node_query->fields('n', array('nid', 'title'));
  $node_query->condition('fdfs.field_sent_value', 0, '=')
    ->condition('fdfr.field_reminder_value', array(time()-60*5, time()+60*5),'BETWEEN');
  $node_result = $node_query->execute()->fetchAll();


  $user_emails = db_select('users', 'u')
    ->fields('u', array('init'))
    ->execute()
    ->fetchField();

  if(!empty($node_result)) {
    require_once drupal_get_path('module', 'MY_MODULE') . '/lib/swiftmailer/swift_required.php';

    $transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, 'ssl')
      ->setUsername('GMAIL_USER')
      ->setPassword('GMAIL_USER_PASS');

    $mailer = Swift_Mailer::newInstance($transport);

    foreach($node_result as $key => $value) {
      $message = Swift_Message::newInstance('MY MESSAGE SUBJECT')
      ->setFrom(array('no-reply@'.$_SERVER['SERVER_NAME'] => 'MYWEBSITE.COM'))
      ->setTo($user_emails)
      ->setBody($node_result[$key]->title . ' is reminding!!', 'text/html');

      $mailer->send($message);

      $sent_node = node_load($node_result[$key]->nid);
      $sent_node_wrapper = entity_metadata_wrapper('node', $sent_node);
      $sent_node_wrapper->field_sent->set(1);
      $sent_node_wrapper->save();
    }
  }
}

// Improve this callback

By this way you can run Cron job on every 10 mins.. This doesn't provide the full functionality which you need (send by 1 or 2 seconds, but you can set cron job even 5 min)..

0

Part 1 - Make sure to include "Entity has field"

First eliminate the possibility that the missing piece to make your rule work is because you didn't include a Rules Condition like "Entity has field" (related to your Reminder date field), as the first Rules Condition.

If you didn't do that yet, then to Rules it is like the value of your Reminder date is simply blank. If needed, enable Rules debugging to double check if the value of that Reminder data has indeed the value that you expect. Refer to my answer to "How can I display the value of a variable inside a condition?" for more details about Rules debugging.

Part 2 - Rework your rule to use the Rules Scheduler

This seems to be a perfect case to actually use the Rules Scheduler (sub-module of Rules). Have a look at my answer to "Rule to store user's last post date and scheduled rule based 30 day reminder", which contains an example of how to use the Rules Scheduler for a variation of your question. The variation is that it is to only eMail 1 user instead of a list of users as in your case, though it uses a field that is similar to your Reminder date field.

The approach using the Rules Scheduler differs from what you tried to do (but couldn't get to work):

  • it does NOT use a Rules Condition like "check if this the right moment to send such eMail (now)".
  • instead it performs appropriate Rules Action to schedule such eMails for somewhere in the future. Moreover, it takes into account that the actual date for that eMail may even change in between (ie if the Reminder date field gets updated, then don't send that previously requested eMail anymore).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.