次の方法で共有


Teams で Fluid を使用する

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

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

  1. Fluid クライアントを Teams タブ アプリケーションに統合します。
  2. Teams アプリケーションを実行して Fluid サービス (Azure Fluid Relay) に接続します。
  3. Fluid コンテナーを作成して取得し、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 Fluid サービスへの接続を作成するために必要な InsecureTokenProvider を定義します。

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

    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 が必要です。 この例では、 initialObjectsとして SharedMap を使用しますが、任意の共有オブジェクトを使用できます。

    注:

    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 を contentUrl に追加し、コンテンツ ページの URL をクエリ パラメーターとして websiteUrlすることです。 Teams 構成ページの [保存] ボタンは、構成ページとコンテンツ ページの間のゲートウェイです。 これは、コンテナーを作成し、設定にコンテナー ID を追加する場所です。

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

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

    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 内にあるかどうか、およびcontentUrlなどの Teams リソースが使用可能かどうかを確認するには、inTeamsブール値定数を初期化する必要があります。

  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 を使用すると、コンテナーを読み込むことができます。 コンテナーが完成したら、 fluidContainer React 状態を設定します。前の手順を参照してください。

  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に渡すことができます。

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

  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とアプリケーション ビューの相互作用を変更することで、Fluid の例を Teams アプリケーションとして作成できます。

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

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

npx @fluidframework/azure-local-service@latest

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

警告

ngrokの空きトンネルを持つ HostName は保持されません。 実行ごとに異なる 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 します。

関連項目