Teams で Fluid を使用する

このチュートリアルの終わりまでに、Fluid を利用するアプリケーションを Teams に統合し、他のユーザーとリアルタイムで共同作業を行うことができます。

このセクションでは、次の概念について説明します。

  1. Fluid クライアントを Teams タブ アプリケーションに統合します。
  2. Teams アプリケーションを実行して Fluid サービス (Azure Fluid Relay) に接続します。
  3. Fluid Containers を作成して取得し、React コンポーネントに渡します。

複雑なアプリケーションの構築の詳細については、「 FluidExamples」を参照してください。

前提条件

このチュートリアルでは、次の概念とリソースに精通している必要があります。

プロジェクトを作成する

  1. コマンド プロンプトを開き、プロジェクトを作成する親フォルダー (例: /My Microsoft Teams Projects) に移動します。

  2. 次のコマンドを実行し、チャネル タブを作成して、Teams タブ アプリケーションを作成します

    yo teams
    
  3. 作成後、次のコマンドを使用してプロジェクトに移動します cd <your project name>

  4. プロジェクトでは、次のライブラリが使用されます。

    ライブラリ 説明
    fluid-framework IFluidContainer と、クライアント間でデータを同期するその他 の分散データ構造 が含まれます。
    @fluidframework/azure-client Fluid コンテナーの開始スキーマを定義します。
    @fluidframework/test-client-utils InsecureTokenProvider Fluid サービスへの接続を作成するために必要な を定義します。

    次のコマンドを実行してライブラリをインストールします。

    npm install @fluidframework/azure-client fluid-framework @fluidframework/test-client-utils
    

プロジェクトをコーディングする

  1. コード エディターでファイル /src/client/<your tab name> を開きます。

  2. として Util.ts 新しいファイルを作成し、次の import ステートメントを追加します。

    //`Util.ts
    
    import { IFluidContainer } from "fluid-framework";
    import { AzureClient, AzureClientProps } from "@fluidframework/azure-client";
    import { InsecureTokenProvider } from "@fluidframework/test-client-utils";
    

Fluid 関数とパラメーターの定義

このアプリは、すべての Fluid 関連のインポート、初期化、および関数を一緒に使用して、Microsoft Teams のコンテキストで使用することを目的としています。 これにより、エクスペリエンスが強化され、将来使用しやすくなります。 import ステートメントに次のコードを追加できます。

// TODO 1: Define the parameter key(s).
// TODO 2: Define container schema.
// TODO 3: Define connectionConfig (AzureClientProps).
// TODO 4: Create Azure client.
// TODO 5: Define create container function.
// TODO 6: Define get container function.

注:

