Rules for admin notifications, Part 2: New comments and content

New spam content posted

Rules is an especially useful Drupal module for all kinds of tasks. One use you might want to put it to is providing admin notifications of certain events on your site, e.g. user registrations (covered in the previous post) and the creation of new comments and content by “untrusted” users (assuming your use case allows them to create any content at all). For some use cases, you may wish to put strict limits on the creation of user accounts and content, but for the purposes of this article we are assuming you are administering a Drupal site where you want to encourage growth and community involvement, so you might allow anonymous users to comment on posts (albeit likely with the rel="nofollow"* attribute added to their links). And you might also allow users to create and confirm their own accounts and then create some types of content (e.g. forum posts, bug reports, etc). The downside is that you’ll need to be vigilant about squashing all the spam this policy invites (or the flow of new spam will quickly increase and be damaging to your SEO efforts), but on a site with only moderate traffic you should be able to manage this without a lot of trouble. This post covers using Rules to provide notifications of new comments and content. If you keep a close eye on user registrations and immediately block the user accounts which follow a pattern like other spam accounts you’ve removed (i.e. accounts likely created with the help of a “spambot”), you can eliminate almost all of the spam that requires use of an authenticated user account.

Adding rel equals nofollow to Drupal Links

*Adding rel="nofollow" to links posted in “Filtered HTML”, presumably the only text format you allow for “untrusted” users, is simple, but well worth doing if you allow “anonymous” or newly-registered “authenticated” users to make any kinds of posts on your site. In Drupal 6, go to admin/settings/filters/1/configure and select the “Spam link deterrent” checkbox. In Drupal 7, go to admin/config/content/formats/filtered_html and find the vertical tab near the bottom labeled “Limit allowed HTML tags”, where the same feature is enabled with a checkbox labeled “Add rel="nofollow" to all links”.

Getting back on topic, the three events we want to create Rules for are:

  1. New user registered (done, see previous article)
  2. New comment posted by “untrusted” user (described below)
  3. New content posted by “untrusted” user (also described below)
In each case, we simply want to send an HTML email* to notify at least one member of staff (anyone with the admin role and, in the case of comments on blog posts, we might want to also email the article’s author.) As with the past installment in this two-part series, this article does not cover configuring your server for sending mail nor setting up HTML mail, but we use Mime Mail for the “send HTML mail” versions of the exported code you’ll find attached. (See attachments to this article for code you can use to import these Rules into your own system—you’ll possibly need to tweak them a bit, but they could save you some time.) Where screenshots are included, we’ll display the Rules administration interface in both Drupal 6 and Drupal 7, side-by-side, since there are some differences that might otherwise lead to confusion. So this article should be helpful for administrators of both Drupal 6 and Drupal 7 sites.

In every case, creating a new rule starts by going to the “add rule” page:
D6: admin/rules/trigger/add
D7: admin/config/workflow/rules/reaction/add

Notify Admin (and/or content authors) when new comments are posted

This rule sends an (HTML or plain text) email which includes the comment title and body, along with a link to quickly edit it. Here at Cocomore, rather than delete comment spam, we’ve been unpublishing the comments so we can still observe patterns. So we don’t get an email for each of our own responses to comments, we configure the rule to only notify us when “untrusted” users (i.e. any users who don’t have a “staff” or admin role) post comments.

Adding a new rule to react to new comments

The first steps, picking a name and adding tags for it, then clicking “add action…”, are virtually identical in both Drupal 6 and Drupal 7 and for each rule. So if you wish to see illustrations of these steps, please look at part 1 of this article. The event we want to react to is called “After saving a new comment” in both the Drupal 6 and Drupal 7 versions of Rules. This is also simple enough that I will leave out any illustration here.

Click “Add condition”

Choose “user has role(s)” in the selector for “condition”

This is almost the same in Drupal 6 and Drupal 7. First select the “user has roles” condition. In the next part of adding the condition, we can select which roles the condition applies to. First we make sure that we select the right user for the “role condition”. In this case, the right user to select as the “argument” (Drupal 6) or “Data selector” (Drupal 7) is the author of the created comment, i.e. in Drupal 6 select “created comment author” and in Drupal 7, select “comment:author”.

