Office Add-ins の add-in command (カスタム Ribbon ボタン)

de:code 2015 の「Office 開発/Office 365 開発の新機能紹介」でもデモしていたアドイン コマンド (リボン コマンド) が、まずは Outlook の Mail Add-in で試せるようになったので紹介したい。

追記 : Office Add-in Command は、Excel Add-in、Word Add-in、PowerPoint Add-in でも可能になった。Outlook 以外で追加した場合、「個人用アドイン」(My Add-in) に登録されている間、常にアプリ (Excel、Word、PowerPoint) に表示される。(ドキュメント単位ではなく、アプリ単位の挿入。)
PowerPoint Add-in の “Pickit Presentation Images” などで確認できるので、是非試してみてほしい。

平たく書くと、Office Add-ins の Mail Add-ins (Mail Add-in for Outlook) で下図のような ribbon command (ボタンを押すと実行できる処理) が使えるようになったというもので、動作させるには、今のところ Windows 版の Outlook 2016 (現在 Preview) が必要だ。(いずれ Outlook Web App やその他の Native の Outlook などでも対応されるだろう。)

addin_command

これまでの Mail Add-ins では、一度、Taskpane などの形で何某かの Window (Pane) を表示して、そこに必要なボタンなどのコントロールを配置してアプリを作るしかなかったが、こうした Window (Pane) が不要なストレートな処理は、今後は上述の Add-in Command を使って作ることが可能だ。

Manifest の記述方法

今回の新機能では、Manifest (Office Add-ins で作成する .xml ファイル) の記述も大幅に拡張されているが、Office Add-ins (および、JavaScript Library) 自体のバージョンがあがるわけではなく、既存のバージョンの拡張として実装されているらしく、上述の通り、この機能が使えないプラットフォームもあるという点に注意が必要だ。例えば、Outlook 2013 から使用した際に、不明な XML 要素によりエラーが発生するようなケースは避ける必要がある。

そこで、Manifest 作成のアプローチとして、そのまま Add-in Command 用の記述を入れるのではなく、いったん過去のプラットフォーム互換な Manifest を作成し、新しいプラットフォーム (Outlook 2016 など) で使用された場合には、その内容を override するというアプローチで Manifest を記述する。

この際 必要になるのが、VersionOverrides 要素だ。
Manifest には下記の通り記述し、この VersionOverrides の中に Add-in Command 用の設定を書いていく。(この中身は、このあと作成する。)

<?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>{9AADFD5D-49A0-47C8-897F-1BB59D5116B5}</Id>
  <Version>1.0</Version>
  <ProviderName>Microsoft</ProviderName>
  <DefaultLocale>en-us</DefaultLocale>
  <DisplayName DefaultValue="My App Test"></DisplayName>
  <Description DefaultValue="This is a test"></Description>
  <Requirements>
    <Sets DefaultMinVersion="1.1">
      <Set Name="Mailbox" />
    </Sets>
  </Requirements>
  <FormSettings>
    <Form xsi:type="ItemRead">
      <DesktopSettings>
        <SourceLocation
          DefaultValue="https://addintest01.azurewebsites.net/app1.html" >
        </SourceLocation>
        <RequestedHeight>150</RequestedHeight>
      </DesktopSettings>
    </Form>
    <Form xsi:type="ItemEdit">
      <DesktopSettings>
        <SourceLocation
          DefaultValue="https://addintest01.azurewebsites.net/app2.html" >
        </SourceLocation>
      </DesktopSettings>
    </Form>
  </FormSettings>
  <Permissions>ReadWriteItem</Permissions>
  <Rule xsi:type="RuleCollection" Mode="Or">
    <Rule xsi:type="ItemIs"
      ItemType="Message"
      FormType="Edit" />
    <Rule xsi:type="ItemIs"
      ItemType="Appointment"
      FormType="Edit" />
  </Rule>
  <DisableEntityHighlighting>true</DisableEntityHighlighting>
  <VersionOverrides
    xmlns="http://schemas.microsoft.com/office/mailappversionoverrides"
    xsi:type="VersionOverridesV1_0">
    <!-- we will write here later -->
  </VersionOverrides>
