web-dev-qa-db-ja.com

ノードを保存するときにトリガーされるルールを作成して、指定した日付にメールを送信するようにスケジュールするにはどうすればよいですか?

私はフィールドリマインダー日付を持つコンテンツタイプtaskのノードを持っています。ノードが保存または更新されたときに、リマインダー日にユーザーのリストにメールを送信するようにスケジュールを設定します。

そのために Rules モジュールを使用しました:

  • ルールイベント:
    • ノードが保存された後
    • ノードが更新された後
  • ルール条件:
    • ノードのタイプはタスクです
    • データ比較:サイトの現在の日付がリマインダーの日付よりも大きい
  • ルールアクション:
    • 変数を追加する
    • ユーザーのフィールドリスト(エンティティ参照フィールドユーザーはエンティティです)
    • 新着。メールする可変メンバー
    • ループを追加しました
    • 可変メンバーからメールへ
    • ループするアクションを追加:メールを送信

発生する問題は次のとおりです。現在の日付をリマインダーの日付と同じに設定すると、電子メールが送信されません。しかし、リマインダーの日付を現在の日付よりも大きく設定すると、リマインダーの日付にメール通知が送信されません。つまり現在の日付がリマインダーの日付よりも大きくなると、cronが実行されていてもメールは送信されません。

Rules Schedulerそのためですよね?どうすればいいですか?

私は 評価時間を設定するためのフィールドの使用 も見ました、これはこれらのステップについて述べています:

  • フラグを使用してルールにユーザーリストを読み込む
  • トリガーされたルールからのルールコンポーネントのスケジュール
  • イベントの日付を変更する必要がある場合の評価の再スケジュールに関するいくつかの単語
  • 条件を使用してルール構成でフィールドを使用可能にする
  • 日付フィールドを使用して評価時間を設定する
  • 評価にオフセットを追加する(-1日)
  • アクションセットを手動で実行して構成を確認する

どうすれば実装できますか?

私も Date Reminder モジュールを試しましたが、メールアドレスを手動で入力した場合にのみメールを送信できる、またはdrupalユーザーにのみ送信されるという制限があります。

3
harshal

私のアプローチは次のようなものです(ルールモジュールなし):

  1. elysia Cronモジュールをインストールして構成したと仮定します。
  2. 構成済みのCrontab
  3. SwiftMailerライブラリはモジュールディレクトリに存在します(またはライブラリモジュールで登録できます)

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();
    }
  }
}

//このコールバックを改善します

このようにして、10分ごとにCronジョブを実行できます。これは、必要な完全な機能を提供しません(1秒または2秒で送信されますが、5分でもcronジョブを設定できます)。

1
xurshid29

パート1-必ず「エンティティにフィールドがあります」を含める

最初に、「Entity has field」のようなルール条件を含めなかったために、ルールを機能させるために欠落している可能性を排除します((Reminder datefield)、最初のルール条件として。

あなたがまだそれをしていない場合、それはルールに対して、あなたのリマインダー日付の値が単に空白のようなものです。必要に応じて、ルールのデバッグを有効にして、そのリマインダーデータの値が本当に期待した値であるかどうかをダブルチェックします。ルールのデバッグの詳細については、「 条件内の変数の値を表示するにはどうすればよいですか? 」への私の回答を参照してください。

パート2-ルールを作り直して、Rules Schedulerを使用する

これは、実際にルールスケジューラ( Rules のサブモジュール)を使用するのに最適なケースのようです。 「 ユーザーの最終投稿日とスケジュールされたルールに基づく30日間のリマインダーを保存するルール に対する私の回答をご覧ください。これには、Rules Schedulerを使用して質問のバリエーションを作成する方法の例が含まれています。バリエーションは、リマインダーの日付フィールドと同様のフィールドを使用しますが、ユーザーのリストではなく、1人のユーザーのみにメールを送信することです。

Rules Schedulerを使用するアプローチは、実行しようとしたものとは異なります(ただし、機能しませんでした)。

  • 「今すぐこのようなメールを送信する適切なタイミングかどうかを確認する」などのルール条件は使用しません。
  • 代わりに、適切なルールアクションを実行して、そのような電子メールを将来のどこかにスケジュールします。さらに、その電子メールの実際の日付がその間で変わる可能性があることも考慮に入れます(つまり、リマインダーの日付フィールドが更新された場合、以前に要求された電子メールをもう送信しないでください)。
0
Pierre.Vriens