ラボ M3 - 新しい検索コマンドでプラグインを拡張
このラボでは、Northwind プラグインに新しいコマンドを追加して拡張します。現在のメッセージ拡張機能は Northwind 在庫データベース内の製品情報を提供できますが、Northwind の顧客に関する情報は提供できません。ユーザーが指定した会社名で注文された製品を取得する API 呼び出しに関連付けられた新しいコマンドを追加してください。
Extend Teams Message Extension ラボのナビゲーション (Extend Path)
NOTE
すべてのコード変更を含む完成版は こちら からダウンロードできます。トラブルシューティング時に便利です。
編集内容をリセットしたい場合は、リポジトリを再クローンしてやり直すことができます。
演習 1 - コード変更
手順 1 - Message Extension / プラグインのユーザー インターフェースを拡張する
前のラボで作成した作業ディレクトリ Northwind 内の appPackage フォルダーにある manifest.json を開きます。
commands 配列内で discountSearch
を探します。discountSearch
コマンドの閉じかっこの後ろにカンマ ( , ) を追加します。その後、companySearch
コマンドのスニペットをコピーして commands 配列に追加してください。
{
"id": "companySearch",
"context": [
"compose",
"commandBox"
],
"description": "Given a company name, search for products ordered by that company",
"title": "Customer",
"type": "query",
"parameters": [
{
"name": "companyName",
"title": "Company name",
"description": "The company name to find products ordered by that company",
"inputType": "text"
}
]
}
COMMAND_ID
"id" は UI とコードを結び付けるキーです。この値は discount/product/SearchCommand.ts
ファイルで COMMAND_ID
定数として定義されています。各ファイルには固有の COMMAND_ID
があり、"id" の値と対応しています。
手順 2 - 会社名での製品検索を実装する
会社名で製品を検索し、その会社が注文した製品一覧を返す機能を実装します。必要な情報は下記のテーブルから取得できます。
Table | Find | Look Up By |
---|---|---|
Customer | Customer Id | Customer Name |
Orders | Order Id | Customer Id |
OrderDetail | Product | Order Id |
仕組みは以下のとおりです。
Customer テーブルで Customer Name から Customer Id を取得します。その Customer Id で Orders テーブルを照会し、関連する Order Id を取得します。各 Order Id について OrderDetail テーブルから関連する製品を取得し、最終的に指定した会社名で注文された製品の一覧を返します。
.\src\northwindDB\products.ts を開きます。
1 行目の import
文を更新し、OrderDetail
, Order
, Customer
を含めます。以下のようになります。
import {
TABLE_NAME, Product, ProductEx, Supplier, Category, OrderDetail,
Order, Customer
} from './model';
import { getInventoryStatus } from '../adaptiveCards/utils';
の直後に、下記スニペットのとおり searchProductsByCustomer()
関数を追加します。
export async function searchProductsByCustomer(companyName: string): Promise<ProductEx[]> {
let result = await getAllProductsEx();
let customers = await loadReferenceData<Customer>(TABLE_NAME.CUSTOMER);
let customerId="";
for (const c in customers) {
if (customers[c].CompanyName.toLowerCase().includes(companyName.toLowerCase())) {
customerId = customers[c].CustomerID;
break;
}
}
if (customerId === "")
return [];
let orders = await loadReferenceData<Order>(TABLE_NAME.ORDER);
let orderdetails = await loadReferenceData<OrderDetail>(TABLE_NAME.ORDER_DETAIL);
// build an array orders by customer id
let customerOrders = [];
for (const o in orders) {
if (customerId === orders[o].CustomerID) {
customerOrders.push(orders[o]);
}
}
let customerOrdersDetails = [];
// build an array order details customerOrders array
for (const od in orderdetails) {
for (const co in customerOrders) {
if (customerOrders[co].OrderID === orderdetails[od].OrderID) {
customerOrdersDetails.push(orderdetails[od]);
}
}
}
// Filter products by the ProductID in the customerOrdersDetails array
result = result.filter(product =>
customerOrdersDetails.some(order => order.ProductID === product.ProductID)
);
return result;
}
手順 3 - 新しいコマンド用のハンドラーを作成する
VS Code で src/messageExtensions フォルダーにある productSearchCommand.ts を複製し、コピーしたファイル名を customerSearchCommand.ts
に変更します。
COMMAND_ID
定数の値を以下のように変更してください。
const COMMAND_ID = "companySearch";
下記の import 文を:
import { searchProducts } from "../northwindDB/products";`
から
import { searchProductsByCustomer } from "../northwindDB/products";
へ置き換えます。
handleTeamsMessagingExtensionQuery の既存の波かっこの中身を下記スニペットに差し替えます。
let companyName;
// Validate the incoming query, making sure it's the 'companySearch' command
// The value of the 'companyName' parameter is the company name to search for
if (query.parameters.length === 1 && query.parameters[0]?.name === "companyName") {
[companyName] = (query.parameters[0]?.value.split(','));
} else {
companyName = cleanupParam(query.parameters.find((element) => element.name === "companyName")?.value);
}
console.log(`🍽️ Query #${++queryCount}:\ncompanyName=${companyName}`);
const products = await searchProductsByCustomer(companyName);
console.log(`Found ${products.length} products in the Northwind database`)
const attachments = [];
products.forEach((product) => {
const preview = CardFactory.heroCard(product.ProductName,
`Customer: ${companyName}`, [product.ImageUrl]);
const resultCard = cardHandler.getEditCard(product);
const attachment = { ...resultCard, preview };
attachments.push(attachment);
});
return {
composeExtension: {
type: "result",
attachmentLayout: "list",
attachments: attachments,
},
};
手順 4 - コマンド ルーティングを更新する
この手順では、companySearch
コマンドを前手順で実装したハンドラーにルーティングします。
src フォルダーにある searchApp.ts を開き、次の import
文を追加します。
import customerSearchCommand from "./messageExtensions/customerSearchCommand";
handleTeamsMessagingExtensionQuery
ハンドラー関数の switch
文に、下記の case
文を追加します。
case customerSearchCommand.COMMAND_ID: {
return customerSearchCommand.handleTeamsMessagingExtensionQuery(context, query);
}
Note
UI ベースの Message Extension / プラグイン操作では、このコマンドが明示的に呼び出されます。しかし Microsoft 365 Copilot から呼び出された場合は、Copilot オーケストレーターによってコマンドがトリガーされます。
演習 2 - アプリを実行して会社名で検索する
これで Microsoft 365 Copilot のプラグインとしてサンプルをテストする準備が整いました。
手順 1: 更新したアプリをローカルで実行する
ローカル デバッガーが動いたままの場合は停止します。新しいコマンドを追加したため、パッケージを新たにインストールする必要があります。
appPackage フォルダー内の manifest.json で manifestVersion
を "1.0.9" から "1.0.10" に更新してください。これによりアプリの変更が反映されます。
F5 キーを押すかスタート ボタン 1️⃣ をクリックしてデバッガーを再起動します。デバッグ プロファイルの選択を求められたら Debug in Teams (Edge) 2️⃣ を選択するか、別のプロファイルを選んでください。
デバッグを開始すると、ブラウザー内で Teams が開きます。Agents Toolkit にサインインしたのと同じ資格情報でログインしてください。
ログインすると Microsoft Teams がアプリを開くかどうか確認するダイアログを表示します。
開くとすぐに、どこでアプリを開くかを尋ねられます。既定ではパーソナル チャットです。チャンネルやグループ チャットも選択できます。[Open] を選択してください。
これでアプリとのパーソナル チャット画面に入ります。しかし今回は Copilot でテストするため、次の手順に進みます。
Teams で Chat をクリックし、続いて Copilot を選択します (最上位に表示されているはずです)。
Plugin アイコン をクリックし、Northwind Inventory を選択してプラグインを有効化します。
手順 2: Copilot で新しいコマンドをテストする
次のプロンプトを入力します。
What are the products ordered by 'Consolidated Holdings' in Northwind Inventory?
ターミナル出力では、Copilot がクエリを理解し companySearch
コマンドを実行して、Copilot が抽出した会社名を渡していることが確認できます。
Copilot での出力例は次のとおりです。
ほかにも次のプロンプトを試してみてください。
What are the products ordered by 'Consolidated Holdings' in Northwind Inventory? Please list the product name, price and supplier in a table.
手順 3: Message Extension としてコマンドをテストする (オプション)
もちろん、この新しいコマンドはサンプルを Message Extension として使用してテストすることもできます(前のラボと同様)。
- Teams のサイドバーで Chats セクションに移動し、任意のチャットを選択するか新しいチャットを開始します。
-
- 記号をクリックして Apps セクションを開きます。
- Northwind Inventory アプリを選択します。
- すると Customer という新しいタブが表示されます。
- Consolidated Holdings を検索して、この会社が注文した製品を確認してください。Copilot で前手順に表示されたものと一致するはずです。
おめでとうございます
これでプラグイン チャンピオンです。次は認証でプラグインを保護しましょう。次のラボに進むには「Next」を選択してください。