コメントは、Fluid サービスとコンテナーと対話するために必要なすべての関数と定数を定義します。

  1. TODO 1: を次のコードに置き換えます。

    export const containerIdQueryParamKey = "containerId";
    

    定数は、Microsoft Teams 設定の に contentUrl 追加され、後でコンテンツ ページでコンテナー ID を解析するためにエクスポートされます。 毎回生の文字列を入力するのではなく、重要なクエリ パラメーター キーを定数として格納するのが一般的なパターンです。

    クライアントがコンテナーを作成するには、このアプリケーションで使用される共有オブジェクトを定義する が必要 containerSchema です。 この例では、 として SharedMap を使用しますが、 initialObjects任意の共有オブジェクトを使用できます。

    注:

    mapは オブジェクトの SharedMap ID であり、他の DDS と同様にコンテナー内で一意である必要があります。

  2. TODO: 2 を次のコードに置き換えます。

    const containerSchema = {
        initialObjects: { map: SharedMap }
    };
    
  3. TODO: 3 を次のコードに置き換えます。

    const connectionConfig : AzureClientProps =
    {
        connection: {
            type: "local",
            tokenProvider: new InsecureTokenProvider("foobar", { id: "user" }),
            endpoint: "http://localhost:7070"
        }
    };
    

    クライアントを使用するには、クライアントが使用する接続の種類を定義する が必要 AzureClientProps です。 connectionConfigサービスに接続するには、 プロパティが必要です。 Azure Client のローカル モードが使用されます。 すべてのクライアント間でコラボレーションを有効にするには、Fluid Relay サービスの資格情報に置き換えます。 詳細については、 Azure Fluid Relay サービスを設定する方法に関するページを参照してください。

  4. TODO: 4 を次のコードに置き換えます。

    const client = new AzureClient(connectionConfig);
    
  5. TODO: 5 を次のコードに置き換えます。

    export async function createContainer() : Promise<string> {
        const { container } = await client.createContainer(containerSchema);
        const containerId = await container.attach();
        return containerId;
    };
    

    構成ページでコンテナーを作成し、Teams 設定の に contentUrl 追加するときは、コンテナーをアタッチした後にコンテナー ID を返す必要があります。

  6. TODO: 6 を次のコードに置き換えます。

    export async function getContainer(id : string) : Promise<IFluidContainer> {
        const { container } = await client.getContainer(id, containerSchema);
        return container;
    };
    

    Fluid コンテナーをフェッチするときは、アプリケーションがコンテナーとその中の DDS をコンテンツ ページで操作する必要があるため、コンテナーを返す必要があります。

構成ページで Fluid コンテナーを作成する

  1. コード エディターでファイル src/client/<your tab name>/<your tab name>Config.tsx を開きます。

    標準の Teams タブ アプリケーション フローは、構成からコンテンツ ページに移動します。 コラボレーションを有効にするには、コンテンツ ページへの読み込み中にコンテナーを永続化することが重要です。 コンテナーを永続化する最善の解決策は、コンテナー ID contentUrlwebsiteUrlを、コンテンツ ページの URL と にクエリ パラメーターとして追加することです。 Teams 構成ページの [保存] ボタンは、構成ページとコンテンツ ページの間のゲートウェイです。 これは、コンテナーを作成し、設定にコンテナー ID を追加する場所です。

  2. 次の import ステートメントを追加します:

    import { createContainer, containerIdQueryParamKey } from "./Util";
    
  3. onSaveHandler メソッドを次のコードに置き換えます。 ここで追加された行は、前Utils.tsに定義した create コンテナー メソッドを呼び出し、返されたコンテナー ID を クエリ パラメーターとして にcontentUrlwebsiteUrl追加することだけです。

    const onSaveHandler = async (saveEvent: microsoftTeams.settings.SaveEvent) => {
        const host = "https://" + window.location.host;
        const containerId = await createContainer();
        microsoftTeams.settings.setSettings({
            contentUrl: host + "/<your tab name>/?" + containerIdQueryParamKey + "=" + containerId + "&name={loginHint}&tenant={tid}&group={groupId}&theme={theme}",
            websiteUrl: host + "/<your tab name>/?" + containerIdQueryParamKey + "=" + containerId + "&name={loginHint}&tenant={tid}&group={groupId}&theme={theme}",
            suggestedDisplayName: "<your tab name>",
            removeUrl: host + "/<your tab name>/remove.html?theme={theme}",
            entityId: entityId.current
        });
        saveEvent.notifySuccess();
    };
    

    をプロジェクトのタブ名に置き換えてください <your tab name>

    警告

    コンテンツ ページ URL はコンテナー ID の格納に使用されるため、[Teams] タブが削除されると、このレコードは削除されます。 さらに、すべてのコンテンツ ページでサポートできるコンテナー ID は 1 つだけです。

