June 2013

Volume 28 Number 6

Microsoft Office - Exploring the JavaScript API for Office: A Sample Mail App

By Angela Chu-Hatoun | June 2013 | Get the Code

This article accompanies the MSDN Magazine article, “Exploring the JavaScript API for Office: Mail Apps” (msdn.microsoft.com/magazine/dn201750). Here, I’ll walk through building a sample Group IM mail app using the techniques explained in that article.

Start Group IM from a Message

The Group IM mail app lets you conveniently start a group instant messaging session with the sender, recipients or any persons whose e-mail addresses are included in the body of a selected message, without leaving Outlook or Outlook Web App. Figure 1 shows the user Belinda having selected the recipients Jeff and Ben and being ready to start an IM session using the Group IM mail app. The app pane includes the SMTP addresses of all the recipients of the current message in the reading pane, as well as any SMTP addresses (for Vernon, Sam and Roman) in the message body for Belinda to start an IM session with.

Selecting Message Recipients in the Group IM Mail App to Start a Group Chat Session
Figure 1 Selecting Message Recipients in the Group IM Mail App to Start a Group Chat Session

The Group IM mail app assumes Lync as the IM client, which supports the Session Initiation Protocol (SIP) and a command-line approach to start IM. You can modify the checkAddress function in the JavaScript file of this mail app, InstantMessage.js, shown in Figure 2 (you can download the complete set of source files for the mail app at code.msdn.microsoft.com/Mail-apps-for-Outlook-2b20fc16), to customize the app for a different IM client.

Figure 2 The InstantMessage.js JavaScript File

var _Item;
var itemEntities;
var myEntities = new Array();
var uniqueNumInRecipientsAndBody=0;
Office.initialize = function () {
  _Item = Office.context.mailbox.item;
  itemEntities = _Item.getEntities();
  $(document).ready(function () {
   initIM();
  }); 
}
var checkedItems;
checkedItems = "";
// This function verifies if the user has checked any of the
// checkboxes for the SMTP addresses, and if so, constructs a hyperlink
// for starting an IM session.
function checkAddress(emailForm)
{
  var anychecked;
  anychecked = 0;
  checkedItems = "im:";
  // See if the e-mail sender address is checked.
  if (emailForm.checkbox0.checked == true) {
    checkedItems += "<sip:" + _Item.sender.emailAddress + ">";
    anychecked = 1;
  }
  for (var i=1; i<=uniqueNumInRecipientsAndBody; i++) {
    var tempy;
    // Determine if each checkbox is checked.
    // Each checkbox name is a variable depending on value of i.
    tempy = "checkbox" + i;
    // Use JavaScript square bracket notation instead of dot notation to access
    // emailForm.tempy.checked, because tempy is a variable.
    tempy = emailForm[tempy]["checked"];
    if (tempy)  {
      // If the checkbox is checked, construct an SIP address
      // for that e-mail address.
      checkedItems += "<sip:" + myEntities[i-1] + ">";
      anychecked = 1; 
    }
  }
  // Clear the variable if none of the checkboxes is checked.
  // UI phrase remains not a hyperlink.
  if (anychecked == 0) {
    checkedItems = "";
    document.getElementById("mySpan").innerHTML = "Start an instant message conversation";
  } 
  else {
    // If one or more checkboxes are checked, then turn the UI phrase into a hyperlink.
    document.getElementById("mySpan").innerHTML =
      "<A HREF = \"" + checkedItems + "\">Start an IM conversation</A>";
  }    
}
// This function counts the unique number of e-mail addresses.
// The first such count number of array cells in myEntities
// contain the unique e-mail addresses.
function makeMyAddressesUnique (addressArray)
{
  var emailAddress;
  var j=0;
  for (var i in addressArray) {
    emailAddress = addressArray[i];
    // Check if e-mail address is not the same as the sender's address
    // or the current user's address, is new and
    // has not occured in the first i number of cells in addressArray.
    if ((emailAddress.toLowerCase() !== _Item.sender.emailAddress.toLowerCase()) &&
      (emailAddress.toLowerCase() !==  
      Office.context.mailbox.userProfile.emailAddress.toLowerCase()) &&
      (emailAddrIsNew (i, emailAddress, addressArray))) {
      myEntities[j] = emailAddress.toLowerCase();
      j++;
    }
    // Otherwise e-mail address already occurred in sender or addressArray, so ignore it.
    // The next new e-mail address will overwrite cell j in myEntities.
  }
    // Tallied the number of unique addresses in the body.
    uniqueNumInRecipientsAndBody = j;   
}
function emailAddrIsNew (index, address, array) {
  var counter = 0;
  while (counter < index) {
    if (address.toLowerCase() === array[counter].toLowerCase()) {
      return (false);
    }
    counter++;
  }
  return (true);
}
function initIM()
{
  var myHTMLString;
  var myCell;
  var tempEntities;
  var toRecipients;
  var ccRecipients;
  var recipientsAddresses = new Array ();
  var recipientsAndBodyAddresses = new Array();
  toRecipients = _Item.to;
  ccRecipients = _Item.cc;
  myHTMLString = "";
  // Assign first the To recipients addresses, followed by
  // the cc recipients addresses.
  for (var i=0; i<toRecipients.length; i++) {
    recipientsAddresses[i] = toRecipients[i].emailAddress;
  }
  for (var i=0; i<ccRecipients.length; i++) {
    recipientsAddresses[i+toRecipients.length] = ccRecipients[i].emailAddress;
  }
  recipientsAndBodyAddresses = recipientsAddresses.concat(itemEntities.emailAddresses);
  makeMyAddressesUnique (recipientsAndBodyAddresses);
  myCell = document.getElementById('extensionspace');
  myHTMLString += "<form><span id=\"mySpan\">Start an instant message conversation</span>" +
    " with the following persons:<BR>";
  myHTMLString += "<input type=checkbox name='checkbox0" + "' value='" +
    _Item.sender.emailAddress + "' onClick='checkAddress(this.form)' />" +
    _Item.sender.emailAddress + "<br>";
  for (var i=0; i<uniqueNumInRecipientsAndBody; i++) {
    myHTMLString += "<input type=checkbox name='checkbox" + (i+1) + "' value='" +
      myEntities[i] + "' onClick='checkAddress(this.form)' />" +
      myEntities[i] + "<br>";
    }
    myCell.innerHTML = myHTMLString + "</form>";
}

