Messaging API Guide

Overview

This article demonstrates the usage of Tizen Messaging (Email) API. It explains how to compose, send and save an email conversation. Also discusses about how to sync the folders to message store and to register for email message change notifications.

HTML

The html source comprises of three pages. The main page contains a list view with links to Compose, Inbox and Sync pages.

<ul data-role="listview">
  <li><a href="#msg-compose">Compose</a></li>
  <li><a href="#msg-recv">Inbox</a></li>
  <li><a href="#msg-sync">Sync</a></li>
</ul>

Compose page facilitates adding a sender mail id, subject and body of the mail conversation with option to send or save as a draft.

<div data-role="page" id="msg-compose" data-add-back-btn="true">
  <div data-role="header" data-position="fixed">
    <h1>Inbox</h1>
    <a data-role="button" onclick="saveMessage()">Save</a> <a
      data-role="button" onclick="sendMessage()">Send</a>
  </div>
  <div data-role="content">
    <h1>Compose</h1>
    <ul data-role="listview">
      <li><label for="new-mail">Email</label> <input type="mail"
        name="new-mail" style="color: black;" id="new-mail"
        value="raghu.kona@hotmail.com" /></li>
      <li><label for="msg-sub">Subject</label> <input type="text"
        style="color: black;" name="msg-sub" id="msg-sub"
        value="Test Subject" /></li>
      <li><label for="new-body">Body</label> <textarea cols="40"
          rows="8" name="new-body" id="new-body" style="height: 150px"></textarea>
      </li>
    </ul>
  </div>
  <div data-role="footer" data-position="fixed"></div>
</div>

Inbox displays list of messages with option to delete message and reload from message store.

Note: Currently messages are deleted only from the displayed list.

<div data-role="page" id="msg-recv" data-add-back-btn="true">
  <div data-role="header" data-position="fixed">
    <div data-role="button" class="naviframe-button" onclick="getEmailMessages()">Refresh</div>
    <h1>Inbox</h1>
  </div>
  <div data-role="content">
    <ul data-role="listview" id="message-list">
    </ul>
  </div>
  <div data-role="footer" data-position="fixed"></div>
</div>

Email Sync and Track page displays a list of folders from the message store. It provides option to start and stop syncing folders. It also provides an option to enable tracking change in messages.

<div data-role="page" id="msg-sync" data-add-back-btn="true">
  <div data-role="header" data-position="fixed">
    <h1>Email Sync & Track</h1>
  </div>
  <div data-role="content">
    <ul data-role="listview" id="email-folder-list">
    </ul>
  </div>
  <div data-role="footer" data-position="fixed">
    <div data-role="tabbar">
      <ul>
        <li><div id="sync-all" data-role="button">SyncAll</div></li>
        <li><div id="stop-sync" data-role="button">Stop</div></li>
        <li><div id="tracking" data-role="button">Track</div></li>
      </ul>
    </div>
  </div>
</div>

JavaScript

initEmailService()

In initEmailService(), you can initialize the email service calling tizen.messaging.getMessageServices(). The same method can be used to initialize SMS service, for which you may need to replace messaging.email with messaging.sms

function initEmailService() {

  function onEmailGetMessageServicesSuccess(services) {
    if(services.length == 0) {
      alert("No Email MessageServices found");
      tizen.application.exit();
      return;
    }

    gEmailService = services[0];
  }

  try {
    tizen.messaging.getMessageServices("messaging.email", onEmailGetMessageServicesSuccess);
  } catch (exc) {
    alert("getMessageServices exc: " + exc.name + ":" + exc.message);
  }
}

sendMessage()

The sendMessage() routine creates a new message with the data from html page. The sendMessage accepts a success and failure callback methods.

