【初心者向け】Cloud Storageの変更をトリガーにCloud Functionsを実行する方法

今回はGCPのCloud Storageの変更をトリガーにCloud Functionsを実行する方法について紹介します。

Cloud StorageとCloud Functionsを連携する方法

全体的な流れ

最初に大まかな流れを説明します。

  1. Cloud Storageにファイルをアップロードする
  2. Cloud StorageへのアップロードをトリガーにPub/Subが実行される
  3. Pub/SubをトリガーにCloud Functionsが実行される

Cloud Storageとは

Cloud StorageとはGCPのオブジェクトストレージになります。無期限5GBの無料枠があります。
Cloud Functionsとの連携という観点でCloud Storageを考えると、Cloud Storageでは以下4種類のトリガーを作成できます。

  1. ファイナライズ(作成または更新のこと)
  2. 削除
  3. アーカイブ
  4. メタデータ更新

今回はファイルが作成されたタイミングでトリガーを作りたいため、1番のファイナライズイベントを利用します。

Cloud Pub/Subとは

Cloud Pub/Subとは、メッセージを送る人とメッセージを受け取る人をつなぐメッセージングと呼ばれるサービスです。
メッセージを送る人をPublisher, メッセージを受け取る人をSubscriberと呼びます。

今回だとメッセージを送る人であるCloud Storageとメッセージを受け取る人であるCloud Functionsをつなぐ役割を担っています。
ちなみに今回の手順では、Pub/Subの設定は特に意識する必要はありません。

Cloud Functionsとは

Cloud Functionsとは指定されたトリガーをきっかけに作成した関数を実行するサービスです。
関数はPython, Node.js, .NETなど様々な言語で記述することができます。

Cloud StorageとCloud Functionsを連携する手順

Cloud Storageにバケットを作成する

まずはCloud Storage側の準備をします。以下からCloud Storageを開きます。

Cloud Storage

作成ボタンを押します。

適当なバケット名を入力します。
全てのGCP環境においてユニークな被らない名前にする必要があります。
今回はとりあえず日付や時刻など入れておけば被ることが減ると思われます。

もし以下画面が表示されたら確認を押します。

バケットが作成されました。

Cloud Functionsで関数を作成する

次はCloud Functionsの準備です。
以下ボタンからCloud Functionsのページを開きます。

Cloud Functions

上部にある関数の作成ボタンを押します。

もしも以下画面が表示されたら有効にするを選択します。関連するGCPサービスのAPIが有効になります。

以下画面が表示されたら環境を第2世代を選択します。

上記画面でEVENTARCトリガーを追加ボタンを押します。
以下画面が表示されたらEVENTARC APIを有効にするボタンを押します。

以下画面が表示されます。

以下のように設定していきます。

  • イベントプロバイダ:Cloud Storage
  • イベント:google.cloud.storage.object.v1.finalized(ファイルの書き込み時)
  • バケット:先ほどCloud Storageで作成したバケット

このトリガーでは~という画面が出ているはずなので、付与ボタンを押し、トリガーを保存ボタンを押します。

次へボタンを押します。

もしも以下画面が表示されたら有効にするを選択します。

ランタイムはお好みですが、今回はPython 3.10を選択して、デプロイボタンを押します。

cloud_eventの構造

cloud_eventの内部構造についてはCloudEvents 形式ページに詳細が載っています。

エラーがなければ、3分程度待つと関数が作成されているはずです。
以下のように関数名(function-1)の左に緑のチェックマークが表示されていれば成功です。

以上で関数の準備は完了です。

Cloud Storageにファイルをアップロードする

これでCloud StorageとCloud Functionsの準備は完了しました。
実際に2つのサービスがつながっているかをテストしてみます。

Cloud Storageに戻り、ファイルをアップロードボタンを押して適当なファイルをアップロードします。

ファイルが無事アップロードされました。

Cloud Functionsに移動し、ログタブを選択します。

うまく成功していれば、上記のようにFILEにファイル名などCloud Storageにアップロードしたファイル情報が記載されているはずです。

今回はブラウザ経由で手動でファイルをアップロードしましたが、もしPythonスクリプトからアップロードを実行したい場合は、以下のページもご覧ください。

【初心者向け】ローカルPCのPythonからCloud Storageに画像ファイルをアップロードする方法

参考:Cloud Storageの画像ファイルをCloud Functionsで扱う方法

サンプルではCloud Storageにアップロードされたファイル名だけを出力していました。
実際にはアップロードされたファイルを関数でも利用したいユースケースがほとんどだと思います。
ということで今回はCloud Storageにアップロードされた画像ファイルをCloud Functionsで受け取り、LINE通知する方法を紹介します。

Cloud Functionを開き、ソースコードを記載していきます。

import functions_framework
import requests
from google.cloud import storage


# Triggered by a change in a storage bucket
@functions_framework.cloud_event
def hello_gcs(cloud_event):
   data = cloud_event.data

   bucket = data["bucket"]
   file_name = data["name"]

   print(f"Bucket: {bucket}")
   print(f"File: {file_name}")

   # GCS connect
   client = storage.Client()
   bucket = client.get_bucket(bucket)

   # GCS file download
   blob = bucket.blob(file_name)
   blob.download_to_filename(filename=file_name)

   # LINE params
   LINE_TOKEN = "YOUR_LINE_TOKEN"
   headers = {
      "Authorization": f"Bearer {LINE_TOKEN}",
   }

   # LINE send
   files = {"message": (None, file_name), "imageFile": open(file_name, "rb")}

簡単なコードの説明としては、

  1. GCS connect:Cloud Storageにアクセスする
  2. GCS file download:Cloud Storageからアップロードされたファイルをダウンロードする
  3. LINE params/send:LINE通知する

という流れになります。

Cloud Functionsでのダウンロード

ダウンロードはCloud Functionsで行われるためCloud Functionsの実行環境のディレクトリに保存されているのだと思いますが、確認はできませんでした。
おそらく関数実行の度に関数以外は毎回リフレッシュされているのだと思います。

こちらのGoogle公式ドキュメントにある通り、Functionsの一時ディレクトリに書き込むのは後処理を正しく行う必要があるようです。

一旦ダウンロードするのがあまりスマートではないため、URL参照などで送る方法をご存知の方がいたら教えていただきたいです。

functions-framework==3.*
requests==2.28.1
requests-file==1.5.1
requests-oauthlib==1.3.1
requests-toolbelt==0.9.1
google-cloud-storage==2.5.0

Cloud Storageにファイルをアップロードしたところ、無事LINEに画像ファイルが送信できていることが確認できました。

まとめ

今回はGCPのCloud Storageの変更をトリガーにCloud Functionsを実行する方法について紹介しました。

ファイルアップロードをトリガーに関数を実行できると様々なユースケースにハマると思います。

ご意見やご質問がありましたらお気軽によろしくお願いします。コメントお待ちしております!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA