このチュートリアルでは、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
でログインし、アプリケーションのデフォルト認証情報をサービス アカウントに設定します。承認を求められたら、前の手順で使用したのと同じアカウントでログインします。gcloud auth application-default login --impersonate-service-account=SERVICE_ACCOUNT_EMAIL
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 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 同意画面を構成してスコープを選択するをご覧ください。