Slack Bolt for JavaScript アプリを Teams に移植する

このガイドは、既存の Slack Bolt for JavaScript アプリケーションを Teams に移植するのに役立ちます。

概要

Slack Bolt と同様に、Teams SDK は、会話型アプリケーションを構築するための Teams バックエンド API とインターフェイスするように設計されています。 どちらの SDK も、受信イベント、メッセージ、および相互作用を処理し、ユーザーに応答を送り返すための抽象化を提供します。 既に Slack ボットをお持ちの場合は、概念に馴染みがあるはずです。

ただし、アプリのインストールなど、いくつかの重要な違いがあります。 Slack では、アプリは OAuth 経由でワークスペースにインストールされますが、Teams では Teams App Store 経由でインストールされます。 さらに、Teams アプリは、個々のユーザーが個人的にインストールすることも、グループ チャット、チャネル、会議などの共同作業スコープにインストールすることもできます。

Slack と Teams の概念の類似点と相違点をいくつか見てみましょう。

概念 Teams 余裕期間
インストール スコープごとにアプリ ストア経由でインストール OAuth 経由でワークスペースにインストール
クイックスタート Teams 開発者 CLI を使用して作成された新しいプロジェクト Slack CLI を使用して作成された新しいプロジェクト。
アプリ マニフェスト エージェントとそのアプリ マニフェストを作成し、Teams 開発者 CLI に登録します。 JSON、YAML、またはアプリ管理ページを使用して作成。
メッセージング エンドポイント Teams 開発者ポータルのボット構成または Azure AI Bot Service リソースで設定します。 Slack アプリ マニフェストで設定。
アプリケーション認証 Entra アプリの登録は、Teams アプリのインストール中に承認されます。 Teams SDK は、メッセージを送信するときに Entra アプリ トークンを内部で取得します。 メッセージングなどのコア アプリ機能では、この認証の種類が SDK の内部的に使用されます。 ユーザーがアプリケーションによって委任されたスコープ (例: incoming-webhook,commands) を承認した後、アプリは Slack ボット トークンを格納します。 メッセージングなどのコア アプリ機能では、この認証の種類が SDK の内部的に使用されます。
REST API のユーザー認証 ユーザー Entra トークンは、Teams SSO を使用して取得できます。 Graph REST API は Teams SDK に統合されています。 トークンは、Azure ボット トークン サービスによって保存および更新されます。 ユーザーの Slack トークンは、OAuth 2.0 を使用して取得できます。 Slack REST API は Slack Bolt に統合されています。 トークンは、アプリケーションによって格納および更新される必要があります。
外部サービスでの認証 OAuth 2.0 を使用して外部サービスのユーザー アクセス トークンを取得します。 トークンは、Azure ボット トークン サービスによって保存および更新されます。 ユーザーは、OAuth 2.0 を使用して外部サービスに対する認証を行います。これは、おそらくアカウント バインドを介して開始されます (下記参照)。 トークンは、アプリケーションによって格納および更新される必要があります。
アカウント リンク Activity イベントには、ユーザーの AAD オブジェクト ID である Activity.from.id が含まれます。 OAuth 2.0 で外部サービスを認証する場合、これらのアカウントは Azure トークン サービスを介して暗黙的にバインドされますが、Slack が推奨するのと同様のフローに従うこともできます。 Slack では、「 サービス間でアカウントをバインドする」 ガイドに従うことを推奨しています。
カード アダプティブ カードを使用したメッセージ内の豊富な UI 要素。 ブロック キットを使用したメッセージ内の豊富な UI 要素。
ファイル Files は、SharePoint / OneDrive Graph API を使用して添付またはダウンロードできます。 Files は、Slack のファイル API を介して添付またはダウンロードできます。
グループ会話でのプライベート メッセージ 対象となるメッセージ エフェメラル メッセージ。
スラッシュ コマンド アプリ マニフェストで宣言され、オートコンプリート メニューを使用して検出可能にされたスラッシュ コマンド。 コマンドは、プライベート ターゲット メッセージとして送信することも、 @mention を介して会話のすべてのユーザーに表示することもできます。 コマンドはメッセージとして送信されます。app.message('/command') または app.message(regexp) 経由で、app.message ハンドラーを使用してコマンドをリッスンします。 Slack Bolt には、Slack アプリ マニフェストのコマンド専用の app.command ハンドラーがあります。 スラッシュ コマンドは、コラボレーション コンテキストで他のユーザーに表示されません。
ワークフロー Teams は、ワークフロー向け Power Automate と統合されています。 ワークフローは Teams SDK のコンポーネントではありません。 Slack ワークフローは Slack Bolt と統合されています。
UI ダイアログ アダプティブ カードには、埋め込み Web サイトまたは別のアダプティブ カードを使用して UI ダイアログを開くアクションを含めることができます。 ダイアログはアダプティブ カード アクションで開く必要があるため、スラッシュ コマンドで直接開くことはできません。 ブロック キット UI モーダルは、スラッシュ コマンド ( client.views.open を使用) またはブロック キット アクションを使用して開くことができます。
AI 戦略 Teams には、ユーザー フィードバック、AI によって生成されたラベル、プロンプトの提案、ストリーミング、引用などに関する独自の AI ネイティブの機能があります。 また、LLM をボットに簡単に統合できるオプションの ChatPrompt クラスも用意されています。 Microsoft 365 Copilot Retrieval Graph API を介してグラウンディング検索を活用します。 AI 機能は通常、あらゆる会話タイプで使用するように設計されています。 Slack には、エージェントのサイドパネル ビューでの AI 対話専用の Assistant クラスがあります。これは、既存のボットの対話パターンを使用する Teams の戦略とは異なります。 標準のボット API を使用して、他の会話の種類で AI を引き続き使用できます。 固定検索に Slack データ アクセス API を使用できます。
AI ユーザー フィードバック ユーザー フィードバック ボタンは、フィードバックを処理するための専用 API を使用して、Teams でネイティブにレンダリングされます。 ユーザーが肯定的または否定的なフィードバックを提供すると、追加情報 (プレーン テキストの応答など) をキャプチャできるモーダルが開きます。 Slack では、専用の feedback_buttons ブロック キット要素の種類と app.action('feedback') を使用して、ユーザー フィードバック (肯定的または否定的) をメッセージに添付します。

