In building a lot of custom workflows, I've found that the ability to send an email to all users of a role would be useful, so here's a patch against 6.x-1.11 which provides a new "Send a tokenized email to users of a role..." action. It's got fairly robust error checking.

Enjoy!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Steven Merrill’s picture

This patch adds one small but desirable bit over the last one - a #default_value for the form, so that the value isn't eradicated upon going back and editing the advanced action.

greggles’s picture

Status: Needs review » Needs work

This seems pretty handy to me. Two questions:

1) The style of the recipient query seems weird:

$recipient_query = <<<QUERY
+SELECT u.mail FROM {users} u
+INNER JOIN {users_roles} ur ON ur.uid = u.uid
+WHERE ur.rid = %d
+QUERY;

I don't think I've ever seen a query like that in Drupal. More common seems to be one big long line which is what I'd prefer.

2) I think it would be better to put the drupal_mail inside of the for loop and send one e-mail per person in the role. First, that makes the watchdog error more specific. Second (and I haven't tested this, soo...) I'm assuming that putting all the recipients on the to: line will mean that all members of a role will see the e-mail addresses for that role. For privacy reasons it's important we don't let that happen.

Sending mails in a tight loop like that can be a performance issue if the role is really big, but we have solutions like http://drupal.org/project/queue_mail for that.

Ylan’s picture

Will this functionality be added to token actions? It seems very usefull to me. This project also does role based email actions, only it doesn't use token.

mudd’s picture

Subscribe

michaelfavia’s picture

subscribe as well. I can clean up this patch if wed like to push it forward. Using email acton role until it is mainlined

greggles’s picture

I think it's just missing a code-style re-roll. Please do re-roll/test and I'll test/commit.

johnmunro’s picture

very interested in this too

not_Dries_Buytaert’s picture

Version: 6.x-1.11 » 6.x-1.12

I fully agree with 'greggles' 2nd remark that:
2a) for monitoring/ maintenance purposes, each email should be send separately (so logging/ watchdog errors become more specific).
2b) for privacy reasons recipients should NOT be able to determine to which other users the tokenized email is send (let alone expose their email addresses).

As this feature request is applicable to any current version and in order to prevent duplicate submissions of this feature request, I changed the version to the latest currently available. Please correct me, if the best practice in such cases is different.

mudd’s picture

I agree -- it would be nice to have a choice between (A) all recipients in the To: field, and (B) private recipients, either by sending separate emails or by using the Bcc field. But to have only (A) is a privacy problem.

In this post #267921: All recipients visible on outgoing mails, jeff gives us a patch for module Action email role that (I think) provides a check box in Action|configure to make this choice.

BUT, he states "Instead of multiple calls to drupal_mail()..." -- Token.module appears to call drupal_mail() with a list of recipients it extracted from the role. By inspecting drupal_mail() and drupal_mail_send() I see that it's up to the module coder to call drupal_mail separately for each recipient (too bad 'private' isn't an available parameter!).

This is an important topic for me, so if necessary I'll find someone to patch Token; I'd just need a consensus on how to proceed.

greggles’s picture

What about bcc? I've never done it, but can't Drupal send using one call to drupal_mail and bcc to achieve "private"?

mudd’s picture

I agree that Bcc might be best when sending to a role, but drupal_mail() seems to not have a bcc field. From the API site:
6-7 drupal_mail($module, $key, $to, $language, $params = array(), $from = NULL, $send = TRUE)
and in mail.inc:

  // Bundle up the variables into a structured array for altering.
  $message = array(
    'id'       => $module .'_'. $key,
    'to'       => $to,
    'from'     => isset($from) ? $from : $default_from,
    'language' => $language,
    'params'   => $params, 
    'subject'  => '',
    'body'     => array()
  );

Does anyone think a bcc field should be added to mail.inc and drupal_mail()? (I also don't see any checks against an empty To: field)
'bcc' => $bcc,

BUT, also in drupal_mail() is this section that appears to let a module alter the email via $params. Since the idea above seems crude and would require a drupal core change, perhaps the road to Oz is below (please pardon my newbiness, I'm still learning drupal, PHP and coding methodology)

  // Build the e-mail (get subject and body, allow additional headers) by
  // invoking hook_mail() on this module. We cannot use module_invoke() as
  // we need to have $message by reference in hook_mail().
  if (function_exists($function = $module .'_mail')) {
    $function($key, $message, $params);
  }

  // Invoke hook_mail_alter() to allow all modules to alter the resulting e-mail.
  drupal_alter('mail', $message);

What would this require? Something in token_actions_mail() that replaces "TO:" with "BCC:" in $message if, say, "private_bcc" is specified in $params? (???)

EDIT: I just noticed this function's already here, but I'm puzzled how to attack this. Do I add somewhere the code to set $params['use_bcc'] = 1 and then in this function check with an IF, and replace all the TO:'s to BCC: in $message['header']?

I did a temp hack on token.module to explode $recipient and then run foreach to send individual emails (yes, a performance hit on large roles, but my user base is still small.)

I'd be nice to also integrate similar code to what jeff.ferrari (awesome name) did for Action email role (#267921: All recipients visible on outgoing mails), such as have a radio button choice when defining the tokenized email action.

mudd’s picture

I'm testing a patch that creates a form checkbox that forces token_actions to send by Bcc: rather than To:. It also checks each user's status and skips them if blocked.

Should I open a "code" or "Token Actions" feature request of type 'needs review' or just attach the patch here?

Note -- I still have two problems...

1) What to put in the TO field. Should it be NO-REPLY@mydomain.com?
2) This is for announcing new-posts. But what if some users don't want to be notified? Will I need a user-page that lets them flag "don't email me on new posts" in the database? (ps, I don't allow access to the 'My account' page)