</OfficeApp>

例えば、ボタンを押したら、ある JavaScript 関数を実行する場合は、以下の通りプログラミングする。

まず、下記の JavaScript 関数を含む html ファイルをどこかインターネット上の見える場所に配置しておく。(今回、これを myfunc.html という名前で公開する。)
なお、下記では単にメールの返信画面を起動しているが、JavaScript API for Office の Mail 関連の API では、アイテム変更 (Compose の際)、EWS の呼び出しなど多くのことが可能なので、COM アドインに匹敵する細かな処理を記述することが可能だ。

<meta http-equiv="X-UA-Compatible" content="IE=9" >
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
  <title>My Test Page</title>
  <script type="text/javascript"
    src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.debug.js">
  </script>
  <script type="text/javascript">
  Office.initialize = function (reason) 
  {
    //// you can initialize here
    //_Om = Office.context.mailbox;
    //_Item = _Om.item;
    //_UserProfile = _Om.userProfile;
  }

  function showTest(event)
  {
    //// if you need source control, do below
    //var buttonId = event.source.id;

    // if in compose, displayReplyForm does not work ...
    Office.context.mailbox.item.displayReplyForm('reply test !');
	
    //// when compose mode, you can do below
    //
    //_Item.setSubjectAsync('Hello World!');
    //
    //Office.context.mailbox.item.body.prependAsync(
    //  'test!',
    //  {
    //    coercionType: Office.CoercionType.Text,
    //    asyncContext: { ... }
    //  },
    //  function(asyncResult) {
    //    event.completed(true);
    //  });
    
    event.completed();
  }
  </script>
</head>
<body>
</body>
</html>

そして、前述の Manifest 内の VersionOverrides に以下の通り記述する。
ここでは、Ribbon Button を配置し、このボタンが押された際に、上記の関数 showTest を呼び出している。

<VersionOverrides
  xmlns="http://schemas.microsoft.com/office/mailappversionoverrides"
  xsi:type="VersionOverridesV1_0">

  <Description resid="residDesc" />

  <Requirements>
    <bt:Sets DefaultMinVersion="1.3">
      <bt:Set Name="Mailbox" />
    </bt:Sets>
  </Requirements>

  <Hosts>
    <Host xsi:type="MailHost">

      <DesktopFormFactor>
        <FunctionFile resid="residFuncUrl" />

        <ExtensionPoint xsi:type="MessageReadCommandSurface">
          <OfficeTab id="TabDefault">
            <Group id="msgreadTabMessage.grp1">
              <Label resid="residLabel" />
              <Tooltip resid="residLabelTip" />
 
              <Control xsi:type="Button" id="button1id">
                <Label resid="residUILessButton" />
                <Tooltip resid="residTip" />
                <Supertip>
                  <Title resid="residSuperTipTitle" />
                  <Description resid="residSuperTipDesc" />
                </Supertip>
                <Icon>
                  <bt:Image size="16" resid="icon1" />
                  <bt:Image size="32" resid="icon2" />
                  <bt:Image size="80" resid="icon3" />
                </Icon>
                <Action xsi:type="ExecuteFunction">
                  <FunctionName>showTest</FunctionName>
                </Action>
              </Control>

            </Group>
          </OfficeTab>
        </ExtensionPoint>
      </DesktopFormFactor>
    </Host>
  </Hosts>

  <Resources>
    <bt:Images>
      <bt:Image id="icon1"
        DefaultValue="https://addintest01.azurewebsites.net/myimg16.bmp" >
      </bt:Image>
      <bt:Image id="icon2"
        DefaultValue="https://addintest01.azurewebsites.net/myimg32.bmp" >
      </bt:Image>
      <bt:Image id="icon3"
        DefaultValue="https://addintest01.azurewebsites.net/myimg80.bmp">
      </bt:Image>
    </bt:Images>
    <bt:Urls>
      <bt:Url id="residFuncUrl"
        DefaultValue="https://addintest01.azurewebsites.net/myfunc.html" >
      </bt:Url>
    </bt:Urls>
    <bt:ShortStrings>
      <bt:String id="residLabel"
        DefaultValue="Test App">
      </bt:String>
      <bt:String id="residUILessButton"
        DefaultValue="Do Func">
      </bt:String>
      <bt:String id="residSuperTipTitle"
        DefaultValue="SuperTip Title">
      </bt:String>
    </bt:ShortStrings>
    <bt:LongStrings>
      <bt:String id="residDesc"
        DefaultValue="This is an add-in test.">
      </bt:String>
      <bt:String id="residLabelTip"
        DefaultValue="This is an add-in test.">
      </bt:String>
      <bt:String id="residTip"
        DefaultValue="Run Test app">
      </bt:String>
      <bt:String id="residSuperTipDesc"
        DefaultValue="Run Test App">
      </bt:String>
    </bt:LongStrings>
  </Resources>