Teams エージェントを登録する

まず、 クイックスタート を完了して新しい Teams エージェントを登録し、Teams SDK 実装を既存のアプリに追加するとすぐに Teams からそれを使用できるようにします。

Teams SDK のインストール

Teams SDK を Slack Bolt プロジェクトにインストールします。

npm install @microsoft/teams.apps

認証構成のコピー

クイックスタート スターター アプリケーションで Teams 開発者 CLI によって作成された .env ファイルから、設定を Slack Bolt の実装にコピーします。 これらの設定は、Teams SDK アプリが Teams と通信できるように認証するための資格情報です。

ランタイムを初期化する

App クラスを使用して Teams SDK アプリケーション ランタイムを起動するために、実装にコードを追加または置換します。 これは、Slack Bolt の App クラスと同等です。

import { App } from '@microsoft/teams.apps';

const app = new App();

app.start(process.env.PORT || 3978).catch(console.error);

メッセージ ハンドラーを追加する

Slack には、さまざまなサブタイプを持つイベントのメッセージ ハンドラーがあります (たとえば、未定義のサブタイプは通常のメッセージ、 event.subtype == 'file_share' ファイル共有メッセージなど)。 Teams には、ActivityTypes 列挙型を使用して列挙されるイベントの種類ごとに異なる Activity ハンドラー (例: app.activity(ActivityTypes.Message)) があります。一部のActivityの種類には、SDK 内で調整された API (例: app.message) があります。 これらの概念はほぼ似ていますが、命名規則と構文は異なります。

// triggers when user sends "hi" or "@bot hi"
app.message("hi", async ({ send, activity }) => {
    await send(`Hello, ${activity.from.name}!`);
});
// listen for ANY message to be received
app.on('message', async ({ send, activity }) => {
    // echo back users request
    await send(`you said: ${activity.text}`);
});

ブロック キットの使用状況をアダプティブ カードに変換する

エージェントから送信されたメッセージにリッチ UI を含めるために、Teams のアダプティブ カードは Slack のブロック キットに相当します。

import { Card, TextBlock } from '@microsoft/teams.cards';

app.message('/card', async ({ send }) => {
    await send(
        new Card(new TextBlock('Hello, world!', { wrap: true, isSubtle: false }))
            .withOptions({
                width: 'Full',
            })
    );
});

ユーザー認証を実装する

Teams と Slack のユーザー認証には、主に 2 種類があります。Slack & Graph REST API の認証と外部サービスの認証です。 それぞれを順番に見ていきましょう。

ユーザー委任 REST API

Slack で、ユーザーが委任したスコープを必要とする Slack REST API を使用する場合は、アプリが既に別のユーザーによってインストールされていてもかまい、Slack ユーザー トークンを取得して保存するために、アプリケーションに OAuth 2.0 インストール フローを実装する必要があります。 Teams では、Teams SSO を利用して、Graph REST API を呼び出すためのユーザー Entra トークンを取得できます。 Teams SDK は、Teams SSO および Azure ボット トークン サービスと統合され、トークンの取得、保存、更新を自動的に処理します。

まず、 Teams SSO ガイドの指示に従います。 次に、コードで認証を構成します。

const app = new App({
    // ... rest of App config
    oauth: {
        // The key here should match the OAuth Connection setting
        // defined in your Azure Bot resource.
        defaultConnectionName: 'graph',
    },
});

app.message('me', async ({ signin, userGraph, send }) => {
    if (!await signin()) {
        return;
    }
    const me = await userGraph.call(endpoints.me.get);
    await send(JSON.stringify(me));
});

外部サービスのユーザー認証

Slack では、 ここに記載されているように、OAuth 2.0 を使用してアカウント バインド フローを実装することで、外部サービスにアクセスできます。 Teams では、OAuth 2.0 フローを実装することで外部サービスにアクセスでき、Azure Bot Token Service がトークンの取得、保存、更新を自動的に処理します。

まず、Azure Bot リソースの Azure portal で OAuth 2.0 接続設定を設定します。

Azure ボットのカスタム OAuth 接続設定を示すスクリーンショット。

次に、認証コードをアプリケーションに追加して、関連するユーザー トークンを取得し、外部サービスを呼び出します。

import
{ App } from '@microsoft/teams.apps';

const app = new App({
    // ... rest of App config
    oauth: {
        // The key here should match the OAuth Connection setting
        // defined in your Azure Bot resource.
        defaultConnectionName: 'custom',
    },
});

app.message('me', async ({ activity, signin, token, send }) => {
    // In production, it is probably better to implement a local cache.
    // (e.g. \`activity.from.id\` <-> token).
    // Otherwise this triggers an API call to Azure Token Service on every inbound message.
    if (!await signin()) {
        return;
    }

    // Call external API
    const response = await fetch('https://example.com/api/helloworld', {
        method: 'POST',
        headers: {
            "Authorization": token,
        },
    });
    const result = await response.json();
    await send(JSON.stringify(result));
});