The Scenario

While reading an e-mail, you want to move forward a discussion by instant-messaging the recipients of the message, or with persons whose e-mail addresses are included in the body of the message. You can choose the Group IM mail app, select in the app pane recipients or e-mail addresses from the message and, without leaving Outlook, start a group IM session in your IM client.

This scenario assumes the use of Outlook 2013 (or a later version) and Exchange Online or Exchange Server 2013 (or a later version). The participants and their SMTP addresses should also be supported by the IM client.

Trying the Mail App

Follow the instructions in the file, “Readme for Group IM mail app,” with the accompanying code download (code.msdn.microsoft.com/Mail-apps-for-Outlook-2b20fc16), to download and install the mail app for your mailbox. Outlook activates this mail app for any e-mail message in your inbox, so you can try this mail app with any message you’re viewing in the reading pane or mail inspector. Alternatively, for a more controlled test environment, you can create a special test e-mail message, include yourself and a few other recipients, specify a few other SMTP addresses in the message body, and send the message.

To test, open the special test message in the reading pane and choose the “Group IM” app button. The app pane lists the e-mail addresses of the recipients and the SMTP addresses in the message body. In the app pane, choose two or more e-mail addresses and choose the link “Start an IM conversation.” Your IM client opens an IM window for you to start the group chat session.

The rest of this article describes the XML manifest, HTML and JavaScript files for the Group IM mail app. Along the way, I’ll highlight points of interest.

The XML Manifest

Each mail app must define a manifest that follows the apps for Office XML schema as documented in the MSDN Library article, **“**Schema map (apps for Office),” at bit.ly/13bPpWH. A mail app manifest defines the following metadata for the app:

  • Identity
  • Locale support
  • Capability required of the host applications
  • Form factors
  • Corresponding HTML file for each form factor (if needed)
  • Display requirements
  • Necessary permissions
  • Activation rules

