Google Meet アドオン SDK を使用してウェブ用のアドオンを作成する

このチュートリアルでは、ウェブ用 Google Meet アドオンのソフトウェア開発キット(SDK)を使用してアドオンを作成する方法を説明します。これにより、Google Meet を離れることなく、ウェブアプリ内で共有と共同編集を行うことができます。

  • Google Meet の Meet ウェブ アドオン。
    ウェブ用 Meet アドオン SDK のサイドパネル。
  • Google Meet の Meet ウェブ アドオン。
    ユーザーがコラボレーションを行うウェブ版 Meet アドオン SDK のメインステージ。

目標

  • Google Cloud コンソールでウェブ用 Meet アドオン SDK を作成してデプロイします。
  • ウェブ用 Meet アドオン SDK のメインステージとサイドパネルを作成します。

環境を準備する

このセクションでは、ウェブ用 Meet アドオン SDK 用に Google Cloud プロジェクトを作成して構成する方法について説明します。

Google Cloud プロジェクトを作成する

Google Cloud コンソール

  1. Google Cloud コンソールで、メニュー > [IAM と管理] > [プロジェクトを作成] に移動します。

    [プロジェクトの作成] に移動

  2. [プロジェクト名] フィールドに、プロジェクトのわかりやすい名前を入力します。

    省略可: プロジェクト ID を編集するには、[編集] をクリックします。プロジェクトの作成後にプロジェクト ID を変更することはできません。プロジェクトの存続期間に応じて、ニーズに合った ID を選択してください。

  3. [ロケーション] フィールドで [参照] をクリックして、プロジェクトの潜在的なロケーションを表示します。[選択] をクリックします。
  4. [作成] をクリックします。Google Cloud コンソールが [ダッシュボード] ページに移動し、数分以内にプロジェクトが作成されます。

gcloud CLI

次のいずれかの開発環境で、Google Cloud CLI(「gcloud」)にアクセスします。

  • Cloud Shell: gcloud CLI がすでに設定されているオンライン ターミナルを使用するには、Cloud Shell をアクティブにします。
    Cloud Shell をアクティブにする
  • ローカルシェル: ローカル開発環境を使用するには、gcloud CLI をインストールしてinitializeします。
    Cloud プロジェクトを作成するには、gcloud projects create コマンドを使用します。
    gcloud projects create PROJECT_ID
    PROJECT_ID は、作成するプロジェクトの ID を設定して置き換えます。

API を有効にする

コンソール

  1. Google Cloud コンソールで、Google Workspace Marketplace SDK と Google Workspace アドオン API を有効にします。

    API を有効にする

  2. 正しい Cloud プロジェクトで API が有効になっていることを確認し、[次へ] をクリックします。

  3. 正しい API が有効になっていることを確認し、[有効にする] をクリックします。

gcloud CLI

  1. 必要に応じて、現在の Google Cloud プロジェクトを gcloud config set project コマンドで作成したプロジェクトに設定します。

    gcloud config set project PROJECT_ID
    

    PROJECT_ID は、作成した Cloud プロジェクトのプロジェクト ID に置き換えます。

  2. gcloud services enable コマンドを使用して、Google Workspace Marketplace SDK と Google Workspace アドオン API を有効にします。

    gcloud services enable appsmarket-component.googleapis.com gsuiteaddons.googleapis.com
    

ウェブアプリを作成してデプロイする

次のセクションでは、ウェブ用の Meet アドオン SDK に必要なアプリケーション コードをすべて含むウェブ アプリケーション プロジェクト(Firebase を使用してビルドされたもの)全体をコピーして更新します。まず、ウェブ アプリケーションを構成してデプロイする必要があります。

サンプルコードを確認する

GitHub でベース ウェブ アプリケーションを表示してダウンロードできます。

GitHub で表示

