1

I'm trying to implement a rule (in D7) that will automatically (no check box or opting out):

  1. send an email to the author of node if new comments
  2. send email to all users who have commented on that node
  3. not send email to author of own comment

I did find instructions for one of the above, but not for all of them in the same rules. And this is where I failed.

Any help?

4
  • use conditional rules module, check each 1,2,3 conditions, make loops where needed, it will a long rule, but it will work
    – pinueve
    Commented Nov 18, 2017 at 0:19
  • 1
    You don't need to use the conditional rules module for this. Loop the comment authors and send each one and the current author to the component. Then have a condition that they're different. Commented Nov 18, 2017 at 5:46
  • There is two way to do it either write two action on comment action or you can write your custom rule as per your requirement.
    – Prem Patel
    Commented Nov 18, 2017 at 6:05
  • Sorry @NiallMurphy ... I disagree with you ... though I couldn't explain why in only 600 chars (= max size of a comment "here") ... So I decided to just post an actual answer ... Of course, by using Rules Components (also), one can avoid Conditional Rules (but that seems to not fit with "in the same rules", as in the question). Commented Nov 18, 2017 at 13:40

1 Answer 1

1

Have a look at this rule (in Rules export format), which does what you're asking for:

{ "rules_notify_users_about_new_comment" : {
    "LABEL" : "Notify users about new comment",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "rules_conditional", "comment" ],
    "ON" : { "comment_insert" : [] },
    "DO" : [
      { "variable_add" : {
          "USING" : { "type" : "list\u003Cuser\u003E" },
          "PROVIDE" : { "variable_added" : { "users_to_notify" : "Users to notify" } }
        }
      },
      { "LOOP" : {
          "USING" : { "list" : [ "comment:node:comments" ] },
          "ITEM" : { "current_comment_item" : "Current comment item" },
          "DO" : [
            { "CONDITIONAL" : [
                {
                  "IF" : { "NOT data_is" : {
                      "data" : [ "current-comment-item:author" ],
                      "value" : [ "comment:author" ]
                    }
                  },
                  "DO" : [
                    { "list_add" : {
                        "list" : [ "users-to-notify" ],
                        "item" : [ "current-comment-item:author" ],
                        "unique" : "1"
                      }
                    }
                  ]
                }
              ]
            }
          ]
        }
      },
      { "CONDITIONAL" : [
          {
            "IF" : { "NOT data_is" : { "data" : [ "comment:author" ], "value" : [ "comment:node:author" ] } },
            "DO" : [
              { "list_add" : {
                  "list" : [ "users-to-notify" ],
                  "item" : [ "comment:node:author" ],
                  "unique" : "1"
                }
              }
            ]
          }
        ]
      },
      { "LOOP" : {
          "USING" : { "list" : [ "users-to-notify" ] },
          "ITEM" : { "current_user_to_notify" : "Current user to notify" },
          "DO" : [
            { "mail" : {
                "to" : [ "current-user-to-notify:mail" ],
                "subject" : "New comment to node with id [comment:node:nid]",
                "message" : "There is a new comment added to the node with id [comment:node:nid]",
                "language" : [ "" ]
              }
            }
          ]
        }
      }
    ]
  }
}

I translate the "... in the same rules ..."-part of your question like "I want it to be a single (monolitic) rule". For that you'll need an additional module, i.e. the Conditional Rules module, while the above rule does use a few of the more advanced techniques available in the Rules module.

If you're familiar with reading/digesting Rules in Rules export format, I'd hope the rule is self explaining. If not here is a summary of the above rule:

  • Rules Event: obvious ... After saving a new comment.
  • Rules Conditions: feel free to add whatever fits (eg limit to selected content types only).
  • Rules Actions:

    1. Add a variable "users_to_notify" (= a list of users).
    2. Loop over all existing comments, and for each comment author, check that it is not the user who just created the comment (which you can check if you have the Conditional Rules module enabled). If that's the case, then add that user to the list of users (= users_to_notify).
    3. If the comment author differs from the node author (which you can check if you have the Conditional Rules module enabled), then also add the node author to the list of users (= users_to_notify).
    4. Loop over the list of users (= users_to_notify) ... again, which we just created and populated). And for each user in that list, do your thing, in this case "send an eMail". The "To" value is crucial here, the body, the from, the title, etc is up to your own imagination.

If you don't want to use the Conditional Rules module, you could also rework the Rules Actions that require this module to performing Rules Components (in which you add the appropriate Rules Conditions), so that you don't need this extra module (for more details on that, refer to the answer to "What's the alternative to using the Conditional Rules module?").

If you want, just import the above rule in your own site (using the Rules UI, which should be enabled to do so), but only after you enabled the Conditional Rules module.

That's really all it takes ... a Rules variable, Rules lists and loops, and Conditional Rules.

Note that the above rule does actually more as compared to what is asked here:

  • As per the "unique" in Rules Action nr 2, it will not create duplicates in that list of users, to avoid the same user would receive duplicate eMails (i.e. if a user commented multiple times).
  • As per the "unique" in Rules Action nr 3, it will not create duplicates in that list of users, to avoid the node author would get duplicate eMails (i.e. if the node author also commented already).
  • This rule will NOT send an eMail if the comment was posted by ... the node author (which seems to me like a contradiction in item 1. and 3. of the question ...). If you disagree on that (i.e. that it should send an eMail anyway: just delete Rules Action nr 3.

Unit testing the rule

If you want to (unit) test the above rule, you may want to add another Rules Action within Rules Action nr 4. I.e. add some sort of "Show a message on the site" (located within Rules group "System"), to produce a message for each user included the list of users (= users_to_notify).

That way, if for some reason your site has not been correctly configured yet to send eMails, those messages will help you confirm that the rule itself is not the cause of that.

Video tutorials

For anybody not familiar (enough/yet) with Rules, checkout the 32 (!!!) great, and free, video tutorials Learn the Rules framework, organized in 7 chapters. Especially these tutorials, which are related to subject of this question:

3
  • I have no doubt that your proposition is excellent. But don't ask me why, I could not implement it (well... I'm not that good with Rules). So I did more research and found this : 1) drupalize.me/videos/notify-author-comments?p=1157 and this: 2) drupalize.me/videos/notify-comment-reply?p=1157.
    – Anne
    Commented Nov 19, 2017 at 14:00
  • @Anne why could you not implement it? Please explain what the problem is? Did you not succeed in importing this rule? Or is there some issue with the eMails being produced? Also, those links look extremely familiar (check my updated answer). Commented Nov 19, 2017 at 19:40
  • Well... your instructions seemed rather overwhelming.
    – Anne
    Commented Dec 14, 2017 at 14:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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