Fluid アプリケーションを反映するようにコンテンツ ページをリファクタリングする

  1. コード エディターでファイル src/client/<your tab name>/<your tab name>.tsx を開きます。 一般的な Fluid 電源アプリケーションは、ビューと Fluid データ構造で構成されます。 Fluid コンテナーの取得と読み込みに焦点を当て、すべての Fluid 関連の相互作用をReact コンポーネントに残します。

  2. コンテンツ ページに次の import ステートメントを追加します。

    import { IFluidContainer } from "fluid-framework";
    import { getContainer, containerIdQueryParamKey } from "./Util";
    
  3. コンテンツ ページの import ステートメントの下にあるすべてのコードを削除し、次のコードに置き換えます。

    export const <your tab name> = () => {
      // TODO 1: Initialize Microsoft Teams.
      // TODO 2: Initialize inTeams boolean.
      // TODO 3: Define container as a React state.
      // TODO 4: Define a method that gets the Fluid container
      // TODO 5: Get Fluid container on content page startup.
      // TODO 6: Pass the container to the React component as argument.
    }
    

    は、プロジェクトに対して定義したタブ名に置き換えてください <your tab name>

  4. TODO 1 を次のコードに置き換えます。

    microsoftTeams.initialize();
    

    Teams でコンテンツ ページを表示するには、 Microsoft Teams JavaScript クライアント ライブラリ を含め、ページの読み込み後に初期化するための呼び出しを含める必要があります。

  5. TODO 2 を次のコードに置き換えます。

    const [{ inTeams }] = useTeams();
    

    Teams アプリケーションは Web ページの IFrame インジェクションにすぎませんので、アプリケーションが Teams 内にあるかどうか、および Teams リソース (など) が使用可能かどうかを確認するには、ブール値定数を初期化 inTeams する contentUrl必要があります。

  6. TODO 3 を次のコードに置き換えます。

    const [fluidContainer, setFluidContainer] = useState<IFluidContainer | undefined>(undefined);
    

    コンテナーとコンテナー内のデータ オブジェクトを動的に更新する機能を提供するため、コンテナーのReact状態を使用します。

  7. TODO 4 を次のコードに置き換えます。

    const getFluidContainer = async (url : URLSearchParams) => {
        const containerId = url.get(containerIdQueryParamKey);
        if (!containerId) {
            throw Error("containerId not found in the URL");
        }
        const container = await getContainer(containerId);
        setFluidContainer(container);
    };
    

    URL を分析して、 で定義された containerIdQueryParamKeyクエリ パラメーター文字列を取得し、コンテナー ID を取得します。 コンテナー ID を使用すると、コンテナーを読み込むことができます。 コンテナーが完成したら、React状態をfluidContainer設定します。前の手順を参照してください。

  8. TODO 5 を次のコードに置き換えます。

    useEffect(() => {
        if (inTeams === true) {
            microsoftTeams.settings.getSettings(async (instanceSettings) => {
                const url = new URL(instanceSettings.contentUrl);
                getFluidContainer(url.searchParams);
            });
            microsoftTeams.appInitialization.notifySuccess();
        }
    }, [inTeams]);
    

    Fluid コンテナーを取得する方法を定義したら、読み込み時に呼び出getFluidContainerすようにReactに指示し、アプリケーションが Teams 内にあるかどうかに基づいて結果を状態に格納する必要があります。 Reactの useState フックは必要なストレージを提供し、useEffect を使用すると、レンダー時にを呼び出getFluidContainerし、返された値を にsetFluidContainer渡すことができます。

    の末尾に依存関係配列を追加 inTeams することで、アプリはコンテンツ ページの useEffect読み込み時にのみこの関数が呼び出されるようにします。

  9. TODO 6 を次のコードに置き換えます。

    if (inTeams === false) {
      return (
          <div>This application only works in the context of Microsoft Teams</div>
      );
    }
    
    if (fluidContainer !== undefined) {
      return (
          <FluidComponent fluidContainer={fluidContainer} />
      );
    }
    
    return (
      <div>Loading FluidComponent...</div>
    );
    

    注:

    コンテンツ ページが Teams 内に読み込まれ、Fluid コンテナーが React コンポーネントに渡される前に定義されていることを確認することが重要です (FluidComponent以下を参照)。