</VersionOverrides>

この Add-in を登録して Outlook 2016 で開くと、下図の通り、Mail の Read の際に Custom の Button が表示される。

execute01

このボタンをクリックすると、下図の通り、選択したメールの Reply 画面が起動する。

mail_popup

ExtensionPoint の type に指定している MessageReadCommandSurface は、「Mail の Read の画面にボタンを配置」という意味だ。ここに別の type を指定することで、Compose (メール作成・変更) の画面にボタンを配置したり、予定 (Appointment) の作成や閲覧の画面にボタンを配置することが可能だ。
また、command button ではなく、従来通りの custom pane を配置する場合、今後は、この type に CustomPane と指定して内容を記述できるようになっている。(過去のバージョンにも対応させる場合は、上述のような VersionOverrides の外の定義と、この定義の両方を書いておく必要があるだろう。)

また、Action の type に注目してほしい。
上記では ExecuteFunction を指定しているが、ここに下記の通り ShowTaskpane と指定すると、ボタンを押した際に Taskpane を表示させることが可能だ。

<VersionOverrides
  xmlns="http://schemas.microsoft.com/office/mailappversionoverrides"
  xsi:type="VersionOverridesV1_0">

  <!-- skip here ... (same as above) -->

  <Hosts>
    <Host xsi:type="MailHost">

      <DesktopFormFactor>
        <FunctionFile resid="residFuncUrl" />

        <ExtensionPoint xsi:type="MessageReadCommandSurface">
          <OfficeTab id="TabDefault">
            <Group id="msgreadTabMessage.grp1">
              <Label resid="residLabel" />
              <Tooltip resid="residLabelTip" />
 
              <Control xsi:type="Button" id="button1id">
                <Label resid="residUILessButton" />
                <Tooltip resid="residTip" />
                <Supertip>
                  <Title resid="residSuperTipTitle" />
                  <Description resid="residSuperTipDesc" />
                </Supertip>
                <Icon>
                  <bt:Image size="16" resid="icon1" />
                  <bt:Image size="32" resid="icon2" />
                  <bt:Image size="80" resid="icon3" />
                </Icon>
                <Action xsi:type="ExecuteFunction">
                  <FunctionName>showTest</FunctionName>
                </Action>
              </Control>

              <Control xsi:type="Button" id="button2id">
                <Label resid="residTaskpaneButton" />
                <Tooltip resid="residTip" />
                <Supertip>
                  <Title resid="residSuperTipTitle" />
                  <Description resid="residSuperTipDesc" />
                </Supertip>
                <Icon>
                  <bt:Image size="16" resid="icon1" />
                  <bt:Image size="32" resid="icon2" />
                  <bt:Image size="80" resid="icon3" />
                </Icon>
	              <Action xsi:type="ShowTaskpane">
	                <SourceLocation resid="residTaskpaneUrl" />
	              </Action>
              </Control>
              
            </Group>
          </OfficeTab>
        </ExtensionPoint>
      </DesktopFormFactor>
    </Host>
  </Hosts>

  <Resources>
    <bt:Images>
      <bt:Image id="icon1"
        DefaultValue="https://addintest01.azurewebsites.net/myimg16.bmp" >
      </bt:Image>
      <bt:Image id="icon2"
        DefaultValue="https://addintest01.azurewebsites.net/myimg32.bmp" >
      </bt:Image>
      <bt:Image id="icon3"
        DefaultValue="https://addintest01.azurewebsites.net/myimg80.bmp">
      </bt:Image>
    </bt:Images>
    <bt:Urls>
      <bt:Url id="residFuncUrl"
        DefaultValue="https://addintest01.azurewebsites.net/myfunc.html" >
      </bt:Url>
      <bt:Url id="residTaskpaneUrl"
        DefaultValue="https://addintest01.azurewebsites.net/mypane.html" >
      </bt:Url>
    </bt:Urls>
    <bt:ShortStrings>
      <bt:String id="residLabel"
        DefaultValue="Test App">
      </bt:String>
      <bt:String id="residUILessButton"
        DefaultValue="Do Func">
      </bt:String>
      <bt:String id="residTaskpaneButton"
        DefaultValue="Show Pane">
      </bt:String>
      <bt:String id="residSuperTipTitle"
        DefaultValue="SuperTip Title">
      </bt:String>
    </bt:ShortStrings>
    <bt:LongStrings>
      <bt:String id="residDesc"
        DefaultValue="This is an add-in test.">
      </bt:String>
      <bt:String id="residLabelTip"
        DefaultValue="This is an add-in test.">
      </bt:String>
      <bt:String id="residTip"
        DefaultValue="Run Test app">
      </bt:String>
      <bt:String id="residSuperTipDesc"
        DefaultValue="Run Test App">
      </bt:String>
    </bt:LongStrings>
  </Resources>

