このチュートリアルでは、Google Meet REST API を Google Workspace Events API および Google Cloud Pub/Sub とともに使用して、会議イベントを監視し、対応する方法について説明します。このサンプル アプリケーションでは、会議の開始時間と終了時間、参加者の参加または退出、生成された会議のアーティファクトが利用可能になった時間を記録します。
イベントの操作について詳しくは、Google Workspace Events API ドキュメントの Google Meet イベントに登録するをご覧ください。
前提条件
組織でこれらの前提条件のいずれかを有効にする必要がある場合は、Google Workspace 管理者に有効にするよう依頼してください。
- Google Meet へのアクセス権を持つ Google Workspace アカウント。
- Google Cloud プロジェクトを作成するためのアクセス権。
- Python 3 がインストールされていること。
- gcloud CLI がインストールされていること。
環境を準備する
このセクションでは、このチュートリアルのローカル環境と Google Cloud プロジェクトを作成して構成する方法について説明します。
作業ディレクトリと Python 仮想環境を作成する
新しい仮想環境を作成して有効にするには、ターミナルで次のコマンドを実行します。
Linux / macOS
mkdir meet-tutorial
cd meet-tutorial
python3 -mvenv env
source env/bin/activate
Windows(コマンド プロンプト)
mkdir meet-tutorial
cd meet-tutorial
python3 -mvenv env
env/bin/activate.bat
Windows(PowerShell)
mkdir meet-tutorial
cd meet-tutorial
python3 -mvenv env
env/bin/activate.ps1
Google Cloud プロジェクトを作成する
Google Cloud コンソール
- Google Cloud コンソールで、メニュー > [IAM と管理] > [プロジェクトを作成] に移動します。
-
[プロジェクト名] フィールドに、プロジェクトのわかりやすい名前を入力します。
省略可: プロジェクト ID を編集するには、[編集] をクリックします。プロジェクトの作成後にプロジェクト ID を変更することはできません。プロジェクトの存続期間に応じて、ニーズに合った ID を選択してください。
- [ロケーション] フィールドで [参照] をクリックして、プロジェクトの潜在的なロケーションを表示します。[選択] をクリックします。
- [作成] をクリックします。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
Google Cloud プロジェクトの課金を有効にする
Google Cloud コンソール
- Google Cloud コンソールで、[お支払い] に移動します。メニュー アイコン > [お支払い] > [マイ プロジェクト] をクリックします。
- [組織を選択] で、Google Cloud プロジェクトに関連付けられた組織を選択します。
- プロジェクトの行で [アクション] メニュー( )を開き、[お支払い情報を変更] をクリックして、Cloud 請求先アカウントを選択します。
- [アカウントを設定] をクリックします。
gcloud CLI
- 使用可能な請求先アカウントを一覧表示するには、次のコマンドを実行します。
gcloud billing accounts list
- 請求先アカウントを Google Cloud プロジェクトにリンクします。
gcloud billing projects link PROJECT_ID --billing-account=BILLING_ACCOUNT_ID
次のように置き換えます。
PROJECT_ID
は、課金を有効にする Cloud プロジェクトのプロジェクト ID です。BILLING_ACCOUNT_ID
は、Google Cloud プロジェクトにリンクする請求先アカウント ID です。
認証と権限付与の設定
認証と認可により、アプリは Meet REST API リソースにアクセスできます。Meet REST API を呼び出すには、ユーザーの承認が必要です。 このセクションでは、ユーザー認証情報を構成して承認をリクエストする方法について説明します。
OAuth 同意画面の設定とスコープの選択
次の手順では、アプリの OAuth 同意画面を設定するためのプレースホルダ情報を提案しています。アプリを外部に公開する前に、この情報を更新してください。
- Google Cloud コンソールで、メニュー > [API とサービス] > [OAuth 同意画面] に移動します。
- [ユーザーの種類] で [内部] を選択し、[作成] をクリックします。
- [アプリ名] に「
Meet REST API Tutorial
」と入力します。 - アプリ登録フォームに入力し、[保存して次へ] をクリックします。
- [スコープを追加または削除] をクリックします。パネルが表示され、Google Cloud プロジェクトで有効にしている各 API のスコープのリストが表示されます。
- [スコープを手動で追加] に、次のスコープを貼り付けます。
https://www.googleapis.com/auth/meetings.space.created
- [Add to Table] をクリックします。
- [更新] をクリックします。
- アプリに必要なスコープを選択したら、[Save and Continue] をクリックします。
- ユーザーの種類に [外部] を選択した場合は、テストユーザーを追加します。
- [テストユーザー] で [ユーザーを追加] をクリックします。
- メールアドレスとその他の承認済みテストユーザーを入力し、[保存して次へ] をクリックします。
- アプリ登録の概要を確認します。変更するには、[編集] をクリックします。アプリ登録に問題がない場合は、[Back to Dashboard] をクリックします。
クライアント ID を作成する
クライアント ID は、OAuth 2.0 フローでアプリケーションの認証情報として機能します。アプリはローカルで実行されるため、デスクトップ クライアント ID を作成します。
- Google Cloud コンソールで、メニュー > [API とサービス] > [認証情報] に移動します。
- [認証情報を作成] > [OAuth クライアント ID] をクリックします。
- [アプリケーションの種類] > [デスクトップ アプリ] をクリックします。
- [名前] フィールドに、認証情報の名前を入力します。この名前は Google Cloud コンソールにのみ表示されます。
- [作成] をクリックします。[OAuth クライアントの作成] 画面が表示され、新しいクライアント ID とクライアント シークレットが表示されます。
- [OK] をクリックします。新しく作成された認証情報が [OAuth 2.0 クライアント ID] に表示されます。
Google 認証ライブラリをインストールする
Google 認証ライブラリをインストールします。
pip install google-auth google-auth-oauthlib
認可の実行
Meet REST API では、OAuth 2.0 アクセス トークン形式のユーザー認証情報が必要です。このセクションでは、OAuth 2.0 フローを実装して、ユーザーのアクセス トークンと更新トークンをリクエストします。
作業ディレクトリに
main.py
ファイルを作成し、次の内容を追加します。import os import json from google.auth.transport import requests from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow def authorize() -> Credentials: """Ensure valid credentials for calling the Meet REST API.""" CLIENT_SECRET_FILE = "./client_secret.json" credentials = None if os.path.exists('token.json'): credentials = Credentials.from_authorized_user_file('token.json') if credentials is None: flow = InstalledAppFlow.from_client_secrets_file( CLIENT_SECRET_FILE, scopes=[ 'https://www.googleapis.com/auth/meetings.space.created', ]) flow.run_local_server(port=0) credentials = flow.credentials if credentials and credentials.expired: credentials.refresh(requests.Request()) if credentials is not None: with open("token.json", "w") as f: f.write(credentials.to_json()) return credentials USER_CREDENTIALS = authorize()
コードを実行するには、クライアント ID と前に作成したシークレットの両方が必要です。ダウンロードしたクライアント シークレット ファイルをプロジェクトの作業ディレクトリにコピーし、名前を
client_secret.json
に変更します。認可の仕組みをテストする場合は、次のコマンドを実行します。アプリは承認を求め、リクエストが承認されると、プロジェクトの作業ディレクトリに
token.json
ファイルを作成します。python3 main.py
Meet REST API を追加する
認証コードが完成したので、次は Meet REST API を有効にして呼び出します。
API を有効にする
このセクションでは Meet REST API を中心に説明しますが、このチュートリアルでは Google Cloud Pub/Sub と Google Workspace Events API も使用します。
Google Cloud コンソール
Google Cloud コンソールで、Google Meet REST API、Google Workspace Events API、Google Cloud Pub/Sub を有効にします。
正しい Cloud プロジェクトで API が有効になっていることを確認し、[次へ] をクリックします。
正しい API が有効になっていることを確認し、[有効にする] をクリックします。
gcloud CLI
必要に応じて、現在の Cloud プロジェクトを
gcloud config set project
コマンドで作成したプロジェクトに設定します。gcloud config set project PROJECT_ID
PROJECT_ID は、作成した Cloud プロジェクトのプロジェクト ID に置き換えます。
gcloud services enable
コマンドを使用して、Google Meet REST API、Google Workspace Events API、Google Cloud Pub/Sub を有効にします。gcloud services enable meet.googleapis.com workspaceevents.googleapis.com pubsub.googleapis.com
Meet REST API クライアント ライブラリをインストールする
Meet REST API クライアント ライブラリをインストールする手順は次のとおりです。
次のコマンドを実行します。
pip install google-apps-meet
main.py
ファイルを編集してクライアントをインポートします。from google.apps import meet_v2 as meet
スペースを作成する
Meet REST API が使用可能になったので、登録可能な会議スペースを作成する関数を定義します。
main.py
を編集して、以下を追加します。
def create_space() -> meet.Space:
"""Create a meeting space."""
client = meet.SpacesServiceClient(credentials=USER_CREDENTIALS)
request = meet.CreateSpaceRequest()
return client.create_space(request=request)
イベントに登録する
会議スペースに関するイベントを受信するには、Google Workspace Events API を使用してサブスクリプションを作成します。また、アプリがイベントを受信する通知エンドポイントとして機能する Google Cloud Pub/Sub トピックを作成してサブスクライブする必要があります。
Google Cloud Pub/Sub を構成する
Pub/Sub トピックを作成してサブスクライブするには:
Google Cloud コンソール
- Google Cloud コンソールで、メニュー > [Pub/Sub] に移動します。
アプリの Cloud プロジェクトが選択されていることを確認します。
- [
- トピック名として「
workspace-events
」と入力します。 - [デフォルトのサブスクリプションを追加] を選択したままにします。
- [作成] をクリックします。完全なトピック名の形式は
projects/{project}/topics/{topic}
です。後の手順で使用するため、この名前をメモしておきます。
トピックを作成] をクリックして、次の操作を行います。
- トピック名として「
- Pub/Sub メッセージをトピックにパブリッシュするためのアクセス権を付与します。
- サイドパネルで [権限] タブを開きます。
- [プリンシパルを追加] をクリックします。
- [新しいプリンシパル] に「
meet-api-event-push@system.gserviceaccount.com
」と入力します。 - [ロールの割り当て] で、
Pub/Sub Publisher
を選択します。 - [保存] をクリックします。
トピックの権限が更新されるまでに数分かかることがあります。
gcloud CLI
- Cloud プロジェクトで、
gcloud pubsub topics create workspace-events
出力には、完全なトピック名が
projects/{project}/topics/{topic}
の形式で表示されます。後の手順で使用するため、この名前をメモしておきます。 - トピックにメッセージをパブリッシュするためのアクセス権を付与します。
gcloud pubsub topics add-iam-policy-binding workspace-events --member='serviceAccount:meet-api-event-push@system.gserviceaccount.com' --role='roles/pubsub.publisher'
トピックの権限が更新されるまでに数分かかることがあります。
- トピックの Pub/Sub サブスクリプションを作成します。
gcloud pubsub subscriptions create workspace-events-sub --topic=TOPIC_NAME
次のように置き換えます。
TOPIC_NAME
: 前の手順で作成したトピックの名前。
トピック名をメモし、{project}
の値がアプリの Cloud プロジェクト ID であることを確認します。後で Google Workspace サブスクリプションを作成する際に、このトピック名を使用します。
サービス アカウントを作成する
Google Cloud コンソール
- Google Cloud コンソールで、メニュー > [IAM と管理] > [サービス アカウント] に移動します。
- [サービス アカウントを作成] をクリックします。
- サービス アカウントの詳細を入力し、[作成して続行] をクリックします。
- 省略可: サービス アカウントにロールを割り当てて、Google Cloud プロジェクトのリソースへのアクセス権を付与します。詳しくは、リソースへのアクセス権の付与、変更、取り消しをご覧ください。
- [続行] をクリックします。
- 省略可: このサービス アカウントを使用してアクションを管理、実行できるユーザーまたはグループを入力します。詳しくは、サービス アカウントの権限借用を管理するをご覧ください。
- [完了] をクリックします。サービス アカウントのメールアドレスをメモします。
gcloud CLI
- サービス アカウント
gcloud iam service-accounts create meet-event-listener \ --display-name="meet-event-listener"
- 省略可: サービス アカウントにロールを割り当てて、Google Cloud プロジェクトのリソースへのアクセス権を付与します。詳しくは、リソースへのアクセス権の付与、変更、取り消しをご覧ください。
サービス アカウントを使用する
サービス アカウントを作成したら、サービス アカウントの権限を借用するためのアクセス権を自身に付与します。
Google Cloud コンソール
- 新しく作成したサービス アカウントの [操作] 列で、> [権限を管理] をクリックします。
- [鍵を追加] > [アクセス権を付与] をクリックします。
- [プリンシパルを追加] にメールアドレスを入力します。
- ロールとして、[サービス アカウント] > [サービス アカウント トークン作成者] を選択します。
- [保存] をクリックします。
gcloud CLI
- 権限を追加するには、サービス アカウントのメールアドレスとユーザーのメールアドレスを使用して
gcloud iam service-accounts add-iam-policy-binding
を実行します。gcloud iam service-accounts add-iam-policy-binding \ SERVICE_ACCOUNT_EMAIL \ --member="user:YOUR_EMAIL \ --role="roles/iam.serviceAccountTokenCreator"
gcloud
でログインして、アプリケーションのデフォルト認証情報をサービス サービス アカウントに設定します。承認を求められたら、前の手順で使用したアカウントを使用してログインします。gcloud auth application-default login --impersonate-service-account=SERVICE_ACCOUNT_EMAIL
Pub/Sub クライアント ライブラリをインストールする
pip
を使用して Pub/Sub 用のクライアント ライブラリをインストールします。pip install google-cloud-pubsub
次に、
main.py
を編集してクライアントをインポートします。from google.cloud import pubsub_v1
Google Workspace サブスクリプションを作成する
次のコードを main.py
に追加して、Meet イベントに登録するメソッドを定義します。このコードは、会議スペースのすべてのイベントに登録します。サブスクライブすると、イベントが Pub/Sub トピックに投稿されます。
def subscribe_to_space(space_name: str = None, topic_name: str = None):
"""Subscribe to events for a meeting space."""
session = requests.AuthorizedSession(USER_CREDENTIALS)
body = {
'targetResource': f"//meet.googleapis.com/{space_name}",
"eventTypes": [
"google.workspace.meet.conference.v2.started",
"google.workspace.meet.conference.v2.ended",
"google.workspace.meet.participant.v2.joined",
"google.workspace.meet.participant.v2.left",
"google.workspace.meet.recording.v2.fileGenerated",
"google.workspace.meet.transcript.v2.fileGenerated",
],
"payloadOptions": {
"includeResource": False,
},
"notificationEndpoint": {
"pubsubTopic": topic_name
},
"ttl": "86400s",
}
response = session.post("https://workspaceevents.googleapis.com/v1/subscriptions", json=body)
return response
次に、対応するコードを追加して、イベントを pull して処理します。
イベントをリッスンして処理する
引き続き main.py
を編集して、次のサンプルコードを追加します。このコードは受信側を実装し、利用可能になった時点で Google Cloud Pub/Sub API を使用してイベントを pull します。さまざまなハンドラ メソッドから、対応するイベントに関する情報が出力されます。
def format_participant(participant: meet.Participant) -> str:
"""Formats a participant for display on the console."""
if participant.anonymous_user:
return f"{participant.anonymous_user.display_name} (Anonymous)"
if participant.signedin_user:
return f"{participant.signedin_user.display_name} (ID: {participant.signedin_user.user})"
if participant.phone_user:
return f"{participant.phone_user.display_name} (Phone)"
return "Unknown participant"
def fetch_participant_from_session(session_name: str) -> meet.Participant:
"""Fetches the participant for a session."""
client = meet.ConferenceRecordsServiceClient(credentials=USER_CREDENTIALS)
# Use the parent path of the session to fetch the participant details
parsed_session_path = client.parse_participant_session_path(session_name)
participant_resource_name = client.participant_path(
parsed_session_path["conference_record"],
parsed_session_path["participant"])
return client.get_participant(name=participant_resource_name)
def on_conference_started(message: pubsub_v1.subscriber.message.Message):
"""Display information about a conference when started."""
payload = json.loads(message.data)
resource_name = payload.get("conferenceRecord").get("name")
client = meet.ConferenceRecordsServiceClient(credentials=USER_CREDENTIALS)
conference = client.get_conference_record(name=resource_name)
print(f"Conference (ID {conference.name}) started at {conference.start_time.rfc3339()}")
def on_conference_ended(message: pubsub_v1.subscriber.message.Message):
"""Display information about a conference when ended."""
payload = json.loads(message.data)
resource_name = payload.get("conferenceRecord").get("name")
client = meet.ConferenceRecordsServiceClient(credentials=USER_CREDENTIALS)
conference = client.get_conference_record(name=resource_name)
print(f"Conference (ID {conference.name}) ended at {conference.end_time.rfc3339()}")
def on_participant_joined(message: pubsub_v1.subscriber.message.Message):
"""Display information about a participant when they join a meeting."""
payload = json.loads(message.data)
resource_name = payload.get("participantSession").get("name")
client = meet.ConferenceRecordsServiceClient(credentials=USER_CREDENTIALS)
session = client.get_participant_session(name=resource_name)
participant = fetch_participant_from_session(resource_name)
display_name = format_participant(participant)
print(f"{display_name} joined at {session.start_time.rfc3339()}")
def on_participant_left(message: pubsub_v1.subscriber.message.Message):
"""Display information about a participant when they leave a meeting."""
payload = json.loads(message.data)
resource_name = payload.get("participantSession").get("name")
client = meet.ConferenceRecordsServiceClient(credentials=USER_CREDENTIALS)
session = client.get_participant_session(name=resource_name)
participant = fetch_participant_from_session(resource_name)
display_name = format_participant(participant)
print(f"{display_name} left at {session.end_time.rfc3339()}")
def on_recording_ready(message: pubsub_v1.subscriber.message.Message):
"""Display information about a recorded meeting when artifact is ready."""
payload = json.loads(message.data)
resource_name = payload.get("recording").get("name")
client = meet.ConferenceRecordsServiceClient(credentials=USER_CREDENTIALS)
recording = client.get_recording(name=resource_name)
print(f"Recording available at {recording.drive_destination.export_uri}")
def on_transcript_ready(message: pubsub_v1.subscriber.message.Message):
"""Display information about a meeting transcript when artifact is ready."""
payload = json.loads(message.data)
resource_name = payload.get("transcript").get("name")
client = meet.ConferenceRecordsServiceClient(credentials=USER_CREDENTIALS)
transcript = client.get_transcript(name=resource_name)
print(f"Transcript available at {transcript.docs_destination.export_uri}")
def on_message(message: pubsub_v1.subscriber.message.Message) -> None:
"""Handles an incoming event from the Google Cloud Pub/Sub API."""
event_type = message.attributes.get("ce-type")
handler = {
"google.workspace.meet.conference.v2.started": on_conference_started,
"google.workspace.meet.conference.v2.ended": on_conference_ended,
"google.workspace.meet.participant.v2.joined": on_participant_joined,
"google.workspace.meet.participant.v2.left": on_participant_left,
"google.workspace.meet.recording.v2.fileGenerated": on_recording_ready,
"google.workspace.meet.transcript.v2.fileGenerated": on_transcript_ready,
}.get(event_type)
try:
if handler is not None:
handler(message)
message.ack()
except Exception as error:
print("Unable to process event")
print(error)
def listen_for_events(subscription_name: str = None):
"""Subscribe to events on the subscription."""
subscriber = pubsub_v1.SubscriberClient()
with subscriber:
future = subscriber.subscribe(subscription_name, callback=on_message)
print("Listening for events")
try:
future.result()
except KeyboardInterrupt:
future.cancel()
print("Done")
コードを完成させる
次のコードを main.py
に追加して、スペースを作成し、イベントに登録して、リッスンするメソッドを呼び出します。TOPIC_NAME
定数と SUBSCRIPTION_NAME
定数を、以前に作成した独自のトピック名とサブスクリプション名に更新します。
コードを
main.py
に追加します。space = create_space() print(f"Join the meeting at {space.meeting_uri}") TOPIC_NAME = "projects/PROJECT_ID/topics/TOPIC_ID" SUBSCRIPTION_NAME = "projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID" subscription = subscribe_to_space(topic_name=TOPIC_NAME, space_name=space.name) listen_for_events(subscription_name=SUBSCRIPTION_NAME)
次のように置き換えます。
PROJECT_ID
: アプリ用の一意の Cloud プロジェクト ID(my-sample-project-191923
など)。TOPIC_ID
: Cloud プロジェクトで作成した Pub/Sub トピックの名前。SUBSCRIPTION_ID
: サブスクリプションの名前(workspace-events-sub
など)。
プログラムを実行します。
python3 main.py
これまでにプログラムを実行したことがない場合は、初めて承認を求められます。Meet REST API を呼び出す権限をアプリケーションに付与します。 プログラムが正常に実行されると、次のような出力が表示されます。
Join the meeting at https://meet.google.com/abc-mnop-xyz
会議に参加
アプリケーションのイベントを生成するには、アプリケーションに表示される URL を使用して会議に参加します。参加後、以下の操作を行ってイベントをトリガーできます。
- 会議から退出して再参加します。
- 他の人を招待したり、スマートフォンでダイヤルインしたりできます。
- 録音と文字起こしを有効にします。
これらの各アクティビティにより、アプリケーションが受信して Google Cloud コンソールに記録するイベントが生成されます。
完了したら、ctrl-c
を使用してプログラムを中断します。
省略可: 試すことができる追加の手順
アプリは、イベントに関する基本的な詳細をログに記録します。引き続き Meet REST API を確認するには、アプリケーションを変更して、これらの追加のアクションを実行してみてください。
- ログインしている参加者に関する追加情報を取得するには、People API を使用します。
- Google Drive API を使用して、録音と文字起こしをダウンロードします。
- Google ドライブから文字起こしをダウンロードするのではなく、Meet REST API の構造化文字起こしメソッドを使用して文字起こしを取得します。
オプション: クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud コンソール アカウントに課金されないようにするには、作成したリソースとプロジェクトをクリーンアップすることをおすすめします。
サブスクリプションを削除するには:
コンソール
Google Cloud コンソールで、メニュー > [Pub/Sub] > [サブスクリプション] に移動します。
サブスクリプションを選択し、
[その他の操作] をクリックします。[削除] をクリックします。[サブスクリプションの削除] ウィンドウが表示されます。
[削除] をクリックします。
gcloud CLI
サブスクリプションを削除します。
gcloud pubsub subscriptions delete SUBSCRIPTION_NAME
トピックを削除するには:
コンソール
Google Cloud コンソールで、メニュー アイコン > [Pub/Sub] > [トピック] に移動します。
トピックを選択して、
[その他の操作] をクリックします。[削除] をクリックします。[トピックの削除] ウィンドウが表示されます。
「
delete
」と入力して、[削除] をクリックします。
gcloud CLI
トピックを削除します。
gcloud pubsub topics delete TOPIC_NAME
プロジェクトを削除するには、次の操作を行います。
コンソール
- Google Cloud コンソールで、[リソースの管理] ページに移動します。メニュー > [IAM と管理] > [リソースの管理] をクリックします。
- プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
- ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。
gcloud CLI
プロジェクトを削除するには、gcloud projects delete コマンドを使用します。
gcloud projects delete PROJECT_ID
関連トピック
- 詳しくは、Google Meet REST API でできることとリファレンス ドキュメントをご覧ください。
- Google Workspace Events API を使用してイベントに登録する方法を確認する。
- 認証の詳細については、OAuth 同意画面を構成してスコープを選択するをご覧ください。