ベースコードの概要は次のとおりです。

  • これは、React ベースのフレームワークである Next.js を使用して構築されています。
  • スタイル設定に Tailwind CSS を使用している。
  • src/components には、アプリケーション ロジックの大部分が含まれます。ここでは更新や変更を行うことはありません。
  • src/firebase には Firebase 構成と初期化コードが含まれています。
  • src/app にはウェブアプリのエントリ ポイントが含まれます。
  • src/app/page.tsx は、メインページまたはプロジェクト リストです。
  • src/app/project/[id]/page.tsx は、個々のプロジェクトとタスクリストのページです。
  • .env には環境構成が含まれています。

Firebase プロジェクトと CLI を設定する

Firebase は、デベロッパーによるアプリ構築を支援するモバイルおよびウェブ アプリケーション開発プラットフォームです。Firestore は、モバイルアプリやウェブアプリのデータの保存、同期、クエリを行える NoSQL ドキュメント データベースです。Firestore には To-Do リストの 情報が保存されますこのアプリは Firebase の機能を使用するため、Firebase プロジェクトと Firebase CLI を設定する必要があります。手順は次のとおりです。

  1. Firebase プロジェクトを作成します。

  2. Cloud Firestore データベースを作成します。

  3. Firebase CLI をインストールするか、最新バージョンに更新します。

  4. ベースアプリのルート ディレクトリに移動します。

  5. プロジェクトを初期化します。

    ローカル プロジェクト ファイルを Firebase プロジェクトに接続します。

    firebase init firestore

    プロジェクトの初期化中に、Firebase CLI のプロンプトで次の操作を行います。

    1. 次のいずれかを選択します。

      Use an existing project を選択し、作成した Firebase プロジェクトを選択します。

      選択した Firebase プロジェクトが、ローカル プロジェクト ディレクトリの「デフォルト」の Firebase プロジェクトになります。

    2. Firestore のルールにはどのファイルを使用する必要がありますか?

      (firestore.rules)」と表示されている場合は、Enter キーを押します。それ以外の場合は、「firestore.rules」と入力して Enter キーを押します。

    3. firestore.rules ファイルはすでに存在します。Firebase コンソールの Firestore ルールで上書きしますか?(はい / いいえ)

      「N」と入力して Enter キーを押します。

    4. Firestore インデックスにはどのファイルを使用する必要がありますか?

      (firestore.indexes.json)」と表示されている場合は、Enter キーを押します。それ以外の場合は、「firestore.indexes.json」と入力して Enter キーを押します。

これで Firestore データベースが設定され、アプリで使用する準備が整いました。

Google で Firebase を認証する

次に、Google プロバイダによる認証を有効にします。手順は次のとおりです。

  1. Firebase コンソールで [Authentication] ページに移動します。

    Firebase Authentication に移動

  2. 初めてプロバイダを設定する場合は、[ログイン方法を設定] をクリックします。それ以外の場合は、[新しいプロバイダを追加] をクリックします。

  3. [Google] を選択し、ステータスが [有効にする] に設定されていることを確認します。

Firebase でウェブアプリを作成する

最後に、Firebase プロジェクト内にウェブアプリを作成し、構成を取得します。手順は次のとおりです。

  1. Firebase コンソールで、ウェブアプリを Firebase プロジェクトに登録します。

  2. [プロジェクトの設定] に移動します。

  3. [アプリ] で、登録済みのウェブアプリを見つけてクリックします。

  4. firebaseConfig の値をメモします。これらは、次のセクションで環境変数を更新するときに使用します。

Google Cloud プロジェクト番号を確認する

  1. Google Cloud コンソールを開きます。

    Google Cloud コンソールに移動

  2. Google Cloud コンソールの横にある下矢印 プルダウン矢印 をクリックし、プロジェクトを選択します。

  3. メニュー メニュー アイコン > [Cloud の概要] をクリックします。

  4. [プロジェクト情報] セクションで、[プロジェクト番号] の値をメモします。次のセクションでこれを使用して、環境変数を更新します。