</VersionOverrides>

[Show Pane] ボタンを押すと、下図の通り、指定した Url のページが Pane として表示される。
もちろん、この Web ページに、これまでの Mail Add-in のように、メールや予定と連携して動作する何某かの処理 (JavaScript) を埋め込んで使うことが可能だ。

execute02

最終的に作成した Manifest のサンプルを以下に掲載しておくので、コピーして、是非試してみていただきたい。(ただし、下記の Id などは変更しておくこと。)

なお、つい最近、この新機能に関する ドキュメントがリリースされたようなので、是非、参考にされたし !

Office Dev Center : Overview of add-in commands for mail

Office Dev Center : Create a manifest for add-in commands

<?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>{9AADFD5D-49A0-47C8-897F-1BB59D5116B5}</Id>
  <Version>1.0</Version>
  <ProviderName>Microsoft</ProviderName>
  <DefaultLocale>en-us</DefaultLocale>
  <DisplayName DefaultValue="My App Test"></DisplayName>
  <Description DefaultValue="This is a test"></Description>
  <Requirements>
    <Sets DefaultMinVersion="1.1">
      <Set Name="Mailbox" />
    </Sets>
  </Requirements>

  <FormSettings>
    <Form xsi:type="ItemRead">
      <DesktopSettings>
        <SourceLocation
          DefaultValue="https://addintest01.azurewebsites.net/app1.html" >
        </SourceLocation>
        <RequestedHeight>150</RequestedHeight>
      </DesktopSettings>
    </Form>
    <Form xsi:type="ItemEdit">
      <DesktopSettings>
        <SourceLocation
          DefaultValue="https://addintest01.azurewebsites.net/app2.html" >
        </SourceLocation>
      </DesktopSettings>
    </Form>
  </FormSettings>
  <Permissions>ReadWriteItem</Permissions>
  <Rule xsi:type="RuleCollection" Mode="Or">
    <Rule xsi:type="ItemIs"
      ItemType="Message"
      FormType="Edit" />
    <Rule xsi:type="ItemIs"
      ItemType="Appointment"
      FormType="Edit" />
  </Rule>
  <DisableEntityHighlighting>true</DisableEntityHighlighting>

  <VersionOverrides
    xmlns="http://schemas.microsoft.com/office/mailappversionoverrides"
    xsi:type="VersionOverridesV1_0">

    <Description resid="residDesc" />

    <Requirements>
      <bt:Sets DefaultMinVersion="1.3">
        <bt:Set Name="Mailbox" />
      </bt:Sets>
    </Requirements>

    <Hosts>
      <Host xsi:type="MailHost">

        <DesktopFormFactor>
          <FunctionFile resid="residFuncUrl" />

          <ExtensionPoint xsi:type="MessageReadCommandSurface">
            <OfficeTab id="TabDefault">
              <Group id="msgreadTabMessage.grp1">
                <Label resid="residLabel" />
                <Tooltip resid="residLabelTip" />
 
                <Control xsi:type="Button" id="button1id">
                  <Label resid="residUILessButton" />
                  <Tooltip resid="residTip" />
                  <Supertip>
                    <Title resid="residSuperTipTitle" />
                    <Description resid="residSuperTipDesc" />
                  </Supertip>
                  <Icon>
                    <bt:Image size="16" resid="icon1" />
                    <bt:Image size="32" resid="icon2" />
                    <bt:Image size="80" resid="icon3" />
                  </Icon>
                  <Action xsi:type="ExecuteFunction">
                    <FunctionName>showTest</FunctionName>
                  </Action>
                </Control>
                
                <Control xsi:type="Button" id="button2id">
                  <Label resid="residTaskpaneButton" />
                  <Tooltip resid="residTip" />
                  <Supertip>
                    <Title resid="residSuperTipTitle" />
                    <Description resid="residSuperTipDesc" />
                  </Supertip>
                  <Icon>
                    <bt:Image size="16" resid="icon1" />
                    <bt:Image size="32" resid="icon2" />
                    <bt:Image size="80" resid="icon3" />
                  </Icon>
	                <Action xsi:type="ShowTaskpane">
	                  <SourceLocation resid="residTaskpaneUrl" />
	                </Action>
                </Control>

              </Group>
            </OfficeTab>
          </ExtensionPoint>
        </DesktopFormFactor>
      </Host>
    </Hosts>

    <Resources>
      <bt:Images>
        <bt:Image id="icon1"
          DefaultValue="https://addintest01.azurewebsites.net/myimg16.bmp" >
        </bt:Image>
        <bt:Image id="icon2"
          DefaultValue="https://addintest01.azurewebsites.net/myimg32.bmp" >
        </bt:Image>
        <bt:Image id="icon3"
          DefaultValue="https://addintest01.azurewebsites.net/myimg80.bmp">
        </bt:Image>
      </bt:Images>
      <bt:Urls>
        <bt:Url id="residFuncUrl"
          DefaultValue="https://addintest01.azurewebsites.net/myfunc.html" >
        </bt:Url>
        <bt:Url id="residTaskpaneUrl"
          DefaultValue="https://addintest01.azurewebsites.net/mypane.html" >
        </bt:Url>
      </bt:Urls>
      <bt:ShortStrings>
        <bt:String id="residLabel"
          DefaultValue="Test App">
        </bt:String>
        <bt:String id="residUILessButton"
          DefaultValue="Do Func">
        </bt:String>
        <bt:String id="residTaskpaneButton"
          DefaultValue="Show Pane">
        </bt:String>
        <bt:String id="residSuperTipTitle"
          DefaultValue="SuperTip Title">
        </bt:String>
      </bt:ShortStrings>
      <bt:LongStrings>
        <bt:String id="residDesc"
          DefaultValue="This is an add-in test.">
        </bt:String>
        <bt:String id="residLabelTip"
          DefaultValue="This is an add-in test.">
        </bt:String>
        <bt:String id="residTip"
          DefaultValue="Run Test app">
        </bt:String>
        <bt:String id="residSuperTipDesc"
          DefaultValue="Run Test App">
        </bt:String>
      </bt:LongStrings>
    </Resources>

  </VersionOverrides>
</OfficeApp>
Advertisements

One thought on “Office Add-ins の add-in command (カスタム Ribbon ボタン)

  1. Pingback: [Officeアドイン]アドイン コマンド(Add-In Commands)の紹介 | 初心者備忘録

Comments are closed.