diff --git a/includes/simplenews.admin.inc b/includes/simplenews.admin.inc
index 5b47cd1..7cb0cbc 100644
--- a/includes/simplenews.admin.inc
+++ b/includes/simplenews.admin.inc
@@ -284,8 +284,13 @@ function simplenews_issue_send($nids) {
       continue;
     }
 
-    simplenews_update_sent_status($node);
-    simplenews_add_node_to_spool($node);
+    $status = simplenews_add_node_to_spool($node);
+    if ($status == SIMPLENEWS_STATUS_SEND_READY) {
+      drupal_set_message(t('Newsletter %title sent.', array('%title' => $node->title)));
+    }
+    else {
+      drupal_set_message(t('Newsletter %title pending.', array('%title' => $node->title)));
+    }
   }
 }
 
diff --git a/includes/simplenews.api.php b/includes/simplenews.api.php
index 5afc107..7fde931 100644
--- a/includes/simplenews.api.php
+++ b/includes/simplenews.api.php
@@ -67,3 +67,29 @@ function hook_simplenews_subscriber_insert($subscriber) {
 function hook_simplenews_subscriber_delete($subscriber) {
 
 }
+
+/**
+ * Invoked if a user is subscribed to a newsletter.
+ *
+ * @param $subscriber
+ *   The subscriber object including all subscriptions of this user.
+ *
+ * @param $subscription
+ *   The subscription object for this specific subscribe action.
+ */
+function hook_simplenews_subscribe_user($subscriber, $subscription) {
+
+}
+
+/**
+ * Invoked if a user is unsubscribed from a newsletter.
+ *
+ * @param $subscriber
+ *   The subscriber object including all subscriptions of this user.
+ *
+ * @param $subscription
+ *   The subscription object for this specific unsubscribe action.
+ */
+function hook_simplenews_unsubscribe_user($subscriber, $subscription) {
+
+}
diff --git a/includes/simplenews.mail.inc b/includes/simplenews.mail.inc
index 8e89ac3..b16110c 100644
--- a/includes/simplenews.mail.inc
+++ b/includes/simplenews.mail.inc
@@ -4,54 +4,52 @@
  * @file
  * Simplenews email send and spool handling
  *
- * @ingroup simplenews
+ * @ingroup mail
  */
 
- /**
- * Send newsletter node to subscribers.
+/**
+ * Add the newsletter node to the mail spool.
  *
- * @param mixed $node
- *   The newsletter node to be sent.  If an integer, the node nid; if an object,
- *   the node object.
+ * Depending on the configuration, the node will either be sent immediatly
+ * afterwards or during cron runs.
+ *
+ * @param $node
+ *   The newsletter node to be sent.
  */
 function simplenews_add_node_to_spool($node) {
-  if (is_numeric($node)) {
-    $node = node_load($node);
-  }
+  // To send the newsletter, the node id and target email addresses
+  // are stored in the spool.
+  // Only subscribed recipients are stored in the spool (status = 1).
+  $select = db_select('simplenews_subscriber', 's');
+  $select->innerJoin('simplenews_subscription', 't', 's.snid = t.snid');
+  $select->addField('s', 'mail');
+  $select->addField('s', 'snid');
+  $select->addField('t', 'tid');
+  $select->addExpression($node->nid, 'nid');
+  $select->addExpression(SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED, 'status');
+  $select->addExpression(REQUEST_TIME, 'timestamp');
+  $select->condition('t.tid', $node->simplenews->tid);
+  $select->condition('t.status', SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED);
+  $select->condition('s.activated', SIMPLENEWS_SUBSCRIPTION_ACTIVE);
 
-  if (is_object($node)) {
-    // To send the newsletter, the node id and target email addresses
-    // are stored in the spool.
-    // Only subscribed recipients are stored in the spool (status = 1).
-    $select = db_select('simplenews_subscriber', 's');
-    $select->innerJoin('simplenews_subscription', 't', 's.snid = t.snid');
-    $select->addField('s', 'mail');
-    $select->addField('s', 'snid');
-    $select->addField('t', 'tid');
-    $select->addExpression($node->nid, 'nid');
-    $select->addExpression(SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED, 'status');
-    $select->addExpression(REQUEST_TIME, 'timestamp');
-    $select->condition('t.tid', $node->simplenews->tid);
-    $select->condition('t.status', SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED);
-    $select->condition('s.activated', SIMPLENEWS_SUBSCRIPTION_ACTIVE);
-
-    $query = db_insert('simplenews_mail_spool')
-      ->from($select)
-      ->execute();
-
-    // When cron is not used the newsletter is send immediately to the emails
-    // in the spool. When cron is used newsletters are send to addresses in the
-    // spool during the next (and following) cron run.
-    if (variable_get('simplenews_use_cron', TRUE) == FALSE) {
-      simplenews_mail_spool();
-      drupal_set_message(t('Newsletter sent.'));
-      simplenews_clear_spool();
-      simplenews_send_status_update();
-    }
-    else {
-      drupal_set_message(t('Newsletter pending.'));
-    }
+  db_insert('simplenews_mail_spool')
+    ->from($select)
+    ->execute();
 
+  // Update simplenews newsletter status to send pending.
+  simplenews_update_sent_status($node);
+
+  // When cron is not used the newsletter is send immediately to the emails
+  // in the spool. When cron is used newsletters are send to addresses in the
+  // spool during the next (and following) cron run.
+  if (variable_get('simplenews_use_cron', TRUE) == FALSE) {
+    simplenews_mail_spool();
+    simplenews_clear_spool();
+    simplenews_send_status_update();
+    return SIMPLENEWS_STATUS_SEND_READY;
+  }
+  else {
+    return SIMPLENEWS_STATUS_SEND_PENDING;
   }
 }
 
diff --git a/simplenews.module b/simplenews.module
index 9acd135..fbddf09 100644
--- a/simplenews.module
+++ b/simplenews.module
@@ -484,7 +484,6 @@ function simplenews_node_update($node) {
   // Check if the newsletter is set to send on publish and needs to be send.
   if ($node->simplenews->status == SIMPLENEWS_STATUS_SEND_PUBLISH && $node->status == NODE_PUBLISHED) {
     module_load_include('inc', 'simplenews', 'includes/simplenews.mail');
-    simplenews_update_sent_status($node);
     simplenews_add_node_to_spool($node);
   }
   else {
@@ -1371,11 +1370,11 @@ function simplenews_subscribe_user($mail, $tid, $confirm = TRUE, $source = 'unkn
     $subscription->source = $source;
     simplenews_subscription_save($subscription);
     $subscriber->tids[$tid] = $tid;
-
     // Execute simplenews subscribe trigger.
     simplenews_call_actions('subscribe', $subscriber);
+
+    module_invoke_all('simplenews_subscribe_user', $subscriber, $subscription);
   }
-  module_invoke_all('simplenews_subscribe_user', $subscriber);
   return TRUE;
 }
 
@@ -1436,8 +1435,9 @@ function simplenews_unsubscribe_user($mail, $tid, $confirm = TRUE, $source = 'un
 
     // Execute simplenews unsubscribe trigger
     simplenews_call_actions('unsubscribe', $subscriber);
+
+    module_invoke_all('simplenews_unsubscribe_user', $subscriber, $subscription);
   }
-  module_invoke_all('simplenews_unsubscribe_user', $subscriber);
   return TRUE;
 }
 
@@ -3007,8 +3007,13 @@ function simplenews_node_tab_send_form_submit($form, &$form_state) {
   // Send newsletter to all subscribers or send test newsletter
   module_load_include('inc', 'simplenews', 'includes/simplenews.mail');
   if ($values['simplenews']['send'] == SIMPLENEWS_COMMAND_SEND_NOW) {
-    simplenews_update_sent_status($node);
-    simplenews_add_node_to_spool($node);
+    $status = simplenews_add_node_to_spool($node);
+    if ($status == SIMPLENEWS_STATUS_SEND_READY) {
+      drupal_set_message(t('Newsletter %title sent.', array('%title' => $node->title)));
+    }
+    else {
+      drupal_set_message(t('Newsletter %title pending.', array('%title' => $node->title)));
+    }
   }
   elseif ($values['simplenews']['send'] == SIMPLENEWS_COMMAND_SEND_TEST) {
     simplenews_send_test($node, $form_state['test_addresses']);
diff --git a/simplenews_rules/simplenews_rules.info b/simplenews_rules/simplenews_rules.info
new file mode 100644
index 0000000..b7a3387
--- /dev/null
+++ b/simplenews_rules/simplenews_rules.info
@@ -0,0 +1,6 @@
+name = Simplenews rules
+description = Provides integration with Rules module for Simplenews.
+dependencies[] = simplenews
+dependencies[] = rules
+package = Mail
+core = 7.x
diff --git a/simplenews_rules/simplenews_rules.module b/simplenews_rules/simplenews_rules.module
new file mode 100755
index 0000000..96cf792
--- /dev/null
+++ b/simplenews_rules/simplenews_rules.module
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Module file for Simpelnews rules integration.
+ */
+
+define('SIMPLENEWS_RULES_CONFIRMATION_DEFAULT', 0);
+define('SIMPLENEWS_RULES_CONFIRMATION_YES', 1);
+define('SIMPLENEWS_RULES_CONFIRMATION_NO', 2);
+
+
+/**
+ * Returns the options for the confirmation paramter.
+ */
+function simplenews_rules_confirmation_list() {
+  return array(
+    SIMPLENEWS_RULES_CONFIRMATION_DEFAULT => t('Default'),
+    SIMPLENEWS_RULES_CONFIRMATION_YES => t('Yes'),
+    SIMPLENEWS_RULES_CONFIRMATION_NO => t('No'),
+  );
+}
+
+/**
+ * Implements hook_simplenews_unsubscribe_user().
+ */
+function simplenews_rules_simplenews_unsubscribe_user($subscriber, $subscription) {
+  $args = array(
+    'mail' => $subscriber->mail,
+    'tid' => $subscription->tid,
+  );
+  rules_invoke_event_by_args('simplenews_rules_event_unsubscribe', $args);
+}
+
+/**
+ * Implements hook_simplenews_unsubscribe_user().
+ */
+function simplenews_rules_simplenews_subscribe_user($subscriber, $subscription) {
+  $args = array(
+    'mail' => $subscriber->mail,
+    'tid' => $subscription->tid,
+  );
+  rules_invoke_event_by_args('simplenews_rules_event_subscribe', $args);
+}
\ No newline at end of file
diff --git a/simplenews_rules/simplenews_rules.rules.inc b/simplenews_rules/simplenews_rules.rules.inc
new file mode 100755
index 0000000..5f9cc9b
--- /dev/null
+++ b/simplenews_rules/simplenews_rules.rules.inc
@@ -0,0 +1,217 @@
+<?php
+
+/**
+ * @file
+ * Rules hooks for the Simplenews newsletter module.
+ *
+ * @addtogroup rules
+ * @{
+ */
+
+/**
+ * Implements hook_rules_action_info().
+ */
+function simplenews_rules_rules_action_info() {
+  return array(
+    'simplenews_rules_action_send' => array(
+      'label' => t('Send newsletter'),
+      'group' => t('Simplenews'),
+      'parameter' => array(
+        'node' => array(
+          'type' => 'node',
+          'label' => t('The newsletter node to be sent.'),
+          'description' => t('The newsletter node that should be sent.'),
+        )
+      )
+    ),
+    'simplenews_rules_action_subscribe' => array(
+      'label' => t('Subscribe an e-mail adress to a newsletter'),
+      'group' => t('Simplenews'),
+      'named parameter' => TRUE,
+      'parameter' => array(
+        'mail' => array(
+          'type' => 'text',
+          'label' => t('E-mail'),
+          'description' => t('The e-mail address that should be subscribed.'),
+        ),
+        'tid' => array(
+          'type' => 'integer',
+          'label' => t('Simplenews category'),
+          'descrption' => t('For which newsletter category the subscription should happen.'),
+          'options list' => 'simplenews_category_list',
+        ),
+        'confirmation' => array(
+          'type' => 'integer',
+          'label' => t('Confirmation required'),
+          'description' => t('Select if a confirmation is required. Default uses the default setting from the chosen newsletter category.'),
+          'options list' => 'simplenews_rules_confirmation_list',
+          'default value' => SIMPLENEWS_RULES_CONFIRMATION_DEFAULT,
+        ),
+        'source' => array(
+          'type' => 'string',
+          'label' => t('Source'),
+          'description' => t('A string to identify the source of this subscription'),
+          'optional' => TRUE,
+        ),
+        'source' => array(
+          'type' => 'text',
+          'label' => t('Source'),
+          'description' => t('A string to identify the source of this subscription'),
+          'optional' => TRUE,
+          'default value' => 'rules',
+        ),
+        'language' => array(
+          'type' => 'token',
+          'label' => t('Language'),
+          'description' => t('If specified, the language to use for the subscription. Defaults to the default language.'),
+          'options list' => 'entity_metadata_language_list',
+          'optional' => TRUE,
+          'default value' => LANGUAGE_NONE,
+        ),
+      ),
+    ),
+    'simplenews_rules_action_unsubscribe' => array(
+      'label' => t('Unsubscribe an e-mail adress from a newsletter'),
+      'group' => t('Simplenews'),      'named parameter' => TRUE,
+      'parameter' => array(
+        'mail' => array(
+          'type' => 'text',
+          'label' => t('E-mail'),
+          'description' => t('The e-mail address that should be unsubscribed.'),
+        ),
+        'tid' => array(
+          'type' => 'integer',
+          'label' => t('Simplenews category'),
+          'descrption' => t('For which newsletter category the unsubscription should happen.'),
+          'options list' => 'simplenews_category_list',
+        ),
+        'confirmation' => array(
+          'type' => 'integer',
+          'label' => t('Confirmation required'),
+          'description' => t('Select if a confirmation is required. Default uses the default setting from the chosen newsletter category.'),
+          'options list' => 'simplenews_rules_confirmation_list',
+          'default value' => SIMPLENEWS_RULES_CONFIRMATION_DEFAULT,
+        ),
+        'source' => array(
+          'type' => 'text',
+          'label' => t('Source'),
+          'description' => t('A string to identify the source of this subscription'),
+          'optional' => TRUE,
+          'default value' => 'rules',
+        ),
+        'language' => array(
+          'type' => 'token',
+          'label' => t('Language'),
+          'description' => t('If specified, the language to use for the subscription. Defaults to the default language.'),
+          'options list' => 'entity_metadata_language_list',
+          'optional' => TRUE,
+          'default value' => LANGUAGE_NONE,
+        ),
+      ),
+    ),
+  );
+}
+
+/**
+ * Implements hook_event_info().
+ */
+function simplenews_rules_rules_event_info() {
+  return array(
+    'simplenews_rules_event_subscribe' => array(
+      'label'  => t('A user has been subscribed'),
+      'group' => t('Simplenews'),
+      'variables'   => array(
+        'mail' => array(
+          'type' => 'text',
+          'label' => t('E-Mail'),
+          'description' => t('The e-mail address that has been subscribed.'),
+        ),
+        'tid' => array(
+          'type' => 'integer',
+          'label' => t('Simplenews category'),
+          'descrption' => t('The newsletter category of the subscription.'),
+          'options list' => 'simplenews_category_list',
+        ),
+      ),
+    ),
+    'simplenews_rules_event_unsubscribe' => array(
+      'label'  => t('A user has been unsubscribed'),
+      'group' => t('Simplenews'),
+      'variables'   => array(
+        'mail' => array(
+          'type' => 'text',
+          'label' => t('E-mail'),
+          'description' => t('The e-mail address that has been subscribed.'),
+        ),
+        'tid' => array(
+          'type' => 'integer',
+          'label' => t('Simplenews category'),
+          'descrption' => t('The newsletter category of the subscription.'),
+          'options list' => 'simplenews_category_list',
+        ),
+      ),
+    ),
+  );
+}
+
+/**
+ * Action implementation, send a newsletter node.
+ */
+function simplenews_rules_action_send($node) {
+  $newsletter = simplenews_newsletter_load($node->nid);
+  if ($newsletter && ($newsletter->status != SIMPLENEWS_STATUS_SEND_PENDING || $newsletter->status != SIMPLENEWS_STATUS_SEND_PENDING)) {
+    simplenews_add_node_to_spool($node);
+  }
+}
+
+/**
+ * Action Implementation: Subscribe an e-mail adress to a Simplenews newsletter.
+ */
+function simplenews_rules_action_subscribe($args, $settings) {
+  if ($args['language'] == LANGUAGE_NONE) {
+    $args['language'] = NULL;
+  }
+
+  $confirmation = simplenews_rules_map_confirmation($args);
+
+  // Pass the call forward.
+  simplenews_subscribe_user($args['mail'], $args['tid'], $confirmation, $args['source'], $args['language']);
+}
+
+/**
+ * Action Implementation: Unsubscribe an e-mail adress to a Simplenews newsletter.
+ */
+function simplenews_rules_action_unsubscribe($args, $settings) {
+  if ($args['language'] == LANGUAGE_NONE) {
+    $args['language'] = NULL;
+  }
+
+  $confirmation = simplenews_rules_map_confirmation($args);
+
+  // Pass the call forward.
+  simplenews_unsubscribe_user($args['mail'], $args['tid'], $confirmation, $args['source'], $args['language']);
+}
+
+
+/**
+ * Map args to the confrmation argument for subscribing/unsubscribing.
+ */
+function simplenews_rules_map_confirmation($args) {
+  switch ($args['confirmation']) {
+    case SIMPLENEWS_RULES_CONFIRMATION_YES:
+      $confirmation = TRUE;
+      break;
+    case SIMPLENEWS_RULES_CONFIRMATION_NO:
+      $confirmation = FALSE;
+      break;
+    case SIMPLENEWS_RULES_CONFIRMATION_DEFAULT:
+      $account = _simplenews_user_load($args['mail']);
+      $confirmation = simplenews_require_double_opt_in($args['tid'], $account);
+      break;
+  }
+  return $confirmation;
+}
+
+/**
+ * @}
+ */