環境変数を更新する

ベースコードの .env ファイルで、前の手順で収集した詳細情報を次のように入力します。

NEXT_PUBLIC_GOOGLE_PROJECT_NUMBER=GOOGLE_PROJECT_NUMBER
NEXT_PUBLIC_GOOGLE_PROJECT_ID=PROJECT_ID
NEXT_PUBLIC_GOOGLE_API_KEY=API_KEY
NEXT_PUBLIC_GOOGLE_AUTH_DOMAIN=AUTH_DOMAIN
NEXT_PUBLIC_GOOGLE_STORAGE_BUCKET=STORAGE_BUCKET
NEXT_PUBLIC_GOOGLE_MSG_SENDER_ID=MSG_SENDER_ID
NEXT_PUBLIC_GOOGLE_APPID=APP_ID

前の手順で収集した firebaseConfig 値とプロジェクト番号を使用して、次のように置き換えます。

  • GOOGLE_PROJECT_NUMBER: Google Cloud プロジェクトのプロジェクト番号
  • PROJECT_ID: Firebase ウェブアプリの projectId
  • API_KEY: Firebase ウェブアプリの apiKey
  • AUTH_DOMAIN: Firebase ウェブアプリの authDomain
  • STORAGE_BUCKET: Firebase ウェブアプリの storageBucket
  • MSG_SENDER_ID: Firebase ウェブアプリの messagingSenderId
  • APP_ID: Firebase ウェブアプリの appId

アプリの認証情報を設定する

Google アプリケーションの認証情報を設定する手順は次のとおりです。

  1. Firebase コンソールで [プロジェクトの設定] ページに移動します。

    [プロジェクト設定] に移動

  2. [サービス アカウント] タブで、[Firebase Admin SDK] タブを選択します。

  3. [新しい秘密鍵を生成] をクリックし、ダウンロードした JSON ファイルのパスをメモします。

  4. ターミナルで、次のコマンドを実行します。

    export GOOGLE_APPLICATION_CREDENTIALS="JSON_PATH"
    

    JSON_PATH は、ダウンロードした JSON ファイルがあるパスに置き換えます。

開発用サーバーにデプロイする

これでコードと環境が用意できたので、ウェブアプリをローカル開発用サーバーにデプロイできます。そのためには、ウェブアプリ ディレクトリに移動し、次の操作を行います。

  1. コマンド npm install を実行し、ノード モジュールがダウンロードされてインストールされるまで待ちます。

  2. コマンド npm run dev を実行します。

  3. http://localhost:3000/ に移動して、ウェブアプリが稼働していることを確認します。

ウェブ用 Meet アドオン SDK を使用する