greggles’s picture

@mudd - Thanks for your work. Please open a new issue for this.

pounard’s picture

What's the current state of this issue, is this going to be released soon or are you still working on it?
EDIT: I really need this feature, I might help if you want.

mudd’s picture

A small patch for BCC is here: #513934: BCC email option for Token Actions

j0nathan’s picture

subscribing

benoitg’s picture

subscribing

AaronBauman’s picture

Did anyone else notice that the node tokens don't get tokenized?

I'm using the "Send tokenized e-mail to users of a role" for the event "After saving new content" with the following tokens, none of which get replaced:
[type-name]
[title]
[nid]

AaronBauman’s picture

I'm too lazy to roll a patch, but adding this on the first line of function token_actions_send_email_to_role_action seems to have fixed it:

  if(empty($context['node'])) {
    $context['node'] = $object;
  }
japanitrat’s picture

patch please :)

vitis’s picture

patch would be appreciated

Agileware’s picture

Attached is new_role_email_action3.patch an updated patch file which works for me. Incorporates #1, #19 and the suggestions from #2.

Agileware’s picture

Status: Needs work » Needs review

And please review :)

Agileware’s picture

Fixed a bug where the user context was not set for newly registered users.

Updated patch attached.

Agileware’s picture

Removed the call to drupal_html_to_text as mentioned in #379948: use of drupal_html_to_text suppresses email-newlines and #317303: Token Actions & Mimemail which was suppressing new line characters and I believe no longer required at all.

Updated patch attached.

netentropy’s picture

BCC belings in the header, just add it to the header of drupal_mail it works fine

Agileware’s picture

BCC is not required at all. An individual email is sent to each member of the role. So each user receives a separate email which does not list any other recipients.

Alan.Guggenheim’s picture

subscribe

Agileware’s picture

We really need someone else to review my latest patch and confirm it's working. Then we can move this request to the next status and hopefully get it committed to the module. Anyone out there able to test the patch?

ddv’s picture

I have a test website (running on Dreamhost) that I use for testing modules prior to deployment on the live site. I can test something, but I'm not a programmer so would need specific instructions on what to do.

flips’s picture

Hi,

When used the "Send tokenized e-mail" action, it worked great. As I need to "Send tokenized e-mail to users of a role", I patched the Token module with new_role_email_action5.patch (and tried new_role_email_action2.patch) which does what I need but there is still an issue.

The Trigger module does not recognize the new added system action : "Send tokenized e-mail to users of a role" and as there is not other system action, I get a "No available actions for this trigger." message instead of the action select drop-down list.

There are no troubles with other Token actions. Any ideas? Thanks for help.

Alan.Guggenheim’s picture

Agileware:
I tested your patch and it works great. I created an action and a trigger, and everything worked.

Can you apply your magic to the send tokenized email action? So far, it does not expand any tokens except global!
Would a patch similar to #19 from aaronbauman do the trick?

Thanks

Agileware’s picture

@flips Please use new_role_email_action5.patch as posted on comment #25 - it is the current patch. All others are superseded.

Agileware’s picture

@Alan.Guggenheim thanks for testing.

new_role_email_action5.patch as posted on comment #25 does incorporate the setting of node context as suggested by aaronbauman in #19. Or was it something else you meant? (please explain) :)

Alan.Guggenheim’s picture

@Agileware you are welcome, and it doies work well, I like it and will use it.
But... my initial problem was indeed something else. i found this issue when I was looking for a solution to issue 635570: Tokenized emails do not expand user tokens.
As I saw that you had initially the same issue, but solved it, I am looking for help in fixing the issue in the send_tokenized_email function.

Agileware’s picture

@Alan.Guggenheim are you testing with new_role_email_action5.patch from comment #25 ???

flips’s picture

FileSize
60.15 KB