Now we only want to send email when an anonymous user or basic authenticated user posts a comment. For the purposes of illustration, I have created a testing environment with two staff roles (one is “administrator” and the other is “editor”). Since both “staff” roles are also “authenticated” (whenever they are logged in, they have the “authenticated user” role, too), we want to use negation in our condition. The roles of the user who posted the comment should NOT include any of the privileged staff roles (or any other “trusted” role you would like to ignore here). So we select the two staff roles, the “Negate” checkbox, and “any” selected role. Then we need to remember to click “Save” for our new condition to be added.

The user who posted the comment should NOT have ANY staff role.

Add an action for “Send mail” or “Send HTML mail”

The “Add action” click pre-step is almost identical in Drupal 6 and Drupal 7, as is the selection of which action to perform (sending a mail); if you wish to see the illustration, please see the relevant screenshots in part 1 of this article.

For the purposes of this article, we will assume that we only want to send the administrator an email when people post comments, so it’s most appropriate to select the “Send (HTML) mail to all users of a role” option, then select “administrator” for the role to receive the email. That way, the administrator can choose to forward emails to the content author when she feels that the author should post a response to the comment. Alternatively, you could include your site’s content author(s) in the comment moderation process and allow them to also receive all the messages about comments by adding their email addresses to a comma-separated list of (in Drupal 6, “arbitrary”) email addresses. Or perhaps you have an “author” role and can select that. Or you could use the “token” to specifically send an email to the author of the commented content. If your site has multiple administrators, you might want to test your rule with an “arbitrary” email action, then copy the configuration for the “subject” and message “body” to a new action so that only you get the messages during the “testing phase”.

Send (HTML) email to all users of a role

Complete the email subject and body

Tokens available for use differ significantly between Drupal 6 and Drupal 7, but most are available in both or at least there is some way to achieve similar results for most output you might want to have. I’ve created some simple messages which you can use as a starting point (if you import the rules export code I’ve attached.) You might need to tweak the array code to fit your site’s configuration (e.g. role IDs, etc)

drupal6-new_comment_html_mail-subject_and_body.png Drupal 7  - Send HTML mail with Rules for new comments

Download exported code for this rule

Rules allows you to export and import rules from saved code, so I have attached an export of this rule. Even if you don’t want exactly the same action, this could be useful as a starting point for a new rule on your site. There are four versions of the import code attached, two each for Drupal 6 and Drupal 7 (for each version of Drupal, there is one version of the rule which uses HTML mail for the admin notification email, and one which just sends a plain mail.)

For Drupal 6 users, you can experiment with my exported Rules code for HTML email or plain text email. Drupal 7 users can download the HTML and/or plain text versions, as well.

Notify Admin when new content is created

Drupal 7 users can try cloning the “new comment” rule

This rule is actually similar enough to the comment-based rule that it’s a good candidate for demonstrating the power of the “clone” operation in Rules for Drupal 7 (unfortunately, Rules in Drupal 6 won’t let us change the event from comment-related to content-related, which is a bit of a drag since much of the rest of the Rule could be a straight copy, but you can create a new Drupal 6 rule that is triggered by the creation of new content, create a similar “condition”, then copy/paste in the email code and edit, as needed). But to experiment with cloning, those of you in Drupal 7 can start by going back to the main Rules overview page (admin/config/workflow/rules in Drupal 7). The clone link is virtually the same in both Drupal 6 and Drupal 7:

In Drupal 7, you can clone the “new comment” rule as a starting point.

Edit the Title, tags, event and condition for the cloned rule

Let’s first think about the differences, then clone the content and edit accordingly. The first significant difference is the title and “tags”, which should obviously say “content” rather than “comment”. Edit the cloned rule, and click on “Save changes”. The next difference is only slightly less trivial. We need to delete the “event” for “After saving a new comment” and add a new event in its place: “After saving new content”. You should then see that there is a warning next to the summary of the condition: “comment:author” is a token which no longer makes any sense.

Drupal 7: Edit the Rules condition to refer to the content author

Not to worry, we can fix that. Click on the “edit” link next to the condition and change the “Data selector” field from “comment:author” to “node:author”. We still only want to trigger the rule for users who do not have one of our trusted staff roles, so the rest of the condition can stay the same. Click on “Save” to go back to the main edit page for the rule, where we just need to click the “edit” link next to the “Send HTML mail…” action and change our message to be a bit more appropriate for the creation of new content.