次のステップでは、必要なコードを更新してコードを統合し、Google Meet アドオンにします。手順は次のとおりです。

  1. ファイル src/meet/meet.d.ts を作成します。

    1. https://www.gstatic.com/meetjs/addons/0.7.0/index.d.ts から最新のタイプを取得して、ファイルをローカルに保存できます。
  2. ファイル src/meet/utils.ts を作成します。

    1. createAddonSession 関数を追加します。ここで、Google Meet 内で通信するためのセッションが確立されます。

      export function createAddonSession() {
        let session;
      
        session = window.meet.addon.createAddonSession({
          cloudProjectNumber: `${process.env.NEXT_PUBLIC_GOOGLE_PROJECT_NUMBER}`,
        });
        return session;
      }
      
  3. ディレクトリ src/app/meet を作成します。これは、Meet 固有のすべてのルートの専用ディレクトリとして機能します。

  4. ファイル src/app/meet/layout.tsx を作成します。

    1. Meet 関連のすべてのページに共通のレイアウトです。このファイルに Meet SDK スクリプトを挿入し、コンテンツをレンダリングする前に SDK が読み込まれていることを確認します。

      "use client";
      
      import Script from "next/script";
      import { useState } from "react";
      
      type LayoutProps = {
        children: React.ReactNode;
      };
      
      /**
      * Layout for the add-on pages. Injects the Meet SDK script.
      */
      export default function RootLayout({ children }: LayoutProps) {
        const [sdkAvailable, setSdkAvailable] = useState(false);
        return (<>
        <Script
          src="https://www.gstatic.com/meetjs/addons/0.7.0/meet.addons.js"
          onReady={() => setSdkAvailable(true)}
        />
        {sdkAvailable ? children : <div>Loading...</div>}
        </>);
      }
      
  5. ファイル src/app/meet/sidepanel/page.tsx を作成します。

    1. Meet アドオンのサイドパネルのコンテンツ。 このページでは、コンテンツの選択と、コンテンツ選択時の共同編集の開始状態の設定に関する処理を行います。

      "use client";
      
      import { firebaseApp } from "@/firebase/config";
      import { getAuth } from "firebase/auth";
      import { ProjectList } from "@/components/ProjectList";
      import { createAddonSession } from "@/meet/utils";
      import { DocumentReference } from "firebase/firestore";
      import { useSearchParams } from "next/navigation";
      import { useAuthState, useSignInWithGoogle } from "react-firebase-hooks/auth";
      import GoogleButton from "react-google-button";
      
      const auth = getAuth(firebaseApp);
      
      async function startCollaboration(ref: DocumentReference) {
        const url = new URL(window.location.href);
      
        // Initializing session
        const session = await createAddonSession();
        const client = await session.createSidePanelClient();
      
        client.setCollaborationStartingState({
          mainStageUrl: `${url.protocol}//${url.host}/meet/project/${ref.id}`,
          sidePanelUrl: `${url.protocol}//${url.host}/meet/sidepanel?participant=true`,
        });
      }
      
      export default function Home() {
        const params = useSearchParams();
        const [user] = useAuthState(auth);
        const [signInWithGoogle] = useSignInWithGoogle(auth);
      
        const handleProjectSelect = async (ref: DocumentReference) => {
          // Before navigating, make sure project selection is saved
          // for when a shared activity is started.
          await startCollaboration(ref);
        };
      
        if (!user) {
          return (
            <GoogleButton
              onClick={() => signInWithGoogle()}
            ></GoogleButton>
          );
        }
      
        if (params.get("participant")) {
          return <div>You may now close this panel.</div>;
        }
      
        return (
          <div className="px-4">
            <ProjectList onSelect={handleProjectSelect} />
          </div>
        );
      }
      
  6. ファイル src/app/meet/project/\[id\]/page.tsx を作成します。

    1. Meet アドオンのメインステージ コンテンツ。サイドパネルから選択したプロジェクトのコンテンツが表示されます。

      "use client";
      
      import { Project } from "@/components/Project";
      import { createAddonSession } from "@/meet/utils";
      import { firebaseApp } from "@/firebase/config";
      import { getAuth, User } from "firebase/auth";
      import { useRouter } from "next/navigation";
      import { useAuthState, useSignInWithGoogle } from "react-firebase-hooks/auth";
      import GoogleButton from "react-google-button";
      
      const auth = getAuth(firebaseApp);
      
      // Monitor auth state changes.
      if (typeof window !== "undefined") {
        auth.onAuthStateChanged(() => {
          onAuthStateSettled(auth.currentUser);
        });
      
        auth.authStateReady().then(() => {
          onAuthStateSettled(auth.currentUser);
        });
      }
      
      /**
      * Check for auth & doc access when auth state changes.
      */
      async function onAuthStateSettled(user: User | null | undefined) {
        const session = await createAddonSession();
        const client = await session.createMainStageClient();
      
        // For participants, side panel should be closed after authentication
        await client.unloadSidePanel();
      }
      
      type PageParams = {
        params: {
          id: string;
        };
      };
      
        export default function Page({ params }: PageParams) {
        const router = useRouter();
        const [user, isUserLoading] = useAuthState(auth);
      
        if (window.meet.addon.getFrameType() === "MAIN_STAGE") {
          if (isUserLoading) {
            return <div>Loading...</div>;
          }
        }
      
        if (!user) {
          return (
              <GoogleButton
                onClick={() => signInWithGoogle()}
              ></GoogleButton>
            );
        }
      
        let backButton = null;
        if (window.meet.addon.getFrameType() === "SIDE_PANEL") {
          backButton = (
            <div className="px-2 pb-2 -my-2">
              <button className="flex flex-row" onClick={() => router.back()}>
                <span className="material-icons">arrow_back</span>previous screen
                <div className="sr-only">navigate back</div>
              </button>
            </div>
          );
        }
      
        return (
          <div className="w-full min-h-screen px-2">
            {backButton}
            <div className="flex flex-col min-h-screeen">
              <Project id={params.id} />
            </div>
          </div>
        );
      }
      