function sendMessage(){

  // Define the success callback.
  function messageSent(recipients) {
    alert("EMAIL sent successfully");
    console.log("The EMAIL has been sent");
    history.back();
  }

  // Define the error callback.
  function messageFailed(error) {
    alert("Sending Failed: " + error.message);
    console.log("The EMAIL could not be sent " + error.message);
  }

  var mailIds = new Array();
  mailIds[0] = $("#new-mail").val();
  var msg = new tizen.Message("messaging.email", {subject: $("#msg-sub").val(), plainBody: $("#new-body").val(),
    to: mailIds});  

  try{
    gEmailService.sendMessage(msg, messageSent, messageFailed);
  } catch (exc) {
    alert("sendMessage exc: " + exc.name + ":" + exc.message);
  }
}

saveMessage()

saveMessage() method facilitates saving the message as draft.

function saveMessage(){
  // Define the success callback.
  function messageSaved(recipients) {
    alert("EMAIL saved successfully");
    console.log("The EMAIL has been saved");
    history.back();
  }

  // Define the error callback.
  function messageFailed(error) {
    console.log("Unable to save: " + error.message);
    console.log("The EMAIL could not be saved " + error.message);
  }

  var msg = new tizen.Message("messaging.email", {subject: $("#msg-sub").val(), plainBody: $("#new-body").val(),
    to: $("#new-mail").val()});
  gEmailService.messageStorage.addDraftMessage(msg, messageSaved, messageFailed);
}

getEmailMessages()

getEmailMessages() facilitates querying the messages from message store. It uses gEmailService.messageStorage.findMessages() to query messages based on filter provided.

function getEmailMessages() {
  var filter = new tizen.AttributeFilter("from", "CONTAINS", "");

  gEmailService.messageStorage.findMessages(filter, onFindMessagesSuccess, onError);
}

The retrieved messages are displayed in a list view with an option to delete the email conversation.

function onFindMessagesSuccess(messages) {
  var str = "";

  gMessages = messages;

  for (var i = 0; i < messages.length; i++) {
//    console.log(i + ". ConvId = " + messages[i].id);
    str += makeListItem(i, messages[i].subject, messages[i].messageCount + " email(s)");
  }

  $("#message-list").html(str).trigger("create").listview("refresh");
}

function makeListItem(id, mainText, subText) {
  return '<li class="ui-li-has-multiline" data-id="'
  + id
  + '">'
  + mainText
  + '<div data-role="button" data-icon="delete" data-style="nobg"></div></li>';
}

function deleteConversation(id) {
  try {
    gEmailService.messageStorage.removeMessages([gMessages[id]], function() {
      gMessages.splice(id,1);
      /*
       * getEmailMessages();
       * removeMessages DB update tends to be delayed and this leads getEmailMessages
       * to retrieve wrong (Not updated) message list.
       * getEmailMessages() is replaced with following codes until this issue resolved.
       * The below code will refresh the list locally.
       */
      var str = "";
      for (var i = 0; i < gMessages.length; i++) {
        str += makeListItem(i, gMessages[i].subject, gMessages[i].messageCount + " email(s)");
      }
      $("#message-list").html(str).trigger("create").listview("refresh");
    }, function() {
      alert("Delete failed");
    });
  } catch (exc) {
    alert("removeMessages exc:" + exc.message);
  }
}

showEmailDetail()

showEmailDetail() provides a detailed view of the email conversation

function showEmailDetail() {
  function onEmailFindMessagesSuccess(messages) {
    if (messages.length == 0) {
      alert("The last email of the message not found");
      return;
    }

    var email = messages[0];

    $("#email-subject").html(email.subject);
    $("#email-from").html(email.from);

    try {
      console.log("email.hasAttachment:" + email.hasAttachment);
      if (email.hasAttachment) {
        gEmailService.loadMessageAttachment(email.attachments[0], function(attachment) {
          console.log("loadMessageAttachment success: filePath: " + attachment.filePath);
          $("#email-attachment").html(attachment.filePath);
        }, onError);
      } else {
        $("#email-attachment").html("None");
      }

      console.log("email.body.loaded:" + email.body.loaded);
      if (email.body.loaded) {
        console.log("email body already loaded");
        $("#email-plain-body").val(email.body.plainBody);
        $("#email-html-body").val(email.body.htmlBody);
      } else {
        console.log("email body about to load");
        gEmailService.loadMessageBody(email, function(message) {
          console.log("email body just loaded");
          $("#email-plain-body").val(message.body.plainBody);
          $("#email-html-body").val(message.body.htmlBody);
        }, onError);
      }
    } catch (exc){
      alert("showEmailDetail failed" + exc.message);
    }
  }

  console.log("lastMessageId = " + gMessages[gEmailId].id);
  gEmailService.messageStorage.findMessages(
      // FYI: "" + gMessages[gEmailId].lastMessageId to make value String type
      new tizen.AttributeFilter("id", "EXACTLY", "" + gMessages[gEmailId].id),
      onEmailFindMessagesSuccess,
      onError);
}

