user581733
user581733

Reputation: 504

Using on-send add-in Office Outlook 2002 build with VueJS

We build an Office Outlook Add-In with VueJS. We want to use the on-send feature to check the body of our message invites. If it passes, the invite will go out. If not, the user will get notified to make necessary changes.

The VueJS app is built via the CLI but we are reading in one main index.js file. We are not using components. I am running on https://localhost:3000.

I downloaded the example code from Microsoft: Contoso Message Body Checker with its manifest xml into my local host. It runs like a champ.

However, when I try to place it into our manifest.xml but I'm not sure how to hook it into our index.js file.

The code is REALLY long. But, I loaded the manifest.xml and the top part of our vue application.

Here is the Contorso Message Body Checker manifest:

<?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"
  xsi:type="MailApp">

  <Id>D0590B2A-0CB8-4B4F-AD70-C520AFA6E3FC</Id>
  <Version>1.0</Version>
  <ProviderName>Contoso</ProviderName>
  <DefaultLocale>en-us</DefaultLocale>
  <DisplayName DefaultValue="Contoso Message Body Checker" />
  <Description DefaultValue="Contoso Message Body Checker" />

  <Requirements>
    <Sets DefaultMinVersion="1.1">
      <Set Name="Mailbox" />
    </Sets>
  </Requirements>

  <FormSettings>
    <Form xsi:type="ItemEdit">
      <DesktopSettings>
        <SourceLocation DefaultValue="https://localhost:3000/index_checker.html" />
      </DesktopSettings>
    </Form>
  </FormSettings>

  <Permissions>ReadWriteMailbox</Permissions>

  <Rule xsi:type="RuleCollection" Mode="Or">
    <Rule xsi:type="ItemIs" ItemType="Message" FormType="Edit" />
    <Rule xsi:type="ItemIs" ItemType="Appointment" FormType="Edit" />
  </Rule>

  <VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides" xsi:type="VersionOverridesV1_0">
    <!-- On Send requires VersionOverridesV1_1 -->
    <VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides/1.1" xsi:type="VersionOverridesV1_1">
      <Description resid="residAppDescription" />
      <Requirements>
        <bt:Sets DefaultMinVersion="1.3">
          <bt:Set Name="Mailbox" />
        </bt:Sets>
      </Requirements>
      <Hosts>
        <Host xsi:type="MailHost">
          <DesktopFormFactor>
            <!-- The functionfile and function name to call on message send.  -->
            <!-- In this particular case the function validateBody will be called within the JavaScript code referenced in residUILessFunctionFileUrl. -->
            <FunctionFile resid="residUILessFunctionFileUrl" />
            <ExtensionPoint xsi:type="Events">
              <Event Type="ItemSend" FunctionExecution="synchronous" FunctionName="validateBody" />
            </ExtensionPoint>
          </DesktopFormFactor>
        </Host>
      </Hosts>
      <Resources>
        <bt:Urls>
           <!-- The JavaScript code is hosted on a secure and trusted web server. -->
          <bt:Url id="residUILessFunctionFileUrl" DefaultValue="https://localhost:3000/index_checker.html" ></bt:Url>
        </bt:Urls>
      </Resources>
    </VersionOverrides>
  </VersionOverrides>
</OfficeApp>

Here is the manifest.xml with the above additions

