既存の API を Copilot for Microsoft 365 プラグインにする
はじめに
2024/04/15 に API ベースの Teams メッセージ拡張機能を作成できるようになりました。
これまでは Teams メッセージ拡張機能は Microsoft Bot Framework でしか作成できませんでした。この機能により既存の API を追加の開発なしで Teams アプリにできます。また Teams メッセージ拡張機能は Copilot for Microsoft 365 プラグインにもなります。つまり、既存の API を Copilot for Microsoft 365 から利用できるようになります。これは非常に強力なアップデートです。
実際に既存の API を使って Copilot for Microsoft 365 から呼び出せるようにする手順を紹介します。
実行手順
サンプルとして次の API を使用します。
Teams アプリを作成するためには、以下の 3 つのファイルが必要です。これらは開発者ポータルで作成できます。
- アプリ マニフェスト ファイル
- 透明なアイコン ファイル (PNG 形式)
- フル カラーのアイコン ファイル (PNG 形式)
API ベースの Teams メッセージ拡張機能の場合は、追加で以下のファイルが必要です。
- API の OpenAPI 仕様 (JSON 形式または YAML 形式)
- 応答レンダリング テンプレート
追加ファイルの準備
OpenAPI 仕様は以下のライブラリを追加することで利用できるようになります。
フレームワーク | 利用可能なライブラリ |
---|---|
ASP.NET Core Web API | Swashbuckle.AspNetCore |
Azure Functions | Microsoft.Azure.WebJobs.Extensions.OpenApi |
Microsoft のドキュメントでは 2.0 および 3.0.x がサポートされていると記載されていますが、2.0 ではうまく読めなかったため、3.0.x にします。
public static IServiceCollection AddOpenAPI(this IServiceCollection services)
{
_ = services.AddSingleton<IOpenApiConfigurationOptions>(provider => new OpenApiConfigurationOptions()
{
Info = new OpenApiInfo()
{
Version = "1.0.0",
Title = "Zenn Search API"
},
Servers = DefaultOpenApiConfigurationOptions.GetHostNames(),
OpenApiVersion = OpenApiVersionType.V3,
IncludeRequestingHostName = true,
ForceHttps = false,
ForceHttp = false,
});
return services;
}
コードが修正できない場合は、手動で OpenAPI 仕様を作成する必要があります。
応答レンダリング テンプレートは 2 種類のアダプティブ カードを含む JSON 形式ファイルです。アダプティブ カードはデザイナーで作成したものを貼り付けます。
開発者ポータルでの設定
Microsoft Teams の 開発者ポータル(https://dev.teams.microsoft.com) にサインインします。
Apps - New app をクリックし、アプリ名を入力して Add をクリックします。
Basic information でアプリの情報を入力します。これは Copilot for Microsoft 365 からの呼び出しに使用されるため、説明は詳細に記載してください。入力後、Save をクリックします。
App Feature で Message extensions をクリックします。Message extension type で API を選択し、OpenAPI 仕様をアップロードします。Save をクリックします。
成功を示すダイアログが表示されるので Got it をクリックします。
Add をクリックし、API を選択して Next をクリックします。
応答レンダリング テンプレートをアップロードしますが、現時点ではエラーが発生します。
一時的に応答レンダリング テンプレートのバージョンを devPreview にするとアップロードできるようになります。
{
- "version": "1.0",
+ "version": "devPreview",
コマンドの情報を入力します。ここも詳細に記載してください。Add をクリックします。
Save をクリックします。
これでアプリの設定は完了ですが、プレビューをするとエラーが発生します。
エラーの詳細を見るとバージョンが正しくないと表示されます。先ほど書き換えたためです。
version | Value "devPreview" does not match constant "1.0".
開発者ポータルでは直接ファイルを変更できません。アプリ パッケージをダウンロードし、再び 1.0 に修正した上でアップロードし直します。
{
- "version": "devPreview",
+ "version": "1.0",
...
改めてプレビューをするとアプリが追加できるようになります。
認証の設定
API が匿名アクセス可能な場合はこれで設定完了です。API が認証を要求する場合は追加の設定が必要です。API ベースの Teams メッセージ拡張機能は シークレット および Microsoft Entra ID による認証に対応しています。なお シークレット は Bearer トークンのみをサポートしています。今回は Azure Functions の API キーでのアクセスを想定していますが、このままでは利用できません。これに対応するため、Azure API Management を作成し、ポリシーで Bearer トークンを X-Functions-Key ヘッダーに変換します。
<policies>
<inbound>
<base />
<set-backend-service id="apim-generated-policy" backend-id="{{backend-id}}" />
<set-header name="X-Functions-Key" exists-action="override">
<value>@(Regex.Match(context.Request.Headers.GetValueOrDefault("Authorization",""), "^Bearer (?<key>.+)$").Groups["key"]?.Value)</value>
</set-header>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
シークレットはアプリ マニフェスト ファイルに記載するのではなく、開発者ポータルに設定しアプリ マニフェスト ファイルから参照する形になります。開発者ポータルで Tools - API key registration - Create an API Key をクリックします。
Add secret をクリックし、シークレット (今回は Azure Functions の関数キー) を入力して Save をクリックします。
API の情報を入力して Save をクリックします。Target Teams app については開発中は Any Teams app で問題ありませんが、通常は Exsiting Teams app に設定することをおすすめします。
作成された API キーの Registration ID をコピーします。
Registration ID をアプリ マニフェスト ファイルに設定します。これも開発者ポータルから設定できないため、アプリ パッケージをダウンロードして修正し、アップロードします。
{
...
"composeExtensions": [
{
"composeExtensionType": "apiBased",
"authorization": {
"authType": "apiSecretServiceAuth",
"apiSecretServiceAuthConfiguration": {
"apiSecretRegistrationId": "{{registration-id}}"
}
},
...
}
]
...
}
実行結果
まずはメッセージ拡張機能のみで動作することを確認します。チャットで拡張機能を表示して検索すると、検索結果が表示されることを確認できます。
次に Copilot での動作を確認します。Copilot チャットで拡張機能をオンにします。
Copilot に質問すると、検索結果をもとに回答できることが確認できます。
おわりに
追加のプログラミングなしで既存の API を Copilot for Microsoft 365 に統合できることがわかりました。いくつか難しい設定や開発者ポータルの不具合もあるため、今後の改善に期待したいところです。ぜひ試してみてください。
Discussion