diff --git a/notifo.admin.inc b/notifo.admin.inc
new file mode 100644
index 0000000..1bdea10
--- /dev/null
+++ b/notifo.admin.inc
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Administration forms for the Notifo module.
+ */
+
+/**
+ * Menu callback; Displays the administration settings for Notifo.
+ */
+function notifo_admin_settings() {
+  $form['notifo_sp'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Service Provider Username'),
+    '#description' => t('This is the service provider username for the site.'),
+    '#default_value' => variable_get('notifo_sp', ''),
+  );
+  $form['notifo_api_key'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Service Provider API key'),
+    '#description' => t('This is the api key related to the above username.'),
+    '#default_value' => variable_get('notifo_api_key', ''),
+  );
+  return system_settings_form($form);
+}
diff --git a/notifo.info b/notifo.info
index 6ec66a1..83e1968 100644
--- a/notifo.info
+++ b/notifo.info
@@ -3,3 +3,5 @@ description = "Provide an action to send notifications via notifo (for more info
 
 core = 7.x
 files[] = notifo.module
+files[] = notifo.rules.inc
+files[] = notifo_api.php
diff --git a/notifo.install b/notifo.install
new file mode 100644
index 0000000..c89f5b3
--- /dev/null
+++ b/notifo.install
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Provides any required installation or upgrade path requirements.
+ */
+
+/**
+ * Implementation of hook_schema().
+ */
+function notifo_schema() {
+  $schema = array();
+  $schema['notifo'] = array(
+    'fields' => array(
+      'notifo_id' => array(
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'uid' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'notifo' => array(
+        'description' => 'The Notifo username for the user.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+    ),
+    'primary key' => array('notifo_id'),
+    'indexes' => array(
+      'uid' => array('uid'),
+    ),
+  );
+  return $schema;
+}
+
+/**
+ * Allow users to provide their own Notifo usernames.
+ */
+function notifo_update_7000() {
+  drupal_install_schema('notifo');
+}
diff --git a/notifo.module b/notifo.module
index d5d4025..3cf550c 100644
--- a/notifo.module
+++ b/notifo.module
@@ -5,6 +5,116 @@
  * API bridge to the Notifo mobile notification service.
  */
 
+/**
+ * Implements hook_help().
+ */
+function notifo_help($path, $arg) {
+  switch ($path) {
+  case 'admin/help#notifo':
+    return '<p>' . t('Provides interaction between Drupal and the Notifo notification service.') . '</p>';
+      break;
+  case 'admin/config/services/notifo':
+    return '<p>'. t('The following provides the general configuration options for the <a href="@notifo">Notifo</a> notification web service.', array('@notifo' => 'http://notifo.com')) .'</p>';
+  }
+}
+
+/**
+ * Implements hook_menu().
+ */
+function notifo_menu() {
+  $items['admin/config/services/notifo'] = array(
+    'title' => 'Notifo',
+    'description' => 'Provides configuration options for the notifo notification system.',
+    'access arguments' => array('administer notifo'),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('notifo_admin_settings'),
+    'file' => 'notifo.admin.inc',
+  );
+  return $items;
+}
+
+/**
+ * Implements hook_permission().
+ */
+function notifo_permission() {
+  return array(
+    'administer notifo' => array(
+      'title' => t('Administer Notifo'),
+    ),
+    'edit own notifo' => array(
+      'title' => t('Provide own Notifo username'),
+    ),
+  );
+}
+
+/**
+ * Implements hook_user_load().
+ */
+function notifo_user_load($users) {
+  $result = db_query('SELECT uid, notifo FROM {notifo} WHERE uid IN (:uids)', array(':uids' => array_keys($users)));
+  foreach ($result as $record) {
+    $users[$record->uid]->notifo = $record->notifo;
+  }
+}
+
+/**
+ * Implemts hook_form_FORM_ID_alter().
+ */
+function notifo_form_user_profile_form_alter(&$form, &$form_state) {
+  global $user;
+  if ($form['#user_category'] == 'account') {
+    // The user can only access their notifo username if they have permission.
+    $account = $form['#user'];
+    $access = ($user->uid == $account->uid) && user_access('edit own notifo');
+
+    // Provide a text field for the user to enter their Notifo username.
+    $form['notifo'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Notifo Username'),
+      '#description' => t('Enter your <a href="@notifo">Notifo</a> username to have notifications sent to you.', array('@notifo' => 'http://notifo.com')),
+      '#default_value' => isset($account->notifo) ? $account->notifo : '',
+      '#access' => $access || user_access('administer notifo'),
+    );
+  }
+}
+
+/**
+ * Implements hook_user_update().
+ */
+function notifo_user_update(&$edit, $account, $category) {
+  // Remove the old username for the user and insert the new one.
+  db_delete('notifo')->condition('uid', $account->uid)->execute();
+  notifo_user_insert($edit, $account, $category);
+}
+
+/**
+ * Implements hook_user_insert().
+ */
+function notifo_user_insert(&$edit, $account, $category) {
+  // Add the username to the Notifo table.
+  $notifo = isset($edit['notifo']) ? $edit['notifo'] : '';
+  if (!empty($notifo)) {
+    db_insert('notifo')->fields(array(
+      'notifo' => $notifo,
+      'uid' => $account->uid,
+    ))->execute();
+    notifo_subscribe_user($notifo);
+  }
+}
+
+/**
+ * Implements hook_user_delete().
+ */
+function notifo_user_delete($account) {
+  // Delete the Notifo username from our table.
+  db_delete('notifo')
+    ->condition('uid', $account->uid)
+    ->execute();
+}
+
+/**
+ * Implements hook_action_info().
+ */
 function notifo_action_info() {
   return array(
     'notifo_send_notifo_action' => array(
@@ -18,6 +128,7 @@ function notifo_action_info() {
 
 function notifo_send_notifo_action($object, $context) {
   global $user;
+  $uri = NULL;
 
   switch ($context['hook']) {
     case 'nodeapi':
@@ -25,11 +136,18 @@ function notifo_send_notifo_action($object, $context) {
       // will not be passed as $object, but it will still be available
       // in $context.
       $node = $context['node'];
+      $uri = url('node/' . $node->nid, array(
+        'absolute' => TRUE,
+      ));
       break;
     // The comment hook provides nid, in $context.
     case 'comment':
       $comment = $context['comment'];
       $node = node_load($comment->nid);
+      $uri = url('node/' . $node->nid, array(
+        'absolute' => TRUE,
+        'fragment' => 'comment-' . $comment->cid,
+      ));
       break;
     case 'user':
       // Because this is not an action of type 'user' the user
@@ -39,46 +157,22 @@ function notifo_send_notifo_action($object, $context) {
       if (isset($context['node'])) {
         $node = $context['node'];
       }
+      $uri = url('user/' . $user->uid, array(
+        'absolute' => TRUE,
+      ));
       break;
     default:
       // We are being called directly.
       $node = $object;
   }
 
-  if (isset($node)) {
-    if (!isset($account)) {
-      $account = user_load(array('uid' => $node->uid));
-    }
-  }
-
-  if (!isset($account)) {
-    $account = $user;
-  }
-  $language = user_preferred_language($account);
-
   $usernames = explode(",", $context['usernames']);
   foreach ($usernames as $username) {
-    notifo_send_notification(trim($username), $context['message'], variable_get('site_name', ""), $context['title'], NULL);
+    notifo_send_notification(trim($username), $context['message'], variable_get('site_name', ""), $context['title'], $uri);
   }
 }
 
 function notifo_send_notifo_action_form($context) {
-  $form['sp'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Notifo Service Provider Username'),
-    '#default_value' => isset($context['sp']) ? $context['sp'] : '',
-    '#maxlength' => '254',
-    '#description' => t('This is the service provider username for the site.'),
-  );
-
-  $form['api_key'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Notifo Service Provider API key'),
-    '#default_value' => isset($context['api_key']) ? $context['api_key'] : '',
-    '#maxlength' => '254',
-    '#description' => t('This is the api key related to the above username.'),
-  );
-
   $form['usernames'] = array(
     '#type' => 'textfield',
     '#title' => t('Usernames'),
@@ -122,8 +216,6 @@ function notifo_send_notifo_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.
-  variable_set('notifo_sp', $form_values['sp']);
-  variable_set('notifo_api_key', $form_values['api_key']);
   $usernames = explode(",", $form_values['usernames']);
   foreach ($usernames as $username) {
     if ($form_values['sp'] != $username) {
@@ -132,8 +224,6 @@ function notifo_send_notifo_action_submit($form, $form_state) {
   }
 
   $params = array(
-    'sp'        => $form_values['sp'],
-    'api_key'   => $form_values['api_key'],
     'usernames' => $form_values['usernames'],
     'title'     => $form_values['title'],
     'message'   => $form_values['message'],
@@ -143,27 +233,6 @@ function notifo_send_notifo_action_submit($form, $form_state) {
 }
 
 /**
- * Submit a POST request to the Notifo API.
- *
- * @param $method
- *   Notifo API method to call.
- * @param $query
- *   An array of keys and values the method expects. Values are urlencoded.
- */
-function notifo_request($method, $query) {
-  $sp = variable_get('notifo_sp', '');
-  $api_key = variable_get('notifo_api_key', '');
-
-  $url = "https://$sp:$api_key@api.notifo.com/v1/$method";
-  $headers = array(
-    'Content-Type' => 'application/x-www-form-urlencoded',
-  );
-  $data = drupal_http_build_query($query);
-  $result = drupal_http_request($url, array('headers' => $headers, 'method' => 'POST', 'data' => $data));
-  watchdog('notifo', '<pre>' . print_r($result, TRUE) . '</pre>');
-}
-
-/**
  * Send a notification message.
  *
  * @param $to
@@ -178,21 +247,38 @@ function notifo_request($method, $query) {
  *   URI for the message.
  */
 function notifo_send_notification($to, $msg, $label, $title, $uri) {
-  $query = array(
+  $notifo = notifo();
+  return $notifo->sendNotification(array(
     'to' => $to,
     'msg' => $msg,
     'label' => $label,
     'title' => $title,
     'uri' => $uri,
-  );
-  notifo_request('send_notification', $query);
+  ));
 }
 
 /**
  * Subscribe a user to the API name of the current site.
+ *
  * @param $username
  *   Notifo username to subscribe.
  */
 function notifo_subscribe_user($username) {
-  notifo_request('subscribe_user', array('username' => $username));
+  $notifo = notifo();
+  return $notifo->subscribeUser($username);
 }
+
+/**
+ * Returns the instance of the Notifo API.
+ */
+function notifo() {
+  static $notifo;
+  if (!isset($nofio)) {
+    module_load_include('php', 'notifo', 'notifo_api');
+    $apiUsername = variable_get('notifo_sp');
+    $apiSecret = variable_get('notifo_api_key');
+    $notifo = new Notifo_API($apiUsername, $apiSecret);
+  }
+  return $notifo;
+}
+
diff --git a/notifo.rules.inc b/notifo.rules.inc
new file mode 100644
index 0000000..a33cf15
--- /dev/null
+++ b/notifo.rules.inc
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * Implements hook_rules_action_info().
+ */
+function notifo_rules_action_info() {
+  return array(
+    'notifo_notification' => array(
+      'label' => t('Send a notification to a user'),
+      'parameter' => array(
+        'user' => array('type' => 'user', 'label' => t('Recipient')),
+        'msg' => array('type' => 'text', 'label' => t('Message')),
+        'label' => array('type' => 'text', 'label' => t('Label')),
+        'title' => array('type' => 'text', 'label' => t('Title')),
+        'uri' => array('type' => 'uri', 'label' => t('URI')),
+      ),
+      'group' => t('Notifo'),
+    ),
+  );
+}
+
+/**
+ * Rules Action callback; Sends a Notifo notification.
+ */
+function notifo_notification($user, $msg, $label, $title, $uri) {
+  if (isset($user->notifo)) {
+    notifo_send_notification($user->notifo, $msg, $label, $title, $uri);
+  }
+}
+
diff --git a/notifo_api.php b/notifo_api.php
new file mode 100644
index 0000000..fb1ced9
--- /dev/null
+++ b/notifo_api.php
@@ -0,0 +1,95 @@
+<?php
+
+class Notifo_API {
+  
+  const API_ROOT = 'https://api.notifo.com/';
+  const API_VER = 'v1';
+
+  protected $apiUsername;
+  protected $apiSecret;
+
+  /**
+   * class constructor
+   */
+  function __construct($apiUsername, $apiSecret) {
+    $this->apiUsername = $apiUsername;
+    $this->apiSecret = $apiSecret;
+  }
+
+  function set_apiusername($val) {
+    $this->apiUsername = $val;
+  }
+
+  function set_apisecret($val) {
+    $this->apiSecret = $val;
+  }
+
+  /**
+   * function: sendNotification
+   * @param: $params - an associative array of parameters to send to the Notifo API.
+   * These can be any of the following:
+   * to, msg, label, title, uri
+   * See https://api.notifo.com/ for more information
+   */
+  function sendNotification($params) {
+    $validFields = array('to', 'msg', 'label', 'title', 'uri');
+    $params = array_intersect_key($params, array_flip($validFields));
+    return $this->sendRequest('send_notification', 'POST', $params);
+  } /* end function sendNotification */
+
+  function sendMessage($params) {
+    $validFields = array('to','msg');
+    $params = array_intersect_key($params, array_flip($validFields));
+    return $this->sendRequest('send_message', 'POST', $params);
+  }
+
+  /**
+   * function: subscribeUser
+   * @param: $username - the username to subscribe to your Notifo service
+   * See https://api.notifo.com/ for more information
+   */
+  function subscribeUser($username) {
+    return $this->sendRequest('subscribe_user', 'POST', array('username' => $username));
+  } /* end function subscribeUser */
+
+
+  /**
+   * helper function to send the requests
+   * @param $method - name of remote method to call
+   * @param $type - HTTP method (GET, POST, etc)
+   * @param $data - array with arguments for remote method
+   */
+  function sendRequest($method, $type, $data) {
+
+    $url = self::API_ROOT.self::API_VER.'/'.$method;
+
+    $ch = curl_init();
+    curl_setopt($ch, CURLOPT_URL, $url);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+    if ($type == "POST") {
+      curl_setopt($ch, CURLOPT_POST, true);
+      curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
+    }
+    curl_setopt($ch, CURLOPT_USERPWD, $this->apiUsername.':'.$this->apiSecret);
+    curl_setopt($ch, CURLOPT_HEADER, false);
+
+    /*
+     * if you are on a shared host or do not have access to install
+     * the root CA certificates on your server, uncomment the next
+     * two lines or the curl_exec call may fail with null
+     */
+    //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
+    //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
+
+    $result = curl_exec($ch);
+    $result = json_decode($result, true);
+    return $result;
+  } /* end function sendRequest */
+
+// for backwards compatibility
+  function send_notification($params) { return json_encode($this->sendNotification($params)); }
+  function send_message($params) { return json_encode($this->sendMessage($params)); }
+  function subscribe_user($username) { return json_encode($this->subscribeUser($username)); }
+  function send_request($url, $type, $data) { return json_encode($this->sendRequest($method, $type, $data)); }
+
+} /* end class Notifo_API */