<?xml version="1.0" encoding="UTF-8"?>
<!--Created:ce44715c-8c4e-446b-879c-ea9ebe0f09c8-->
<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">

  <!-- Begin Basic Settings: Add-in metadata, used for all versions of Office unless override provided. -->

  <!-- IMPORTANT! Id must be unique for your add-in, if you reuse this manifest ensure that you change this id to a new GUID. -->
  <Id>3f1a65ac-9e5a-4ce7-8203-2ff6f626e81e</Id>

  <!--Version. Updates from the store only get triggered if there is a version change. -->
  <Version>0.0.0.7</Version>
  <ProviderName>App Name</ProviderName>
  <DefaultLocale>en-US</DefaultLocale>

  <!-- The display name of your add-in. Used on the store and various places of the Office UI such as the add-ins dialog. -->
  <DisplayName DefaultValue="App Name" />
  <Description DefaultValue="App Name"/>
  <IconUrl DefaultValue="http://localhost:3000/images/icon64.png"/>
  <HighResolutionIconUrl DefaultValue="http://localhost:3000/images/icon128.png" />

  <!-- Domains that will be allowed when navigating. For example, if you use ShowTaskpane and then have an href link, navigation will only be allowed if the domain is on this list. -->
  <AppDomains>
    <AppDomain>AppDomain1</AppDomain>
  </AppDomains>
  <!--End Basic Settings. -->

  <Hosts>
    <Host Name="Mailbox" />
  </Hosts>
  <Requirements>
    <Sets>
      <Set Name="Mailbox" MinVersion="1.1" />
    </Sets>
  </Requirements>
  <FormSettings>
    <Form xsi:type="ItemRead">
      <DesktopSettings>
        <SourceLocation DefaultValue="http://localhost:3000/index.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 xsi:type="ItemIs" ItemType="Message" FormType="Edit" />
    <Rule xsi:type="ItemIs" ItemType="Appointment" FormType="Read" />
    <Rule xsi:type="ItemIs" ItemType="Appointment" FormType="Edit" />
  </Rule>
  <DisableEntityHighlighting>false</DisableEntityHighlighting>

  <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">
      <Requirements>
        <bt:Sets DefaultMinVersion="1.3">
          <bt:Set Name="Mailbox" />
        </bt:Sets>
      </Requirements>
      <Hosts>
        <Host xsi:type="MailHost">
          <DesktopFormFactor>

            <!-- The functionfile and function name to call on message send.  -->
            <!-- In this particular case the function validateBody will be called within the JavaScript code referenced in residUILessFunctionFileUrl. -->
            <FunctionFile resid="residUILessFunctionFileUrl" />
            <ExtensionPoint xsi:type="Events">
              <Event Type="ItemSend" FunctionExecution="synchronous" FunctionName="app.$methods.validateBody" />
            </ExtensionPoint>

            <!-- Appointment Edit -->
            <ExtensionPoint xsi:type="AppointmentOrganizerCommandSurface">
              <!-- Use the default tab of the ExtensionPoint or create your own with <CustomTab id="myTab"> -->
              <OfficeTab id="TabDefault">
                <!-- Up to 6 Groups added per Tab -->
                <Group id="msgReadGroup">
                  <Label resid="groupLabel" />
                  <!-- Launch the add-in : task pane button -->
                  <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">
                      <!--<TaskpaneId>Office.AutoShowTaskpaneWithDocument</TaskpaneId>-->
                      <SourceLocation resid="messageReadTaskPaneUrl" />
                    </Action>
                  </Control>
                  <!-- Go to http://aka.ms/ButtonCommands to learn how to add more Controls: ExecuteFunction and Menu -->
                </Group>
              </OfficeTab>
            </ExtensionPoint>

            <ExtensionPoint xsi:type="AppointmentAttendeeCommandSurface">
              <!-- Use the default tab of the ExtensionPoint or create your own with <CustomTab id="myTab"> -->
              <OfficeTab id="TabDefault">
                <!-- Up to 6 Groups added per Tab -->
                <Group id="msgReadGroup2">
                  <Label resid="groupLabel" />
                  <!-- Launch the add-in : task pane button -->
                  <Control xsi:type="Button" id="msgReadOpenPaneButton2">
                    <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>
                  <!-- Go to http://aka.ms/ButtonCommands to learn how to add more Controls: ExecuteFunction and Menu -->
                </Group>
              </OfficeTab>
            </ExtensionPoint>

            <!-- Go to http://aka.ms/ExtensionPointsCommands to learn how to add more Extension Points: MessageRead, AppointmentOrganizer, AppointmentAttendee -->
          </DesktopFormFactor>
        </Host>
      </Hosts>

      <Resources>
        <bt:Images>
          <bt:Image id="icon16" DefaultValue="http://localhost:3000/images/icon16.png"/>
          <bt:Image id="icon32" DefaultValue="http://localhost:3000/images/icon32.png"/>
          <bt:Image id="icon80" DefaultValue="http://localhost:3000/images/icon80.png"/>
        </bt:Images>
        <bt:Urls>
          <bt:Url id="functionFile" DefaultValue="http://localhost:3000/index.html"/>
          <bt:Url id="messageReadTaskPaneUrl" DefaultValue="http://localhost:3000/index.html"/>
          <bt:Url id="residUILessFunctionFileUrl" DefaultValue="https://localhost:3000/index.html" ></bt:Url>
        </bt:Urls>
        <bt:ShortStrings>
          <bt:String id="groupLabel" DefaultValue="App Name (Local)"/>
          <bt:String id="customTabLabel"  DefaultValue="App Name"/>
          <bt:String id="paneReadButtonLabel" DefaultValue="App Name"/>
          <bt:String id="paneReadSuperTipTitle" DefaultValue="App Name"/>
        </bt:ShortStrings>
        <bt:LongStrings>
          <bt:String id="paneReadSuperTipDescription" DefaultValue="Click here to add/edit the agenda for this meeting."/>
        </bt:LongStrings>
      </Resources>
    </VersionOverrides>
  </VersionOverrides>
</OfficeApp>

The beginning of the index.js creating the view snippet. This is brought in via index.html

Office.onReady().then(function (info) {

    document.body.style.zoom = 1.0;
    document.getElementById("confirmDeleteModal").removeAttribute("style");

    Vue.use(VueI18n);

    if (info.host === Office.HostType.Outlook) {
            //put in the stuff here...
        var app = new Vue({
            el: '#vueApp',

I think the problem lies here...I'm trying to call vue as an external function.

            <FunctionFile resid="residUILessFunctionFileUrl" />
            <ExtensionPoint xsi:type="Events">
              <Event Type="ItemSend" FunctionExecution="synchronous" FunctionName="app.$methods.validateBody" />
            </ExtensionPoint>

Any suggestions on how to make the hook will be appreciated.

Thanks

Upvotes: 1

Views: 518

Answers (1)

user7823505
user7823505

Reputation:

I'm not very familiar with VueJS, however, the On-Send feature looks for the handler function in the add-in's JS by using the value of FunctionName provided in the manifest. This value is treated as a literal string. It is not evaluated with eval. So app.$methods.validateBody will not work.

Try making validateBody a simple global function in your add-ins JS and set that as the FunctionName in your manifest.

As an alternate suggestion, try manually adding your function to the window object to see if that works instead.

window.validateBody = app.$methods.validateBody;

Upvotes: 1

Related Questions