In the email subject, we can change the word, “comment”, to the token, “[node:content-type]”, which will be dynamically re-written to say, for example, “bug report”. We can change all the links and mentions of comment to the appropriate tokens for content. With just a few edits, we can have a new message body that looks something like this:

A new piece of [node:content-type] content has been posted on [site:name]. Please review for spam or post a reply, if appropriate:
  <strong>Title:</strong> <a href="[node:url]">[node:title]</a> (<a href="[node:edit-url]">edit</a>)
  <strong>Content body:</strong>
  [node:body]

Create a rule for “new content” in Drupal 6

If you are using Drupal 6, we couldn’t clone the “new comment” rule as a starting point for our “new content” rule, but it should be clear how to create the rule we need. Start by creating a new rule triggered by the event: “After saving new content”.

Drupal 6 - New rule with event: “After saving new content”

Add a “User has role(s)” condition

Condition: content’s AUTHOR does NOT have ANY trusted roleHere we want to select the “content’s author” option for the “user” in the “Arguments configuration” section. The rest is just like we did before; select trusted roles, negate, and make sure “any” is selected for the “match against…” option:

Add an action to send an (HTML) email

Now simply create your email message, just as before, but using token replacement patterns that work with content. So you might want to use something like: “New [node:type-name] on [:global:site-name]” for your “Subject” and enter an HTML message like:

<p>Please check the following new [node:type-name] content, created [node:small], for possible spam:<br />
  <strong>Content: </strong><a href="[node:node-url]">[node:title]</a> (<a href="[:global:site-url]node/[node:nid]/edit">edit</a>)<br />
  <strong>Created by:</strong> <a href="[author:account-url]">[author:user]</a></p>
Unfortunately, it seems that Rules in Drupal 6 does not provide for a [node:body] token and we have to build our “edit url” from the various components (i.e. the token for the site’s base URL, which outputs, e.g. "http://example.com/" and ends in a slash, plus node/[node:nid]/edit gives us the same output that the [node:edit-url] token provides in Drupal 7.)

And this is what it should look like when a spammer creates a new piece of “content”

The following is a screenshot of the message generated by one of the most recent pieces of spam “content” posted on drupal.cocomore.com when I didn’t spot the new account creation early enough to block the user before they started spamming:

An example, real-world message from the example code given above

Download exported code for this rule

I’ve also attached the exported Rules for all versions (Drupal 6 and Drupal 7 / plain and HTML email notifications), so if this code is of any help to your process, you can work with it:
Drupal 6 new content created by untrusted role—HTML email / Plain-text email
Drupal 7 new content created by untrusted role—HTML email / Plain-text email

Best wishes and… troubleshooting tips

As I suggested in the previous post, it’s probably best to start by initially triggering a simple rule with an even simpler email (to test that you get your message) and then build up the complexity a small step at a time, testing as you go. Sometimes the tokens don’t work as expected or a token might not have a value in every situation; and unfortunately in such cases, Rules just doesn’t send a message. If you are working in a development environment, you can turn on full “debugging” for Rules in the settings and allow all roles to see the evaluation of the rules (so you can switch between test users and see what happens when you trigger the actions).

I wish you the best of luck in creating the perfect Rules workflow for your use case.

AttachmentSize
new_comment_untrusted_role-d6-html_mail.txt3.48 KB
new_comment_untrusted_role-d6-plain_mail.txt2.68 KB
new_comment_untrusted_role-d7_rules-html_mail.txt1.06 KB
new_comment_untrusted_role-d7_rules-plain_mail.txt908 bytes
new_content_untrusted_role-d6_rules_html_mail.txt3.63 KB
new_content_untrusted_role-d6_rules_plain_mail.txt5.18 KB
new_content_untrusted_role-d7_rules_html_mail.txt1.09 KB
new_content_untrusted_role-d7_rules_plain_mail.txt883 bytes

Comments

thanks a lot for the post! I

thanks a lot for the post! I am new at this, so it is going to be helpful
i wish i came across your blog earlier, bookmarking it now