@Agileware I tried again (new_role_email_action5.patch as posted on comment #25) and I get the same problem.

I use Trigger and Apply_for_role modules. When I create any action with Token, they are displayed in the Apply_for_role tab of Triggers except the "Send tokenized e-mail to users of a role" one. Under the Users tab of Trigger, this one is displayed.

Could the problem come from the Apply for role module ?

thanks for your help.

nicanorflavier’s picture

@#25 I tested your patch but it's not working, I'm using workflow module, I was able to select the action and configure it, but when I approve and send emails to roles, when I click submit it is giving me a blank white page. Any ideas?

Agileware’s picture

@nickyflavier:
If you are getting a blank white page can you check your apache error log and post the error that is occurring?

dwightaspinwall’s picture

Patch in #25 works great for me. Many thanks.

valuebound’s picture

#25: new_role_email_action5.patch queued for re-testing.

5t4rdu5t’s picture

Hi,

I've tested patch in #25, corrected 1 typo ($context['recipient'] for $content['recipient']), and added functionality for multiple roles selection.

Any further testing or improvements are welcome!

Status: Needs review » Needs work

The last submitted patch, new_role_email_action6.patch, failed testing.

stinky’s picture

Subscribe

flamingvan’s picture

I've taken the #25 patch and done a couple of things with it. I made it into a standalone module (which I put into the modules/token directory). A standalone module is desirable to me because it seems easier to maintain.

More to the point, though, I made the dropdown selection for the role a multiple selection box and modified some of the SQL. This way, you can select multiple roles to which an email will be sent. Also, I added some and/or radio buttons, so you can decide if you want the mail to go to users who are memebers of any of the selected roles ('or') or only users who are members of all of the selected roles ('and').

Would somebody want to test this? Also, my SQL code works but I think it could probably be more concise. Is there a SQL wiz out there who would want to take a crack at it? Here's the relevant section of code:

  if($context['recipientLogic'] == "AND"){ 
    $query = 'SELECT u.mail
              FROM users_roles ur
              INNER JOIN users u on u.uid = ur.uid
              WHERE ur.rid = ' . current($context['recipient']);
    while(next($context['recipient'])){
      $query .= ' AND ur.uid IN (
              	SELECT ur.uid
              	FROM users_roles ur
              	WHERE ur.rid = ' . current($context['recipient']) . ')';
    }
    $query .= " AND u.status = 1 AND (u.mail is not null OR u.mail!='')";  
    $recipient_result = db_query($query);    
  }
  else{
    $recipient_result = db_query("SELECT u.mail FROM {users} u INNER JOIN {users_roles} ur ON ur.uid = u.uid WHERE ur.rid IN %s AND u.status = 1 AND (u.mail is not null OR u.mail!='')", "(".implode(",", $context['recipient']).")" );        
  }
flamingvan’s picture

FileSize
2.73 KB

Forgot to include the module

flamingvan’s picture

FileSize
3.12 KB

Here's an enhanced version of the module from #47. This one also allows the email sent to be limited by term (for node related actions).

Would anyone mind if I made this into a module project? I'd be happy to give credit to others who wrote the original code that I modified.

valuebound’s picture

Title: Send tokenized email to members of a role » please help me to find variables acced from module to theme....

hi,
i am getting information in presenting a node completely as a description where as i want to access all individual variables so as i can display only a few of them.
thanks,
suneel

greggles’s picture

Title: please help me to find variables acced from module to theme.... » Send tokenized email to members of a role
Status: Needs work » Closed (won't fix)

@valuebound, please don't repurpose an issue to something totally different :/

I think this issue is "won't fix" at this point.

http://drupal.org/project/views_send works really well for this kind of thing.

Agileware’s picture

@greggles what's the reasoning for changing the status to "won't fix" ?

http://drupal.org/project/views_send does not provide this functionality at all and so cannot be used as a replacement for this feature.

greggles’s picture

From the project page:

Create a view and add at least one column containing E-mail addresses.
[Optional] Expose Views filters to let the user easily build list of recipients using UI.
Create a "Page" display and set the Style to "Bulk Operations".
On "Bulk Operations" Style configuration, under "Selected operations", select Send mass mail (views_send_mail_action).
Save the view, load the page, use exposed filters to build the list, select all or some rows and choose "Send mass mail".
Fill the message form to configure the E-mail. Use tokens to personalize your E-mail. The module provide also row-based tokens, taken from the current row of the view. For example, if the view has a column with the key users_name (the user name) you can use this replacement token [views-send-users_name].
Preview and send the message.

That sounds pretty similar to what this patch did (last I tried it).

Can you point out something that is possible with this patch and not with views_send?

Agileware’s picture

Can you integrate the Views, Bulk Operations so that it called from the Drupal Action? As that is the feature that this patch provides, sending "Send a tokenized email to users of a role" using a Drupal Action.

Which is trivial to setup and very useful.

dkinzer’s picture

subscribing

gagarine’s picture