Sync

The method syncEmails() can be used to sync all folders with the server and syncFolder() for individual folders. stopSync() stops the sync process.

function syncFolder(id) {
  if (gSyncOpId) {
    alert("Other sync is in progress");
  } else {
    try {
      gSyncOpId = gEmailService.syncFolder(gFolders[id], function() {
        alert("Folder sync succeeded");
        gSyncOpId = null;
      }, function() {
        alert("Folder sync failed");
        gSyncOpId = null;
      }, 30);
      alert("Sync started for " + gFolders[id].name);
    } catch (exc) {
      alert("Folder sync failed: " + exc.message);
      gSyncOpId = null;
    }
  }
}

function syncEmails() {
  if (gSyncOpId) {
    alert("Other sync is in progress");
  } else {
    try {
      gSyncOpId = gEmailService.sync(function() {
        alert("Synchronization succeeded");
        gSyncOpId = null;
      }, function(err) {
        alert("Synchronization failed:" + err.message);
        gSyncOpId = null;
      });
      alert("Sync all started");
    } catch (exc) {
      alert("Sync exc: " + exc.code + ":" + exc.message);
      gSyncOpId = null;
    }
  }
}

function stopSync() {
  if (gSyncOpId) {
    gEmailService.stopSync(gSyncOpId);
    alert("Sync stopped");
    gSyncOpId = null;
  }
}

Notifications on Message Store changes

You can register for notications for changes in the message store, so that you can get notified when there is a change in email conversation or folder details. gEmailService.messageStorage.addMessagesChangeListener() can be used to register for these notifications.

function registerListeners() {
  var messagesChangeCB = {
      messagesadded : function(messages) {
        alert("Tracking message :" + messages.length + " message(s) added");
      },
      messagesupdated : function(messages) {
        alert("Tracking message :" + messages.length + " message(s) updated");
      },
      messagesremoved : function(messages) {
        alert("Tracking message :" + messages.length + " message(s) removed");
      }
  },
  foldersChangeCB = {
      foldersadded : function(folders) {
        alert("Tracking message :" + folders.length + " folders(s) added");
      },
      foldersupdated : function(folders) {
        alert("Tracking message :" + folders.length + " folders(s) updated");
      },
      foldersremoved : function(folders) {
        alert("Tracking message :" + folders.length + " folders(s) removed");
      }
  };

  try {
    gMessagesListenerId = gEmailService.messageStorage.addMessagesChangeListener(messagesChangeCB);
    console.log("Listening for Messages Change started");

    gFoldersListenerId = gEmailService.messageStorage.addFoldersChangeListener(foldersChangeCB);
    console.log("Listening for Folders Change started");

    $("#tracking").unbind("vclick", registerListeners);
    $("#tracking").bind("vclick", unregisterListeners);
    alert("Tracking started");
  } catch (exc) {
    alert("addChangeListeners error:" + exc.message);
  }
}

function unregisterListeners() {
  gEmailService.messageStorage.removeChangeListener(gMessagesListenerId);
  gEmailService.messageStorage.removeChangeListener(gFoldersListenerId);

  $("#tracking").unbind("vclick", unregisterListeners);
  $("#tracking").bind("vclick", registerListeners);
  alert("Tracking stopped");
}

Message

 

Compose Message

File attachments: