😺
Looker Studio から非公開の Cloud Storage PDF を開く
はじめに
こんにちは、クラウドエースのイリゴチです。
社内外のレポートやチェックシートなど、PDF を Google Cloud Storage に保存して運用するケースは多いと思います。
しかし、バケットを「非公開」のまま Looker Studio の表に「PDF を開く」リンクを出したい、というニーズも少なくありません。
本記事では、Cloud Run Functions(2nd gen) で「署名付き URL」を発行して即リダイレクトする小さな HTTP 関数を用意し、Looker Studio の 計算フィールド でその関数 URL を組み立ててクリック可能なリンクを表示する手順を紹介します。
目的
- バケットは最後まで「非公開(Public なし)」
- オブジェクト単位の GET のみ一時的に許可(署名付き URL)
- Looker Studio の表の各行からワンクリックで PDF を表示
全体アーキテクチャ
- PDF は Google Cloud Storage (非公開) の特定バケットに保存
-
Cloud Run Functions(2nd gen) の HTTP 関数に対して
?object=<オブジェクトのパス>を付けてアクセス - 関数が V4 署名付き URL を生成し、302 リダイレクト
- ブラウザが署名付き URL へ遷移して PDF を表示
- Looker Studio 側では 計算フィールド で関数 URL を行ごとに組み立て、表に「PDF を開く」リンクを表示
ステップ 1:Google Cloud Storage に PDF を保管する
-
バケットは 非公開 のままにします。
-
PDF のオブジェクト名は、Looker Studio の行データから一意に導出できるパターンにします。
- 例:
<社員ID>_<連番>_<提出年月日>.pdf
- 例:
日本語が含まれる場合は、URL エンコード される前提で運用します。
ステップ 2:Cloud Run Functions(2nd gen)の HTTP 関数を作成する
1. 関数
- Google Cloud Console の左メニューから 「Cloud Run」 を開きます。
- 右上の 「関数を作成」 をクリックします。
- サービスの名前、リージョン を選択します。
- ランタイムは Python 3.12 を選択します。
- 認証で公開アクセスを許可するを選択します。
- コンテナ、ボリューム、ネットワーキング、セキュリティを開き、変数とシークレットを選択します。
- 以下 2 つの環境変数を追加します
名前 値 BUCKET_NAME PDFを保存したバケット名 SIGNER_SERVICE_ACCOUNT Cloud Run のデフォルトサービスアカウント - 作成を選択します。
💡 この設定により、Looker Studio から直接関数 URL にアクセスできるようになります。
実際の PDF ファイルは署名付き URL 経由でしかアクセスできないため、バケットは非公開のままで安全です。
2. ソース
ディレクトリ構成(Python 3.12)
.
├── main.py
└── requirements.txt
requirements.txt
functions-framework==3.*
google-cloud-storage==2.*
flask==3.*
google-auth==2.*
main.py
関数のエントリポイントにはget_signed_urlと入力してください。
import os
import functions_framework
from google.cloud import storage
from datetime import timedelta
from flask import Request, redirect
import google.auth
import google.auth.transport.requests
BUCKET_NAME = os.environ.get("BUCKET_NAME")
SERVICE_ACCOUNT_EMAIL = os.environ.get("SIGNER_SERVICE_ACCOUNT")
@functions_framework.http
def get_signed_url(request: Request):
"""
非公開バケットのオブジェクトに対し、V4 署名付き URL を生成して 302 リダイレクトします。
クエリ: ?object=<オブジェクト名(パス)>
"""
object_name = request.args.get("object")
if not BUCKET_NAME:
return ("Server misconfiguration: BUCKET_NAME is not set.", 500)
if not SERVICE_ACCOUNT_EMAIL:
return ("Server misconfiguration: SIGNER_SERVICE_ACCOUNT is not set.", 500)
if not object_name:
return ("Error: 'object' parameter is required.", 400)
# アクセストークンを取得(鍵レス署名)
credentials, _ = google.auth.default()
credentials.refresh(google.auth.transport.requests.Request())
try:
storage_client = storage.Client()
bucket = storage_client.bucket(BUCKET_NAME)
blob = bucket.blob(object_name)
signed_url = blob.generate_signed_url(
version="v4",
expiration=timedelta(minutes=15),
method="GET",
service_account_email=SERVICE_ACCOUNT_EMAIL,
access_token=credentials.token,
)
# 署名付き URL へリダイレクト
return redirect(signed_url, code=302)
except Exception as e:
# 例外は Cloud Logging に出力されます
print(f"signing error: {e}")
return ("Internal Server Error: Could not generate signed URL.", 500)
3. 権限
署名に使用するサービスアカウントに、以下の権限をIAM と管理から付与します。
- roles/iam.serviceAccountTokenCreator
- roles/storage.objectViewer
ステップ 3:Looker Studio の計算フィールドでリンクを作成する
- データソース(BigQuery 等)に、PDF の オブジェクト名 を組み立てられる列(または組み合わせ)を用意します。
- チャート(表)の 計算フィールド を新規作成し、次のように関数 URL を合成します。
計算フィールド例
HYPERLINK(
CONCAT(
"https://<関数のURL>/",
"?object=<フォルダ名>/",
CONCAT(
TRIM(<Looker Studio のフィールド名>), "_",
TRIM(<Looker Studio のフィールド名>), "_",
TRIM(<Looker Studio のフィールド名>),
".pdf"
)
),
"PDF を開く"
)
- 関数の URL は Cloud Run Functions の関数画面上部にあります。

- フォルダ名は PDF を格納しているバケット内のフォルダ名です。フォルダがない場合は
"?object=",と記入し、オブジェクト名の指定は不要です。 - CONCAT 内は実際の PDF ファイル名の形式に該当する Looker Studio のフィールドを記入します。
- 出力は「PDF を開く」という クリック可能なリンク になります。
- リンクをクリックすると関数が呼び出され、署名付き URL へリダイレクトされて PDF が表示されます。
オブジェクト名に日本語が含まれる場合、URL エンコードが必要です。
Looker Studio 上では変換できないため、JSON.stringify()を使用して、事前にエンコード済みの文字列を取得し、その変換結果を計算フィールドに記入してください。
以下はコード例です。
console.log(encodeURIComponent("オブジェクト名"))
さいごに
- バケットを非公開のまま、Cloud Run Functions(2nd gen) で V4 署名付き URL を発行・リダイレクトすることで、Looker Studio から安全に PDF を開けます。
- Looker Studio 側は 計算フィールドの HYPERLINK と URL エンコード だけで実現でき、既存の表にシンプルに組み込めます。
- IMAGE 関数と組み合わせることで画像のサムネイル表示も実現可能です。
Discussion