--- token_actions.module	2010-01-22 15:27:29.000000000 +1100
+++ token_actions.module-updated	2010-01-22 15:27:51.000000000 +1100
@@ -39,6 +39,17 @@ function token_actions_action_info() {
         'taxonomy' => array('insert', 'update', 'delete'),
       )
     ),
+    'token_actions_send_email_to_role_action' => array(
+      'description' => t('Send tokenized e-mail to users of a role'),
+      'type' => 'system',
+      'configurable' => TRUE,
+      'hooks' => array(
+        'nodeapi' => array('view', 'insert', 'update', 'delete'),
+        'comment' => array('view', 'insert', 'update', 'delete'),
+        'user' => array('view', 'insert', 'update', 'delete', 'login'),
+        'taxonomy' => array('insert', 'update', 'delete'),
+      )
+    ),
     'token_actions_goto_action' => array(
       'description' => t('Redirect to a tokenized URL'),
       'type' => 'system',
@@ -142,6 +153,128 @@ function token_actions_send_email_action
   }
 }
 
+/**
+ * Return a form definition so the Send email action can be configured.
+ *
+ * @param $context
+ *   Default values (if we are editing an existing action instance).
+ * @return
+ *   Form definition.
+ */
+function token_actions_send_email_to_role_action_form($context) {
+  if(empty($context['node'])) {
+    $context['node'] = $object;
+  }
+
+  // Set default values for form.
+  if (!isset($context['recipient'])) {
+    $context['recipient'] = '';
+  }
+  if (!isset($context['subject'])) {
+    $context['subject'] = '';
+  }
+  if (!isset($context['message'])) {
+    $context['message'] = '';
+  }
+
+  $form['recipient'] = array(
+    '#type' => 'select',
+    '#title' => t('Recipient Role'),
+    '#default_value' => $context['recipient'],
+    '#options' => user_roles(),
+    '#size' => '20',
+    '#maxlength' => '254',
+    '#description' => t('The role to which the message should be sent.'),
+  );
+  $form['subject'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Subject'),
+    '#default_value' => $context['subject'],
+    '#size' => '20',
+    '#maxlength' => '254',
+    '#description' => t('The subject of the message.'),
+  );
+  $form['message'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Message'),
+    '#default_value' => $context['message'],
+    '#cols' => '80',
+    '#rows' => '20',
+    '#description' => t('The message that should be sent.'),
+  );
+
+  $form['help'] = array(
+    '#type' => 'fieldset',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#title' => t('Placeholder tokens'),
+    '#description' => t("The following placeholder tokens can be used in to generate the URL path. Some tokens may not be available, depending on the context in which the action is triggered."),
+  );
+
+  $form['help']['tokens'] = array(
+    '#value' => theme('token_help', 'all'),
+  );
+
+  return $form;
+}
+
+function token_actions_send_email_to_role_action_submit($form, $form_state) {
+  $form_values = $form_state['values'];
+  // Process the HTML form to store configuration. The keyed array that
+  // we return will be serialized to the database.
+  $params = array(
+    'recipient' => $form_values['recipient'],
+    'subject'   => $form_values['subject'],
+    'message'   => $form_values['message'],
+  );
+  return $params;
+}
+
+/**
+ * Implementation of a configurable Drupal action.
+ * Sends an email.
+ */
+function token_actions_send_email_to_role_action($object, $context) {
+  $role_name = db_result(db_query("SELECT name FROM {role} WHERE rid=%d", $context['recipient']));
+  if (!$role_name) {
+    watchdog('error', 'Unable to send mail - role ID %rid does not exist', array('%rid' => $content['recipient']));
+    return;
+  }
+  
+  $context['global'] = NULL;
+  if (!empty($context['node']) && empty($context['user'])) {
+    $context['user'] = user_load(array('uid' => $context['node']->uid));
+  }
+
+  $params['from'] = variable_get('site_mail', ini_get('sendmail_from'));
+  $params['subject'] = str_replace(array("\r", "\n"), '', token_replace_multiple($context['subject'], $context));
+  $params['body'] = drupal_html_to_text(token_replace_multiple($context['message'], $context));
+
+  // Only select those users who are active AND have an email address set
+  $recipient_result = db_query("SELECT u.mail FROM {users} u INNER JOIN {users_roles} ur ON ur.uid = u.uid WHERE ur.rid = %d AND u.status = 1 AND (u.mail is not null OR u.mail!='') ", $context['recipient']);
+
+  if ($recipient_result) {
+    while ($recipient = db_fetch_array($recipient_result)) {
+      if ($recipient['mail']) {
+        if (drupal_mail('token_actions', 'action_send_email', $recipient['mail'], language_default(), $params)) {
+          watchdog('action', 'Sent email to user with role %role_name: %recipient', array(
+          '%recipient' => $recipient['mail'],
+          '%role_name' => $role_name,
+          ));
+        }
+        else {
+          watchdog('error', 'Unable to send email to %recipient', array('%recipient' => $recipient['mail']));
+        }  
+      }
+    }
+  }
+  else {
+    // No users with that role - should update the action
+    watchdog('error', 'Unable to send mail - there are no users in role %role_name', array('%role_name' => $role_name));
+    return;
+  }
+}
+
 function token_actions_mail($key, &$message, $params) {
   $message['subject'] = $params['subject'];
   $message['body'][] = $params['body'];
