Outlook Email Reporting Sample

I just posted a new Outlook sample on GitHub. I have created something very similar to this sample for a couple of customers now and have been using this as a template. What this sample does is place a button on the Ribbon for users to report suspicious email to the administrator. The user will get the option to select why they think it is suspicious as well as provide a comment. When they click Send, it will email the administrator. The email address which receives this notification is configured in the URL for the add-in page via the manifest XML.

Anyway, I wanted to share this basic sample with the community so others can use this to quickly implement similar solutions in their environment.

All the details for configuring the add-in are in the README.md. Here is the link the new sample: https://github.com/davecra/Outlook.ReportAddin. I also created this in VS Code.

Please let me know if you have any questions or suggestions for other samples you would like to see.

The Most Anticipated OfficeJS Feature is Here

If you are an Outlook Web Access developer trying to create an add-in to help mitigate the accidental release of Personally Identifiable Information (PII), you have probably been looking for a way to stop the send of the message if it does not pass a test. The functionality has not been a part of the new OfficeJS object model, until now. However, there are several things you need to know in order to set this up. Here are the general steps:

  • Use PowerShell to create a policy to enable to the OWAOnSendAddinAllUserPolicy
  • Use PowerShell to set that policy for a mailbox or group of mailboxes
  • Update your manifest file to enable the functionality and specify the event function you want to call when the user presses send
  • Write your JavaScript to properly handle the event.

NOTE: There are several caveats to this functionality. These are: you CANNOT publish an app using this functionality to the Store; this will not work on Shared mailboxes; and this will not work from any other clients, just Outlook Web Access (for now).

Create the OWAOnSendAddinAllUserPolicy

To set the policy for a user account, you need to create a policy with it enabled (or edit the default or specific policy you have applied). First, you need these steps to connect to the Exchange server as an administrator and establish a session:

Next, you need to then use PowerShell to set/configure the policy and then apply it to an account.

Once you have done, this you can then start writing the functionality into your code.

Update the Manifest file

The manifest will require a new and additional version overrides node. You will then use the FunctionFile to define an Extension point in your code. This will be a function you call. If you are not familiar with Function Files, here is a link to how to create one:

Here is what you manifest will need to look like:

[code lang=”xml” collapse=”true” title=”click to expand if the embedding below is not visible.”]
<VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides&quot; xsi:type="VersionOverridesV1_0">
<!– On Send requires VersionOverridesV1_1 –>
<!– https://dev.office.com/docs/add-ins/outlook/outlook-on-send-addins –>
<VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides/1.1&quot; xsi:type="VersionOverridesV1_1">
<Requirements>
<bt:Sets DefaultMinVersion="1.5">
<bt:Set Name="Mailbox" />
</bt:Sets>
</Requirements>
<Hosts>
<Host xsi:type="MailHost">
<DesktopFormFactor>
<!– Location of the Functions that UI-less buttons can trigger (ExecuteFunction Actions). –>
<FunctionFile resid="functionFile" />
<ExtensionPoint xsi:type="Events">
<Event Type="ItemSend" FunctionExecution="synchronous" FunctionName="onSendEvent" />
</ExtensionPoint>

</DesktopFormFactor>
</Host>
</Hosts>

</VersionOverrides>
</VersionOverrides>
[/code]

<VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides" xsi:type="VersionOverridesV1_0">
<!-- On Send requires VersionOverridesV1_1 -->
<!-- https://dev.office.com/docs/add-ins/outlook/outlook-on-send-addins -->
<VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides/1.1" xsi:type="VersionOverridesV1_1">
<Requirements>
<bt:Sets DefaultMinVersion="1.5">
<bt:Set Name="Mailbox" />
</bt:Sets>
</Requirements>
<Hosts>
<Host xsi:type="MailHost">
<DesktopFormFactor>
<!-- Location of the Functions that UI-less buttons can trigger (ExecuteFunction Actions). -->
<FunctionFile resid="functionFile" />
<ExtensionPoint xsi:type="Events">
<Event Type="ItemSend" FunctionExecution="synchronous" FunctionName="onSendEvent" />
</ExtensionPoint>
...
</DesktopFormFactor>
</Host>
</Hosts>
...
</VersionOverrides>
</VersionOverrides>
view raw OnSend.xml hosted with ❤ by GitHub

The important thing to note here is that your FunctionFile function for OnSend will need to be defined OUTSIDE the scope of the Office.initialize() function. It needs to be GLOBAL. So you simply place it in the root of your functionFile.js. However, you still need to define an Office.initialize() function in your FunctionFile and in there you probably will want to grab a reference to the mailbox, mailbox.item and the user maybe and place them in a global var as well. This way you will have access to those things in the Event method to be able to make call like body.getAsync() or subject.getAsync(), etc.

Here is how you define it:

[code lang=”javascript” collapse=”true” title=”click to expand if the embedding below is not visible.”]
var sendEvent;
function onSendEvent(event) {
///
<summary>
/// OUTLOOK SEND EVENT
/// Entry point for Message onSend event
/// Per example: https://github.com/OfficeDev/Outlook-Add-in-On-Send/tree/master/outlook-add-in-on-send
/// Setup mailbox policy first:
/// 1) Get sessions and commands: https://technet.microsoft.com/en-us/library/jj984289(v=exchg.160).aspx
/// 2) Set policy and more info: https://dev.office.com/docs/add-ins/outlook/outlook-on-send-addins
/// </summary>

/// <param name="event" type="object">ItemSend event is automatically passed by on send code to the function
// specified in the manifest.</param>
sendEvent = event;

// do your work here… since it will likely be ASYNC, you will want to
// set the event handler to a global. When you are done, you will issue
// > sendEvent.completed({ allowEvent: true }); // to send
// > sendEvent.completed({ allowEvent: false }); // to block
doSomething.Async(values, asyncComplete);
}
[/code]