Fluid ビューとデータのReact コンポーネントを作成する

Teams と Fluid の基本的な作成フローを統合しました。 アプリケーション ビューと Fluid データ間の相互作用を処理する独自のReact コンポーネントを作成できるようになりました。 今から、ロジックとフローは他の Fluid 電源アプリケーションと同様に動作します。 基本的な構造を設定すると、コンテンツ ページの DDSes/data オブジェクトとアプリケーション ビューの相互作用を変更ContainerSchemaすることで、Teams アプリケーションとして任意の Fluid の例を作成できます。

Fluid サーバーを起動し、アプリケーションを実行する

Azure Client ローカル モードで Teams アプリケーションをローカルで実行している場合は、コマンド プロンプトで次のコマンドを実行して Fluid サービスを開始してください。

npx @fluidframework/azure-local-service@latest

Teams アプリケーションを実行して起動するには、別のターミナルを開き、 指示に従ってアプリケーション サーバーを実行します

警告

の空きトンネルを持つ ngrokHostName は保持されません。 実行ごとに異なる URL が生成されます。 新 ngrok しいトンネルが作成されると、古いコンテナーにアクセスできなくなります。 運用環境のシナリオについては、「 Azure Fluid Relay で AzureClient を使用する」を参照してください。

注:

このデモを Webpack 5 と互換性を持たせるために、追加の依存関係をインストールします。 "buffer" パッケージに関連するコンパイル エラーが発生した場合は、を実行 npm install -D buffer してやり直してください。 これは、Fluid Framework の将来のリリースで解決される予定です。

次の手順

Azure Fluid Relay で AzureClient を使用する

これは Teams タブ アプリケーションであるため、コラボレーションと対話がメインの焦点です。 前に提供したローカル モード AzureClientProps を Azure サービス インスタンスからのローカル以外の資格情報に置き換えて、他のユーザーがアプリケーションに参加して対話できるようにします。 Azure Fluid Relay サービスをプロビジョニングする方法を参照してください。

重要

AzureClientProps す資格情報が誤ってソース管理にコミットされないようにすることが重要です。 Teams プロジェクトには、資格情報を .env 環境変数として格納できるファイルが付属しており、ファイル自体は に既に .gitignore含まれています。 Teams で環境変数を使用するには、「環境変数の 設定と取得」を参照してください。

警告

InsecureTokenProvider は、アプリケーションをローカルでテストするための便利な方法です。 ユーザー認証を処理し、運用環境で セキュリティで保護されたトークン を使用するのは、お客様の責任です。

環境変数を設定して取得する

環境変数を設定し、Teams で取得するには、組み込みの .env ファイルを利用できます。 次のコードを使用して、 で .env環境変数を設定します。

# .env

TENANT_KEY=foobar

ファイルの内容を.envクライアント側アプリに渡すには、実行時にアクセスできるように webpack ファイルを にwebpack.config.js構成する必要があります。 次のコードを使用して、 から .env環境変数を追加します。

// webpack,config.js

webpack.EnvironmentPlugin({
    PUBLIC_HOSTNAME: undefined,
    TAB_APP_ID: null,
    TAB_APP_URI: null,
    REACT_APP_TENANT_KEY: JSON.stringify(process.env.TENANT_KEY) // Add environment variable here
}),

環境変数には、 Util.ts

// Util.ts

tokenProvider: new InsecureTokenProvider(JSON.parse(process.env.REACT_APP_TENANT_KEY!), { id: "user" }),

ヒント

コードを変更すると、プロジェクトが自動的に再構築され、アプリケーション サーバーが再読み込みされます。 ただし、コンテナー スキーマを変更すると、アプリケーション サーバーを閉じて再起動した場合にのみ有効になります。 これを行うには、コマンド プロンプトに移動し、Ctrl キーを押しながら C キーを 2 回押します。 次に、または をもう一度実行 gulp serve します gulp ngrok-serve

関連項目