Log appointment notes to an external application in Outlook mobile add-ins

Saving your appointment notes and other details to a customer relationship management (CRM) or note-taking application can help you keep track of meetings you've attended.

In this article, you'll learn how to set up your Outlook mobile add-in to enable users to log notes and other details about their appointments to your CRM or note-taking application. Throughout this article, we'll be using a fictional CRM service provider named "Contoso".

Supported clients

Logging notes to an external application from an Outlook mobile add-in is supported in Outlook on Android and on iOS with a Microsoft 365 subscription.

Set up your environment

Complete the Outlook quick start to create an add-in project with the Yeoman generator for Office Add-ins.

Capture and view appointment notes

You can opt to implement a function command or task pane. To update your add-in, select the tab for either function command or task pane, then follow the instructions.

This option will enable a user to log and view their notes and other details about their appointments when they select a function command from the ribbon.

Configure the manifest

To enable users to log appointment notes with your add-in, you must configure the MobileLogEventAppointmentAttendee extension point in the manifest under the parent element MobileFormFactor. Other form factors aren't supported.

Note

Add-ins using the Unified manifest for Microsoft 365 (preview) aren't currently supported on mobile devices.

  1. In your code editor, open the quick start project.

  2. Open the manifest.xml file located at the root of your project.

  3. Select the entire <VersionOverrides> node (including open and close tags) and replace it with the following XML. Make sure to replace all references to Contoso with your company's information.

    <VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides" xsi:type="VersionOverridesV1_0">
      <VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides/1.1" xsi:type="VersionOverridesV1_1">
        <Description resid="residDescription"></Description>
        <Requirements>
          <bt:Sets>
            <bt:Set Name="Mailbox" MinVersion="1.3"/>
          </bt:Sets>
        </Requirements>
        <Hosts>
          <Host xsi:type="MailHost">
            <DesktopFormFactor>
              <FunctionFile resid="residFunctionFile"/>
              <ExtensionPoint xsi:type="AppointmentAttendeeCommandSurface">
                <OfficeTab id="TabDefault">
                  <Group id="apptReadGroup">
                    <Label resid="residDescription"/>
                    <Control xsi:type="Button" id="apptReadOpenPaneButton">
                      <Label resid="residLabel"/>
                      <Supertip>
                        <Title resid="residLabel"/>
                        <Description resid="residTooltip"/>
                      </Supertip>
                      <Icon>
                        <bt:Image size="16" resid="icon-16"/>
                        <bt:Image size="32" resid="icon-32"/>
                        <bt:Image size="80" resid="icon-80"/>
                      </Icon>
                      <Action xsi:type="ExecuteFunction">
                        <FunctionName>logCRMEvent</FunctionName>
                      </Action>
                    </Control>
                  </Group>
                </OfficeTab>
              </ExtensionPoint>
            </DesktopFormFactor>
            <MobileFormFactor>
              <FunctionFile resid="residFunctionFile"/>
              <ExtensionPoint xsi:type="MobileLogEventAppointmentAttendee">
                <Control xsi:type="MobileButton" id="appointmentReadFunctionButton">
                  <Label resid="residLabel"/>
                  <Icon>
                    <bt:Image size="25" scale="1" resid="icon-16"/>
                    <bt:Image size="25" scale="2" resid="icon-16"/>
                    <bt:Image size="25" scale="3" resid="icon-16"/>
                    <bt:Image size="32" scale="1" resid="icon-32"/>
                    <bt:Image size="32" scale="2" resid="icon-32"/>
                    <bt:Image size="32" scale="3" resid="icon-32"/>
                    <bt:Image size="48" scale="1" resid="icon-48"/>
                    <bt:Image size="48" scale="2" resid="icon-48"/>
                    <bt:Image size="48" scale="3" resid="icon-48"/>
                  </Icon>
                  <Action xsi:type="ExecuteFunction">
                    <FunctionName>logCRMEvent</FunctionName>
                  </Action>
                </Control>
              </ExtensionPoint>
            </MobileFormFactor>
          </Host>
        </Hosts>
        <Resources>
          <bt:Images>
            <bt:Image id="icon-16" DefaultValue="https://contoso.com/assets/icon-16.png"/>
            <bt:Image id="icon-32" DefaultValue="https://contoso.com/assets/icon-32.png"/>
            <bt:Image id="icon-48" DefaultValue="https://contoso.com/assets/icon-48.png"/>
            <bt:Image id="icon-80" DefaultValue="https://contoso.com/assets/icon-80.png"/>
          </bt:Images>
          <bt:Urls>
            <bt:Url id="residFunctionFile" DefaultValue="https://contoso.com/commands.html"/>
          </bt:Urls>
          <bt:ShortStrings>
            <bt:String id="residDescription" DefaultValue="Log appointment notes and other details to Contoso CRM."/>
            <bt:String id="residLabel" DefaultValue="Log to Contoso CRM"/>
          </bt:ShortStrings>
          <bt:LongStrings>
            <bt:String id="residTooltip" DefaultValue="Log notes to Contoso CRM for this appointment."/>
          </bt:LongStrings>
        </Resources>
      </VersionOverrides>
    </VersionOverrides>
    

Tip

To learn more about manifests for Outlook add-ins, see Office add-in manifests and Add support for add-in commands in Outlook on mobile devices.

Capture appointment notes