Deployment を作成する

アドオンのデプロイを設定します。

  1. Google Cloud コンソールで、[Google Workspace Add-ons API] に移動します。

    Google Workspace Add-ons API に移動

  2. [代替ランタイム] タブをクリックします。

  3. [Create new deployment] をクリックし、アドオンのデプロイ ID を入力します。デプロイ ID は、アドオン デベロッパーがアドオン マニフェストを含むデプロイを識別する際に役立つ任意の文字列です。デプロイ ID は必須で、100 文字以内で指定してください。

  4. [次へ] をクリックします。

  5. サイドパネルが開き、アドオン マニフェストの仕様を JSON 形式で送信できます。このパネルを使用して、マニフェスト ファイルとして以下を入力します。

    {
    "addOns": {
      "common": {
        "name": "My First Meet Web Add-on",
        "logoUrl": "https://fonts.gstatic.com/s/i/googlematerialicons/markunread_mailbox/v6/black-24dp/1x/gm_markunread_mailbox_black_24dp.png"
      },
      "meet": {
        "web": {
          "sidePanelUri": "http://localhost:3000/meet/sidepanel",
          "addOnOrigins": ["http://localhost:3000"]
        }
      }
    }
    }
    
    
  6. [Submit] をクリックします。アドオンが正常にデプロイされると、「Deployment "ID" created」というメッセージが表示されます。

  7. このページの [デプロイ] セクションで、デプロイを確認します。

ウェブ向け Meet アドオン SDK をテストする

ウェブ用の Meet アドオン SDK 全体をテストするには、Google Meet を実行して、アプリが想定どおりに動作することを確認します。手順は次のとおりです。

  1. Meet に移動して、新しい会議を開始します。
  2. [アクティビティ] をクリックします。
  3. [アドオン] セクションに [My First Meet Web add-on] が表示されます。これを選択してアドオンを実行します。
  4. アドオンが実行されると、サイドパネルが開きます。
  5. Google アカウントを使用してアプリにログインします。ログインしたら、[新しいプロジェクト] をクリックします。
  6. 作成された [無題のプロジェクト] を選択します。
  7. サイドパネルで [Start Activity] をクリックします。
  8. 開始すると、サイドパネルが閉じてメインステージが開きます。

これでアドオンは想定どおりに実行されますが、対象はアプリからログインしたユーザーのみです(ステップ 5)。Meet からアクティビティに参加する他の参加者は、最初のユーザーと同じセッションを共有できないため、アプリ内でコラボレーションすることはできません。コンテンツを他のユーザーと共有するには、さらなる実装(トークン共有メカニズムなど)が必要です。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、Cloud プロジェクトを削除することをおすすめします。

  1. Google Cloud コンソールで、[リソースの管理] ページに移動します。メニュー > [IAM と管理] > [リソースの管理] をクリックします。

    Resource Manager に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。