This section highlights specific points of interest in the manifest, Lync IM.xml, which characterize the Group IM mail app. For a complete listing of the manifest, see Figure 3 (you can download the complete set of source files for the mail app at (code.msdn.microsoft.com/Mail-apps-for-Outlook-2b20fc16).

Figure 3 App XML Manifest File

<?xml version="1.0" encoding="utf-8"?>
<OfficeApp xmlns="https://schemas.microsoft.com/office/appforoffice/1.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:type="MailApp">
  <Id>0DA74E27-C945-47A0-9857-64268DEF6542</Id>
  <Version>1.0</Version>
  <ProviderName>Microsoft</ProviderName>
  <DefaultLocale>EN-US</DefaultLocale>
  <DisplayName DefaultValue="Group IM">
    <Override Locale="FR-FR" Value="Message instantané"/>
  </DisplayName>
  <Description DefaultValue="Start a group instant message session using Lync.">
    <Override Locale="FR-FR" Value="Démarrer un message instantané appel directement à partir de Outlook ou Outlook Web App à l'aide de Lync."/>
  </Description>
  <IconUrl DefaultValue="https://exchangemoe.redmond.corp.microsoft.com/ext/ach/GroupIM/mslync-logo_small.png"/>
  <Capabilities>
    <Capability Name="Mailbox"/>
  </Capabilities>
  <DesktopSettings>
    <!-- Change the following line to specify the web server -->
    <!-- that hosts the HTML file. -->
    <SourceLocation DefaultValue=
      "https://exchangemoe.redmond.corp.microsoft.com/ext/ach/GroupIM/InstantMessage.htm"/>
    <RequestedHeight>216</RequestedHeight>
  </DesktopSettings>
  <TabletSettings>
    <!-- Change the following line to specify the web server -->
    <!-- that hosts the HTML file. -->
    <SourceLocation DefaultValue=
      "https://exchangemoe.redmond.corp.microsoft.com/ext/ach/GroupIM/InstantMessage.htm"/>
    <RequestedHeight>180</RequestedHeight>
  </TabletSettings>
  <Permissions>ReadItem</Permissions>
  <Rule xsi:type="ItemIs" ItemType="Message"/>
</OfficeApp>

The Root Element OfficeApp specifies the namespace and the app type MailApp, and is the root element that encloses child elements applicable to mail apps in a sequential order. MailApp extends OfficeApp, and its child elements define further metadata for mail apps:

<OfficeApp xmlns="https://schemas.microsoft.com/office/appforoffice/1.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:type="MailApp">

A Unique Identifier The Id element specifies a universally unique identifier (UUID) that differentiates this app from other apps for Office for the host application:

<Id>0DA74E27-C945-47A0-9857-64268DEF6542</Id>

An App Label The DisplayName element identifies the app as “Group IM” on the app bar. Outlook activates this app by displaying “Group IM” on the app bar, if the rules specified in the manifest are met with respect to the selected item (see the “Activation Rules” section):

<DisplayName DefaultValue="Group IM">
  <Override Locale="FR-FR" Value="Message instantané"/>
</DisplayName>

Locale Support The DefaultLocale element specifies the culture name of the locale, in this case EN-US, of the UI strings in the app manifest. You can use the Override child element to support locale-specific display names (such as the name “Message instantané” for the FR-FR locale in the previous example), descriptions, icon images or source files:

<DefaultLocale>EN-US</DefaultLocale>

A Verbose Description The Description element typically specifies the purpose of the app. The DefaultValue attribute corresponds to the locale specified by the DefaultLocale element. You can use an Override child element to support a description for a different locale, such as FR-FR:

<Description DefaultValue="Start a group instant message session using Lync.">
  <Override Locale="FR-FR"
    Value="Démarrer un message instantané appel directement
    à partir de Outlook ou Outlook Web App à l'aide de Lync."/>
</Description>

Capabilities The Capabilities and Capability elements specify the functionality your app works with—in this case, the Mailbox capability. Instead of explicitly specifying the host applications your app requires, you use these elements to tell the apps for Office platform how to match eligible host applications that can support your app. An application that supports the Mailbox capability can become a host for this app:

<Capabilities>
  <Capability Name="Mailbox"/>
</Capabilities>

Because the JavaScript API for Office is an integrated API shared by all apps for Office and supporting host applications, the support for certain objects or members differs from host to host. More of such cases occur with task pane apps (for example, Bindings.addFromPromptAsync). An example for mail apps is the Diagnostics.OWAView property, which is intended for debugging in Outlook Web App but not Outlook. In such cases, you should ensure that the API is defined before using it.

Device-Dependent Source File and Display The DesktopSettings and TabletSettings elements specify that this app can run on the desktop and tablet form factors. You can use the SourceLocation and RequestedHeight elements to specify the same or device-dependent HTML source files and display height (in pixels) for the app. The Group IM mail app uses the same HTML source file for the desktop and tablet form factors, and it specifies a taller app pane for the desktop than the tablet.

This is the URL for the HTML file:

https://webserver/GroupIM/InstantMessage.htm

Before trying the Group IM app, you should replace the URL for the HTML file with the actual location of the HTML file in your configuration:

<DesktopSettings>
  <!-- Change the following line to specify the Web server -->
  <!-- that hosts the HTML file. -->
  <SourceLocation DefaultValue="https://webserver/GroupIM/InstantMessage.htm"/>
  <RequestedHeight>216</RequestedHeight>
</DesktopSettings>
<TabletSettings>
  <!-- Change the following line to specify the Web server -->
  <!-- that hosts the HTML file. -->
  <SourceLocation DefaultValue="https://webserver/GroupIM/InstantMessage.htm"/>
  <RequestedHeight>180</RequestedHeight>
</TabletSettings>

Permission The Permissions element specifies the level of permission that this app requires. In this case, the Group IM mail app requires read item permission because the app accesses entities (SMTP addresses) that Exchange extracts from the message subject and body:

<Permissions>ReadItem</Permissions>

Activation Rules This app specifies an ItemIs rule with Message as the item type. This means Outlook will display Group IM in the app bar whenever the user views a message in the reading pane or inspector:

<Rule xsi:type="ItemIs" ItemType="Message"/>

Note that there are certain types of messages that don’t support mail apps. See the “Items supporting activation” section (bit.ly/11n0hNE) of the MSDN Library article, “Defining rules to show a mail app in Outlook 2013,” for more information.

HTML Implementation

The HTML file, InstantMessage.htm, specifies the UI of the app as displayed in the app pane. This section highlights a few points of interest. For a complete listing of InstantMessage.htm, see Figure 4 (you can download the complete set of source files for the mail app from code.msdn.microsoft.com/Mail-apps-for-Outlook-2b20fc16).

Figure 4 The InstantMessage.htm File

<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml" >
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<style type="text/css">
  .title{
    font-family: arial, sans-serif;
    color: blue;
    font-size: 12pt;
    text-decoration:none;
    font-weight:bold;
  }
  .property{
    font-family:Segoe UI;
    color: black;
    font-size: 10pt;
    text-decoration:none;
  }
  .value{
    font-family:Segoe UI;
    color: gray;
    font-size:  10pt;
    text-decoration:none;
  }
  .valuesmall{
    font-family: Segoe UI;
    color: gray;
    font-size:  8pt;
    text-decoration:none;
  }
</style>
  <title>Send Instant Messages with Lync</title>
  <script type="text/javascript"
    src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"></script>
  <script type="text/javascript"
    src="https://appsforoffice.microsoft.com/lib/1.0/hosted/office.js"></script>
  <script type="text/javascript" src="InstantMessage.js"></script>
</head>
<body>
  <img src='mslync-logo.png' alt='Microsoft Lync'/>
  <div id="extensionspace" style="font-family: 'Segoe UI'; font-size: 10pt"> </div>
</body>
</html>

Using the Highest Available Internet Explorer Mode Apps for Office require a minimum of Internet Explorer 9 on the client computer. Use the following meta tag to allow your app to use the highest Internet Explorer mode available on the computer, to provide the best experience the user can get:

<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml" >
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">

Note: Always place the meta element as a child element of the head element, before all other elements except for title and other meta elements.

Specifying a CSS for the App The Group IM mail app specifies a CSS inline in the HTML file to control the visual design and layout of the app, as shown in Figure 5.

Figure 5 Specifying a CSS

<style type="text/css">
  .title{
    font-family: arial, sans-serif;
    color: blue;
    font-size: 12pt;
    text-decoration:none;
    font-weight:bold;
  }
  .property{
    font-family:Segoe UI;
    color: black;
    font-size: 10pt;
    text-decoration:none;
  }
  .value{
    font-family:Segoe UI;
    color: gray;
    font-size:  10pt;
    text-decoration:none;
  }
  .valuesmall{
    font-family: Segoe UI;
    color: gray;
    font-size:  8pt;
    text-decoration:none;
  }
</style>

For more guidelines, see the “Style guidelines for apps for Office” section (bit.ly/XEwfED) of the MSDN Library article, “Apps for Office UX design guidelines.”

Including the JavaScript API for Office Library The JavaScript API for Office, office.js, is provided in a content delivery network (CDN) location. Always use the following statement to reference office.js from that location:

<script type="text/javascript"
  src="https://appsforoffice.microsoft.com/lib/1.0/hosted/office.js"></script>

This mail app uses similar script elements to include other JavaScript library files, including its own aforementioned JavaScript file, InstantMessage.js.

JavaScript Implementation

As seen in the previous section that describes the activation rule for this mail app, this app is available in the app bar whenever the user views a message in the reading pane or inspector. If the user chooses the app, the JavaScript file (InstantMessage.js) displays the recipients and any e-mail addresses included in the message body, gets any choices from the user and starts a group IM session with the selected people.

Rather than walking through how InstantMessage.js displays e-mail addresses and gets the user’s choices for IM, the rest of this section illustrates how this mail app uses the features listed in the “Fundamental Features of the JavaScript API for Office” section of the accompanying MSDN Magazine article (msdn.microsoft.com/en-us/magazine/dn201750).

Synchronizing to the Initialize and DOM-Loaded Events Every app for Office must handle the Office.initialize event. As shown in the following initialize event handler, as soon as the apps for Office runtime is ready, this mail app gets the current message selected by the user and all the well-known entities that exist in the message:

Office.initialize = function () {
  _Item = Office.context.mailbox.item;
  itemEntities = _Item.getEntities();
  $(document).ready(function () {
   initIM();
  }); 
}

The app holds off until the DOM is loaded, when it then calls the initIM function to proceed with displaying the app UI with e-mail addresses.

Accessing Message Properties sender, to and cc This mail app uses the sender, to and cc properties available on the message object to let the user pick one or more of the message sender or recipients. Each of these properties returns one or more EmailAddressDetails objects, each of which maps to a person and includes the person’s SMTP address.

Figure 6 shows the part of the initIM function that gets the e-mail address details for the to and cc recipients.

Figure 6 Getting E-Mail Address Details

function initIM()
{
  var myHTMLString;
  var myCell;
  var tempEntities;
  var toRecipients;
  var ccRecipients;
  var recipientsAddresses = new Array ();
  var recipientsAndBodyAddresses = new Array();
  toRecipients = _Item.to;
  ccRecipients = _Item.cc;
  myHTMLString = "";
  // Assign first the To recipients addresses, followed by
  // the cc recipients addresses.
  for (var i=0; i<toRecipients.length; i++) {
    recipientsAddresses[i] = toRecipients[i].emailAddress;
  }
  for (var i=0; i<ccRecipients.length; i++) {
    recipientsAddresses[i+toRecipients.length] = 
      ccRecipients[i].emailAddress;
  }
...

The following code snippet shows the part of the initIM function that accesses the message sender address and displays it in the list of choices on the app pane:

myHTMLString +=
  "<form><span id=\"mySpan\">Start an instant message conversation</span>" +
  " with the following persons:<BR>";
myHTMLString += "<input type=checkbox name='checkbox0" + 
  "' value='" +
  _Item.sender.emailAddress + 
  "' onClick='checkAddress(this.form)' />" +
  _Item.sender.emailAddress + "<br>";

Accessing SMTP Addresses in the Message Body as Entities The following code snippet shows the part of the initialize function that gets the full set of well-known entities in the message subject and body:

Office.initialize = function () {
  _Item = Office.context.mailbox.item;
  itemEntities = _Item.getEntities();
...

Note that the getEntities function returns a full set of well-known entities—including any SMTP addresses—that exist in the subject or body of that message. itemEntities.emailAddresses returns only an array of strings that Exchange recognizes as SMTP addresses. The following code snippet shows how the initIM function combines the set of recipient e-mail addresses with any e-mail addresses that exist in the message subject or body, and then calls the makeMyAddressesUnique function to exclude any equivalent SMTP addresses to provide a list of unique choices for the user later on:

recipientsAndBodyAddresses =
  recipientsAddresses.concat(itemEntities.emailAddresses);
makeMyAddressesUnique (recipientsAndBodyAddresses);

Accessing the User Profile to Get User’s Address In order to avoid offering the user’s own SMTP address as a choice for the IM session, the makeMyAddressesUnique function compares e-mail addresses with the user’s address stored in the UserProfile.emailAddress property. Figure 7 shows the code.

Figure 7 Comparing E-Mail Addresses with the User’s Address

// This function counts the unique number of e-mail addresses.
// The first such count number of array cells in
 // myEntities contains the unique e-mail addresses.
function makeMyAddressesUnique (addressArray)
{
  var emailAddress;
  var j=0;
  for (var i in addressArray) {
    emailAddress = addressArray[i];
    // Check if e-mail address is not the same as the sender's address
    // or the current user's address, is new, and
    // has not occurred in the first i number of cells in addressArray.
    if ((emailAddress.toLowerCase() !==
      _Item.sender.emailAddress.toLowerCase()) &&
        (emailAddress.toLowerCase() !==
        Office.context.mailbox.userProfile.emailAddress.toLowerCase()) &&
        (emailAddrIsNew (i, emailAddress, addressArray))) {
          myEntities[j] = emailAddress.toLowerCase();
          j++;
    }
    // Otherwise e-mail address occurred in
    // sender or addressArray already, ignore it.
    // The next new e-mail address will overwrite cell j in myEntities.
  }

IM Client Dependencies Note that this app assumes the user has set up an IM client that supports the IM and SIP protocols and uses the following format to start IM with the specified SMTP addresses:

im:<sip:user1@host><sip:user2@host>

As mentioned, an example of such an IM client is Lync. On Lync, the previous command opens an IM window for the user and specified SMTP addresses if the user has already signed in to Lync or has set up Lync to automatically sign in. Otherwise, the command opens the sign-in window.

Alternatively, you can modify the checkAddress function in this example to support a different IM client and build the appropriate command for that client to start group IM.

For more information about the support for Lync, see the MSDN Library article, “Starting Lync from Another Application” (bit.ly/ZvbTvc).

Alternative Means to Activate

Notice that my implementation uses only one activation rule (the selected item being a message) and the JavaScript API (the Message.getEntities method and Entities.emailAddresses property) to get any SMTP addresses in the message body. I’ll show an alternative implementation to illustrate an example of a regular expression activation rule and how to get regular expression matches in the app.

In the app manifest, combine the existing ItemIs rule using the Mode=And attribute, with a second rule that the item body must contain one or more e-mail addresses, as filtered by the regular expression named reg1:

<Rule xsi:type="RuleCollection" Mode="And">
  <Rule xsi:type="ItemIs" ItemType="Message"/>
  <Rule xsi:type="ItemHasRegularExpressionMatch" RegExName="reg1"
    RegExValue="[-\w.]+@([A-z0-9][-A-z0-9]+\.)+[A-z]{2,3}"
    PropertyName="BodyAsPlaintext"/>
</Rule>

Then, in the JavaScript file, instead of accessing any well-known entities that Exchange has extracted from the selected message, like this:

itemEntities = _Item.getEntities();

You can use the Message.getRegExMatches method to get any e-mail addresses that match reg1:

myEntities = _Item.getRegExMatches();

Modify the makeMyEntitiesUnique function to handle e-mail addresses stored in the myEntities.reg1 array.

Of the two approaches, using well-known entities is preferred to avoid any extra overhead in evaluating a regular expression while trying to activate the mail app. Regardless of the type of activation rules specified in an app manifest, Exchange always extracts any well-known entities from the subject or body of the selected item, so there’s no additional overhead incurred by getting any e-mail addresses in the message body as entities. On the other hand, the overhead of evaluating regular expressions in an activation rule can be significant if the e-mail body is relatively long and contains many e-mail addresses. To provide a satisfactory experience for mail app users, there are certain thresholds you should be aware of if you use regular expressions. See the MSDN Library article, “Limits for activation and data in mail apps for Outlook” (bit.ly/170WAQf), for details.


Angela Chu-Hatoun started as a software developer and switched to writing for her greater interest in explaining how software works. She has been a programmer writer in the Office Division for 12 years, and writes for developers about creating apps for Office and other solutions for Outlook. She enjoys reading about current affairs, gardening, travelling, food and fashion.

Thanks to the following technical experts for reviewing this article: Andrew Salamatov (Microsoft) and Tim Wan (Microsoft)

Tim Wan graduated from Caltech in 2003 and holds a degree in Engineering and Applied Sciences. For the past nine years he has been a software developer in Outlook. He worked extensively on the mail apps feature in Outlook 2013, as well as the Outlook Object Model in previous releases. He looks forward to bringing new features and improvements to customers worldwide.