In this section, learn how your add-in can extract appointment details when the user selects the Log button.

  1. From the same quick start project, open the file ./src/commands/commands.js in your code editor.

  2. Replace the entire content of the commands.js file with the following JavaScript.

    var event;
    
    Office.initialize = function (reason) {
      // Add any initialization code here.
    };
    
    function logCRMEvent(appointmentEvent) {
      event = appointmentEvent;
      console.log(`Subject: ${Office.context.mailbox.item.subject}`);
      Office.context.mailbox.item.body.getAsync(
        "html",
        { asyncContext: "This is passed to the callback" },
        function callback(result) {
          if (result.status === Office.AsyncResultStatus.Succeeded) {
            event.completed({ allowEvent: true });
          } else {
            console.error("Failed to get body.");
            event.completed({ allowEvent: false });
          }
        }
      );
    }
    
    // Register the function.
    Office.actions.associate("logCRMEvent", logCRMEvent);
    

Next, update the commands.html file to reference commands.js.

  1. From the same quick start project, open the ./src/commands/commands.html file in your code editor.

  2. Find and replace <script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script> with the following:

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

View appointment notes

The Log button label can be toggled to display View by setting the EventLogged custom property reserved for this purpose. When the user selects the View button, they can look at their logged notes for this appointment.

Your add-in defines the log viewing experience. For example, you can display the logged appointment notes in a dialog when the user selects the View button. For details on using dialogs, refer to Use the Office dialog API in your Office Add-ins.

Add the following function to ./src/commands/commands.js. This function sets the EventLogged custom property on the current appointment item.

function updateCustomProperties() {
  Office.context.mailbox.item.loadCustomPropertiesAsync(
    function callback(customPropertiesResult) {
      if (customPropertiesResult.status === Office.AsyncResultStatus.Succeeded) {
        let customProperties = customPropertiesResult.value;
        customProperties.set("EventLogged", true);
        customProperties.saveAsync(
          function callback(setSaveAsyncResult) {
            if (setSaveAsyncResult.status === Office.AsyncResultStatus.Succeeded) {
              console.log("EventLogged custom property saved successfully.");
              event.completed({ allowEvent: true });
              event = undefined;
            }
          }
        );
      }
    }
  );
}

Then, call it after the add-in successfully logs the appointment notes. For example, you can call it from logCRMEvent as shown in the following function.

function logCRMEvent(appointmentEvent) {
  event = appointmentEvent;
  console.log(`Subject: ${Office.context.mailbox.item.subject}`);
  Office.context.mailbox.item.body.getAsync(
    "html",
    { asyncContext: "This is passed to the callback" },
    function callback(result) {
      if (result.status === Office.AsyncResultStatus.Succeeded) {
        // Replace `event.completed({ allowEvent: true });` with the following statement.
        updateCustomProperties();
      } else {
        console.error("Failed to get body.");
        event.completed({ allowEvent: false });
      }
    }
  );
}

Delete the appointment log

If you'd like to enable your users to undo logging or delete the logged appointment notes so a replacement log can be saved, you have two options.

  1. Use Microsoft Graph to clear the custom properties object when the user selects the appropriate button on the ribbon.

  2. Add the following function to ./src/commands/commands.js to clear the EventLogged custom property on the current appointment item.

    function clearCustomProperties() {
      Office.context.mailbox.item.loadCustomPropertiesAsync(
        function callback(customPropertiesResult) {
          if (customPropertiesResult.status === Office.AsyncResultStatus.Succeeded) {
            var customProperties = customPropertiesResult.value;
            customProperties.remove("EventLogged");
            customProperties.saveAsync(
              function callback(removeSaveAsyncResult) {
                if (removeSaveAsyncResult.status === Office.AsyncResultStatus.Succeeded) {
                  console.log("Custom properties cleared");
                  event.completed({ allowEvent: true });
                  event = undefined;
                }
              }
            );
          }
        }
      );
    }
    

Then, call it when you want to clear the custom property. For example, you can call it from logCRMEvent if setting the log failed in some way as shown in the following function.

function logCRMEvent(appointmentEvent) {
  event = appointmentEvent;
  console.log(`Subject: ${Office.context.mailbox.item.subject}`);
  Office.context.mailbox.item.body.getAsync(
    "html",
    { asyncContext: "This is passed to the callback" },
    function callback(result) {
      if (result.status === Office.AsyncResultStatus.Succeeded) {
        updateCustomProperties();
      } else {
        console.error("Failed to get body.");
        // Replace `event.completed({ allowEvent: false });` with the following statement.
        clearCustomProperties();
      }
    }
  );
}

Test and validate

  1. Follow the usual guidance to test and validate your add-in.
  2. After you sideload the add-in in Outlook on the web, on Windows (classic or new (preview)), or on Mac, restart Outlook on your Android or iOS mobile device.
  3. Open an appointment as an attendee, then verify that under the Meeting Insights card, there's a new card with your add-in's name alongside the Log button.

UI: Log the appointment notes

As a meeting attendee, you should see a screen similar to the following image when you open a meeting.

The Log button on an appointment screen on Android.

UI: View the appointment log

After successfully logging the appointment notes, the button should now be labeled View instead of Log. You should see a screen similar to the following image.

The View button on an appointment screen on Android.

Available APIs

The following APIs are available for this feature.

To learn more about APIs that are supported in Outlook on mobile devices, see Outlook JavaScript APIs supported in Outlook on mobile devices.

Restrictions

Several restrictions apply.

  • The Log button name can't be changed. However, there's a way for a different label to be displayed by setting a custom property on the appointment item. For more details, refer to the View appointment notes section for function command or task pane as appropriate.
  • The EventLogged custom property must be used if you want to toggle the label of the Log button to View and back.
  • The add-in icon should be in grayscale using hex code #919191 or its equivalent in other color formats.
  • The add-in should extract the meeting details from the appointment form within the one-minute timeout period. However, any time spent in a dialog box the add-in opened for authentication, for example, is excluded from the timeout period.

See also