with JavaScript


Create Project Folder

Open Visual Studio and create a New Project.
Find "Outlook Web Add-in" (with C#) and press Next.
Change the Project Name to "OutlookVisualStudio".
Change the Location by clicking on the Browse button.
Tick the "Place solution and project in the same directory" checkbox and press Create.
Note: The "Create Office Add-in wizard" does not appear (which it does with Excel and PowerPoint).
This will create a solution that contains two projects
OutlookVisualStudio - This contains the manifest file.
OutlookVisualStudioWeb - This contains the HTML pages.

alt text

packages.config

<?xml version="1.0" encoding="utf-8"?> 
<packages>
  <package id="jQuery" version="3.6.0" targetFramework="net48" />
  <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net48" />
  <package id="Microsoft.Office.js" version="1.1.0.18" targetFramework="net48" />
  <package id="OfficeUIFabricCore" version="9.6.0" targetFramework="net48" />
</packages>

OutlookVisualStudio.xml

<?xml version="1.0" encoding="UTF-8"?> 
<OfficeApp
  xmlns="http://schemas.microsoft.com/office/appforoffice/1.1"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0"
  xmlns:mailappor="http://schemas.microsoft.com/office/mailappversionoverrides/1.0"
  xsi:type="MailApp">

  <Id> Unique GUID </Id>
  <Version>1.0.0.0</Version>
  <ProviderName>BetterSolutions.com</ProviderName>
  <DefaultLocale>en-US</DefaultLocale>
  <DisplayName DefaultValue="OutlookVisualStudio" />
  <Description DefaultValue="OutlookVisualStudio"/>
  <IconUrl DefaultValue="~remoteAppUrl/Images/icon64.png"/>
  <SupportUrl DefaultValue="https://bettersolutions.com" />
  <AppDomains>
    <AppDomain>AppDomain1</AppDomain>
  </AppDomains>
  <Hosts>
    <Host Name="Mailbox" />
  </Hosts>
  <Requirements>
    <Sets>
      <Set Name="Mailbox" MinVersion="1.1" />
    </Sets>
  </Requirements>
  <FormSettings>
    <Form xsi:type="ItemRead">
      <DesktopSettings>
        <SourceLocation DefaultValue="~remoteAppUrl/MessageRead.html"/>
        <RequestedHeight>250</RequestedHeight>
      </DesktopSettings>
    </Form>
  </FormSettings>
  <Permissions>ReadWriteItem</Permissions>
  <Rule xsi:type="RuleCollection" Mode="Or">
    <Rule xsi:type="ItemIs" ItemType="Message" FormType="Read" />
  </Rule>
  <DisableEntityHighlighting>false</DisableEntityHighlighting>
  <VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides" xsi:type="VersionOverridesV1_0">
    <Requirements>
      <bt:Sets DefaultMinVersion="1.3">
        <bt:Set Name="Mailbox" />
      </bt:Sets>
    </Requirements>
    <Hosts>
      <Host xsi:type="MailHost">
        <DesktopFormFactor>
          <FunctionFile resid="functionFile" />
          <ExtensionPoint xsi:type="MessageReadCommandSurface">
            <OfficeTab id="TabDefault">
              <Group id="msgReadGroup">
                <Label resid="groupLabel" />
                <Control xsi:type="Button" id="msgReadOpenPaneButton">
                  <Label resid="paneReadButtonLabel" />
                  <Supertip>
                    <Title resid="paneReadSuperTipTitle" />
                    <Description resid="paneReadSuperTipDescription" />
                  </Supertip>
                  <Icon>
                    <bt:Image size="16" resid="icon16" />
                    <bt:Image size="32" resid="icon32" />
                    <bt:Image size="80" resid="icon80" />
                  </Icon>
                  <Action xsi:type="ShowTaskpane">
                    <SourceLocation resid="messageReadTaskPaneUrl" />
                  </Action>
                </Control>
              </Group>
            </OfficeTab>
          </ExtensionPoint>
        </DesktopFormFactor>
      </Host>
    </Hosts>
    <Resources>
      <bt:Images>
        <bt:Image id="icon16" DefaultValue="~remoteAppUrl/Images/icon16.png"/>
        <bt:Image id="icon32" DefaultValue="~remoteAppUrl/Images/icon32.png"/>
        <bt:Image id="icon80" DefaultValue="~remoteAppUrl/Images/icon80.png"/>
      </bt:Images>
      <bt:Urls>
        <bt:Url id="functionFile" DefaultValue="~remoteAppUrl/Functions/FunctionFile.html"/>
        <bt:Url id="messageReadTaskPaneUrl" DefaultValue="~remoteAppUrl/MessageRead.html"/>
      </bt:Urls>
      <bt:ShortStrings>
        <bt:String id="groupLabel" DefaultValue="My Add-in Group"/>
        <bt:String id="customTabLabel" DefaultValue="My Add-in Tab"/>
        <bt:String id="paneReadButtonLabel" DefaultValue="Display all properties"/>
        <bt:String id="paneReadSuperTipTitle" DefaultValue="Get all properties"/>
      </bt:ShortStrings>
      <bt:LongStrings>
        <bt:String id="paneReadSuperTipDescription" DefaultValue="This is a button that opens a task pane."/>
      </bt:LongStrings>
    </Resources>
  </VersionOverrides>
</OfficeApp>

MessageRead.html

This html file must include a reference to office.js.
This html file must call its corresponding javascript file (MessageRead.js).

<!DOCTYPE html> 
<html>
<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <title></title>
    <script src="Scripts/jquery-3.6.0.js" type="text/javascript"></script>
    <script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
    <script src="MessageRead.js" type="text/javascript"></script>
    <script src="Scripts/MessageBanner.js" type="text/javascript"></script>
    <link href="Content/Button.css" rel="stylesheet" type="text/css" />
    <link href="Content/MessageBanner.css" rel="stylesheet" type="text/css" />
    <link rel="stylesheet" href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/9.6.0/css/fabric.min.css">
</head>
<body class="ms-Fabric" dir="ltr">
    <div id="content-header">
        <div class="padding">
            <p class="ms-font-xl ms-fontColor-themeDarkAlt ms-fontWeight-semilight">All properties</p>
        </div>
    </div>
    <div id="content-main" class="ms-Grid" dir="ltr">
        <div class="ms-Grid-row">
            <div class="ms-Grid-col ms-sm12">
                <h2 class="ms-font-l">Office.context.mailbox.Item properties</h2>
                <div class="ms-Grid" dir="ltr">
                    <div class="ms-Grid-row">
                        <div class="ms-Grid-col ms-sm5">Property</div>
                        <div class="ms-Grid-col ms-sm7">Value</div>
                    </div>
                    <div class="ms-Grid-row">
                        <div class="ms-Grid-col ms-fontWeight-semibold ms-sm5">dateTimeCreated</div>
                        <div id="dateTimeCreated" class="ms-Grid-col ms-sm7"></div>
                    </div>
                    <div class="ms-Grid-row">
                        <div class="ms-Grid-col ms-fontWeight-semibold ms-sm5">dateTimeModified</div>
                        <div id="dateTimeModified" class="ms-Grid-col ms-sm7"></div>
                    </div>
                    <div class="ms-Grid-row">
                        <div class="ms-Grid-col ms-fontWeight-semibold ms-sm5">itemClass</div>
                        <div id="itemClass" class="ms-Grid-col ms-sm7"></div>
                    </div>
                    <div class="ms-Grid-row">
                        <div class="ms-Grid-col ms-fontWeight-semibold ms-sm5">itemId</div>
                        <div id="itemId" class="ms-Grid-col ms-sm7"></div>
                    </div>
                    <div class="ms-Grid-row">
                        <div class="ms-Grid-col ms-fontWeight-semibold ms-sm5">itemType</div>
                        <div id="itemType" class="ms-Grid-col ms-sm7"></div>
                    </div>
                </div>
            </div>
        </div>

        <div id="message-props" class="ms-Grid-row hidden">
            <div class="ms-Grid-col ms-sm12 ms-md12 ms-lg12">
                <h2 class="ms-font-l">Office.context.mailbox.Message properties</h2>
                <div class="ms-Grid" dir="ltr">
                    <div class="ms-Grid-row">
                        <span class="ms-Grid-col ms-sm5">Property</span>
                        <span class="ms-Grid-col ms-sm7">Value</span>
                    </div>
                    <div class="ms-Grid-row">
                        <span class="ms-Grid-col ms-fontWeight-semibold ms-sm5">attachments</span>
                        <span id="attachments" class="ms-Grid-col ms-sm7"></span>
                    </div>
                    <div class="ms-Grid-row">
                        <span class="ms-Grid-col ms-fontWeight-semibold ms-sm5">cc</span>
                        <span id="cc" class="ms-Grid-col ms-sm7"></span>
                    </div>
                    <div class="ms-Grid-row">
                        <span class="ms-Grid-col ms-fontWeight-semibold ms-sm5">conversationId</span>
                        <span id="conversationId" class="ms-Grid-col ms-sm7"></span>
                    </div>
                    <div class="ms-Grid-row">
                        <span class="ms-Grid-col ms-fontWeight-semibold ms-sm5">from</span>
                        <span id="from" class="ms-Grid-col ms-sm7"></span>
                    </div>
                    <div class="ms-Grid-row">
                        <span class="ms-Grid-col ms-fontWeight-semibold ms-sm5">internetMessageId</span>
                        <span id="internetMessageId" class="ms-Grid-col ms-sm7"></span>
                    </div>
                    <div class="ms-Grid-row">
                        <span class="ms-Grid-col ms-fontWeight-semibold ms-sm5">normalizedSubject</span>
                        <span id="normalizedSubject" class="ms-Grid-col ms-sm7"></span>
                    </div>
                    <div class="ms-Grid-row">
                        <span class="ms-Grid-col ms-fontWeight-semibold ms-sm5">sender</span>
                        <span id="sender" class="ms-Grid-col ms-sm7"></span>
                    </div>
                    <div class="ms-Grid-row">
                        <span class="ms-Grid-col ms-fontWeight-semibold ms-sm5">subject</span>
                        <span id="subject" class="ms-Grid-col ms-sm7"></span>
                    </div>
                    <div class="ms-Grid-row">
                        <span class="ms-Grid-col ms-fontWeight-semibold ms-sm5">to</span>
                        <span id="to" class="ms-Grid-col ms-sm7"></span>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="MessageBanner" style="position:absolute;bottom: 0;">
        <div class="MessageBanner-content">
            <div class="MessageBanner-text">
                <div class="MessageBanner-clipper">
                    <div class="ms-font-m-plus ms-fontWeight-semibold" id="notificationHeader"></div>
                    <div class="ms-font-m ms-fontWeight-semilight" id="notificationBody"></div>
                </div>
            </div>
            <button class="MessageBanner-expand" style="display:none"><i class="ms-Icon ms-Icon--chevronsDown"></i> </button>
            <div class="MessageBanner-action"></div>
        </div>
        <button class="MessageBanner-close"> <i class="ms-Icon ms-Icon--ChromeClose"></i> </button>
    </div>
</body>
</html>

MessageRead.js

The JQuery messageBanner control is part of the Office UI Fabric JavaScript components.
This control is used to display any errors at the bottom of the task pane.

(function () { 
  "use strict";

  var messageBanner;

  // The Office initialize function must be run each time a new page is loaded.
  Office.initialize = function (reason) {
    $(document).ready(function () {
      var element = document.querySelector('.MessageBanner');
      messageBanner = new components.MessageBanner(element);
      messageBanner.hideBanner();
      loadProps();
    });
  };

  // Take an array of AttachmentDetails objects and build a list of attachment names, separated by a line-break.
  function buildAttachmentsString(attachments) {
    if (attachments && attachments.length > 0) {
      var returnString = "";
      
      for (var i = 0; i < attachments.length; i++) {
        if (i > 0) {
          returnString = returnString + "<br/>";
        }
        returnString = returnString + attachments[i].name;
      }
      return returnString;
    }
    return "None";
  }

  // Format an EmailAddressDetails object as
  // GivenName Surname <emailaddress>
  function buildEmailAddressString(address) {
    return address.displayName + " <" + address.emailAddress + ">";
  }

  // Take an array of EmailAddressDetails objects and
  // build a list of formatted strings, separated by a line-break
  function buildEmailAddressesString(addresses) {
    if (addresses && addresses.length > 0) {
      var returnString = "";

      for (var i = 0; i < addresses.length; i++) {
        if (i > 0) {
          returnString = returnString + "<br/>";
        }
        returnString = returnString + buildEmailAddressString(addresses[i]);
      }
      return returnString;
    }
    return "None";
  }

  // Load properties from the Item base object, then load the
  // message-specific properties.
  function loadProps() {
    var item = Office.context.mailbox.item;

    $('#dateTimeCreated').text(item.dateTimeCreated.toLocaleString());
    $('#dateTimeModified').text(item.dateTimeModified.toLocaleString());
    $('#itemClass').text(item.itemClass);
    $('#itemId').text(item.itemId);
    $('#itemType').text(item.itemType);
    $('#message-props').show();
    $('#attachments').html(buildAttachmentsString(item.attachments));
    $('#cc').html(buildEmailAddressesString(item.cc));
    $('#conversationId').text(item.conversationId);
    $('#from').html(buildEmailAddressString(item.from));
    $('#internetMessageId').text(item.internetMessageId);
    $('#normalizedSubject').text(item.normalizedSubject);
    $('#sender').html(buildEmailAddressString(item.sender));
    $('#subject').text(item.subject);
    $('#to').html(buildEmailAddressesString(item.to));
  }

  // Helper function for displaying notifications
  function showNotification(header, content) {
    $("#notificationHeader").text(header);
    $("#notificationBody").text(content);
    messageBanner.showBanner();
    messageBanner.toggleExpansion();
  }
})();

Load the Add-in - Online

With Multi-Factor Authentication
If your account is using multi-factor authentication, you need to change this property to True.

alt text

Select (Debug > Start Debugging).
You will see a "Sign in to your account" dialog box appear.
Sign in with your Office Developer account or Microsoft account.
A browser window will open displaying Outlook (you may have to sign in again if you have multiple accounts).
Select an email and in the preview pane, select More Actions, More Apps.
You will see "OutlookVisualStudio" in the list, click on it to load the add-in.
As soon as you load this add-in a task pane will appear on the RHS displaying the message properties.

alt text

Without Multi-Factor Authentication
Select (Debug > Start Debugging).
You will see the "Connect to Exchange email account" dialog box appear.

alt text

Enter your email address and password and press Connect.
A browser window will open displaying Outlook (you may have to sign in again if you have multiple accounts).


Load the Add-in - Desktop

For Excel, Word and PowerPoint you can just build the project and launch the Desktop application.
This approach will not work with Outlook and requires a few more steps.
In order for any add-in to be available it needs to be hosted, either locally or on an https server.
Side loading in Outlook is a bit more complicated because of Exchange Online.
It is possible to see this add-in inside the Desktop but you need to load the add-in in the browser first.
Once the browser window opens and your Inbox is displayed, minimise this browser window.
All the time the browser window is open the add-in will remain hosted locally allowing you to see it from within the Desktop application.

alt text

Open Outlook. On the Home tab click on "Get Add-ins".
On the left hand side click on "My add-ins" and scroll to the bottom of the list.
Under "Custom Addins" you should see an entry for "OutlookVisualStudio" and is should say Added.
Select this add-in and press the Back button.
Close the dialog using the cross in the top right corner.
Now when you click on an email in your inbox you should see another group displayed on the tab called "My Add-in Group".

alt text

If you are trying this within a large organisation you will need the 'My Custom Apps' role in order to be able to sideload an addin.


© 2022 Better Solutions Limited. All Rights Reserved. © 2022 Better Solutions Limited TopPrevNext