var sendEvent;
function onSendEvent(event) {
/// <summary>
/// OUTLOOK SEND EVENT
/// Entry point for Message onSend event
/// Per example: https://github.com/OfficeDev/Outlook-Add-in-On-Send/tree/master/outlook-add-in-on-send
/// Setup mailbox policy first:
/// 1) Get sessions and commands: https://technet.microsoft.com/en-us/library/jj984289(v=exchg.160).aspx
/// 2) Set policy and more info: https://dev.office.com/docs/add-ins/outlook/outlook-on-send-addins
/// </summary>
/// <param name="event" type="object">ItemSend event is automatically passed by on send code to the function
// specified in the manifest.</param>
sendEvent = event;
// do your work here... since it will likely be ASYNC, you will want to
// set the event handler to a global. When you are done, you will issue
// > sendEvent.completed({ allowEvent: true }); // to send
// > sendEvent.completed({ allowEvent: false }); // to block
doSomething.Async(values, asyncComplete);
}
view raw OnSend.js hosted with ❤ by GitHub

Then later in your code, you can either Cancel the send or allow the send event to occur, like this:

[code lang=”javascript” collapse=”true” title=”click to expand if the embedding below is not visible.”]
function asyncCompelte() {
// procress the result
if(isOkToSend() == true) {
sendEvent.completed({ allowEvent: true }); // send it
} else {
sendEvent.completed({ allowEvent: false }); // block it
}
}
[/code]

function asyncCompelte() {
// procress the result
if(isOkToSend() == true) {
sendEvent.completed({ allowEvent: true }); // send it
} else {
sendEvent.completed({ allowEvent: false }); // block it
}
}

Once you have set the policy on the mailbox, modified your manifest and then added the event function to your FunctionFile, you are good to go. I will be working on a simple demo to place on GitHub in coming weeks and will post an update when complete.

UPDATE: Here it my post with the demo:
Outlook OnSend and Dialog Sample

But I wanted to get this information out here for now. In the meantime, you can use this demo as an example of how to implement this end-to-end:

Determine Compose Message Type

In working with a customer on a new Mail App for OWA, they had a requirement to determine if the mail item being composed is a Reply or Forward or new mail message. Determining is New or Reply/Forward is easy. But getting the Reply/Forward determination is unfortunately… too easy. wlEmoticon-disappointedsmile.png Meaning the ONLY way I have been able to determine this is to look at the subject and see if there is a RE: or FW: in there. It’s a little ugly, but this is how it is. And worse – it is language dependent. If you need to support multiple languages you will have to determine the language and then make this function – much larger. So here is the English only version:

[code lang=”javascript” collapse=”true” title=”click to expand if the github.com embedding below is not visible.”]
/// getMailType()
/// This function determines the type of email item currently being composed
/// – If it is a new item, it returns "New"
/// – If it is a reply, it return "Reply"
/// – If it is a Forward it returns "Forward"
/// – And if it cannot determine, it returns "UnknownReplyOrForward"
/// This accepts a function that is called with the resulting value.
function getMailType(returnFunction) {
// get the conversation ID – if it exists
var id = Office.cast.item.toItemCompose(Office.context.mailbox.item).conversationId;
if (id == null) {
// We have a new item
returnFunction("New");
return;
}
else {
// at this point we know we have a reply or forward. Now we determine which on it is.
// we do this by getting the SUBJECT and then – yes – we look and see if it is a
// RE: or FW: or unknown.
Office.cast.item.toItemCompose(Office.context.mailbox.item)
.subject.getAsync(function (result) {
var subject = result.value;
// now this sucks, but the only way to do this is look at the
// beginning of the subject and see it if it RE or FWD and
// even worse, this is language specific…
// and worse yet – if the user changed it, we have no idea
if(subject.toString().toUpperCase.startsWith("RE:")){
returnFunction("Reply");
}
else if(subject.toString().toUpperCase.startsWith("FW:")){
returnFunction("Forward");
}
else {
returnFunction("UnknownReplyOrForward");
}
});
}
}
[/code]


/// getMailType()
/// This function determines the type of email item currently being composed
/// – If it is a new item, it returns "New"
/// – If it is a reply, it return "Reply"
/// – If it is a Forward it returns "Forward"
/// – And if it cannot determine, it returns "UnknownReplyOrForward"
/// This accepts a function that is called with the resulting value.
function getMailType(returnFunction) {
// get the conversation ID – if it exists
var id = Office.cast.item.toItemCompose(Office.context.mailbox.item).conversationId;
if (id == null) {
// We have a new item
returnFunction("New");
return;
}
else {
// at this point we know we have a reply or forward. Now we determine which on it is.
// we do this by getting the SUBJECT and then – yes – we look and see if it is a
// RE: or FW: or unknown.
Office.cast.item.toItemCompose(Office.context.mailbox.item)
.subject.getAsync(function (result) {
var subject = result.value;
// now this sucks, but the only way to do this is look at the
// beginning of the subject and see it if it RE or FWD and
// even worse, this is language specific…
// and worse yet – if the user changed it, we have no idea
if(subject.toString().toUpperCase.startsWith("RE:")){
returnFunction("Reply");
}
else if(subject.toString().toUpperCase.startsWith("FW:")){
returnFunction("Forward");
}
else {
returnFunction("UnknownReplyOrForward");
}
});
}
}

view raw

getMailType.js

hosted with ❤ by GitHub

And to test this, I just created a button on my Compose App task pane, that runs the following code:

[code language=”javascript”]
$(‘#getMailType’).click(function () {
getMailType(function (result) {
app.showNotification("This is a: " + result);
});
});
[/code]