Cloud Storage 教學課程 (第 1 代)

本簡單教學課程示範如何編寫、部署及觸發以事件為準的 Cloud Run 函式,並使用 Cloud Storage 觸發條件回應 Cloud Storage 事件。

如要尋找使用 Cloud Storage 的程式碼範例,請前往 Google Cloud 範例瀏覽器

準備應用程式

  1. 建立 Cloud Storage bucket 以上傳測試檔案,其中 YOUR_TRIGGER_BUCKET_NAME 是全域不重複的 bucket 名稱:

    gcloud storage buckets create gs://YOUR_TRIGGER_BUCKET_NAME
  2. 將應用程式存放區範例複製到本機電腦中:

    Node.js

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git

    您也可以 下載 zip 格式的範例,然後解壓縮該檔案。

    Python

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

    您也可以 下載 zip 格式的範例,然後解壓縮該檔案。

    Go

    git clone https://github.com/GoogleCloudPlatform/golang-samples.git

    您也可以 下載 zip 格式的範例,然後解壓縮該檔案。

    Java

    git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git

    您也可以 下載 zip 格式的範例,然後解壓縮該檔案。

    Ruby

    git clone https://github.com/GoogleCloudPlatform/ruby-docs-samples.git

    您也可以 下載 zip 格式的範例,然後解壓縮該檔案。

  3. 變更為包含 Cloud Run 函式程式碼範例的目錄:

    Node.js

    cd nodejs-docs-samples/functions/helloworld/

    Python

    cd python-docs-samples/functions/helloworld/

    Go

    cd golang-samples/functions/helloworld/

    Java

    cd java-docs-samples/functions/helloworld/hello-gcs/

    Ruby

    cd ruby-docs-samples/functions/helloworld/storage/

部署及觸發函式

Cloud Storage 函式是以 Cloud Storage 的 Pub/Sub 通知為基礎,並支援類似的事件類型:

下列各節將說明如何為這裡的每一種事件類型部署及觸發函式。

物件建立完成

當成功完成「寫入」Cloud Storage 物件時,物件建立完成事件就會觸發。特別是,這表示建立新物件或覆寫現有物件都會觸發此事件。此觸發條件會忽略已封存與中繼資料已更新作業。

物件建立完成:部署函式

請查看處理 Cloud Storage 事件的函式範例:

Node.js

/**
 * Generic background Cloud Function to be triggered by Cloud Storage.
 * This sample works for all Cloud Storage CRUD operations.
 *
 * @param {object} file The Cloud Storage file metadata.
 * @param {object} context The event metadata.
 */
exports.helloGCS = (file, context) => {
  console.log(`  Event: ${context.eventId}`);
  console.log(`  Event Type: ${context.eventType}`);
  console.log(`  Bucket: ${file.bucket}`);
  console.log(`  File: ${file.name}`);
  console.log(`  Metageneration: ${file.metageneration}`);
  console.log(`  Created: ${file.timeCreated}`);
  console.log(`  Updated: ${file.updated}`);
};

Python

def hello_gcs(event, context):
    """Background Cloud Function to be triggered by Cloud Storage.
       This generic function logs relevant data when a file is changed,
       and works for all Cloud Storage CRUD operations.
    Args:
        event (dict):  The dictionary with data specific to this type of event.
                       The `data` field contains a description of the event in
                       the Cloud Storage `object` format described here:
                       https://cloud.google.com/storage/docs/json_api/v1/objects#resource
        context (google.cloud.functions.Context): Metadata of triggering event.
    Returns:
        None; the output is written to Cloud Logging
    """

    print(f"Event ID: {context.event_id}")
    print(f"Event type: {context.event_type}")
    print("Bucket: {}".format(event["bucket"]))
    print("File: {}".format(event["name"]))
    print("Metageneration: {}".format(event["metageneration"]))
    print("Created: {}".format(event["timeCreated"]))
    print("Updated: {}".format(event["updated"]))

Go


// Package helloworld provides a set of Cloud Functions samples.
package helloworld

import (
	"context"
	"fmt"
	"log"
	"time"

	"cloud.google.com/go/functions/metadata"
)

// GCSEvent is the payload of a GCS event.
type GCSEvent struct {
	Kind                    string                 `json:"kind"`
	ID                      string                 `json:"id"`
	SelfLink                string                 `json:"selfLink"`
	Name                    string                 `json:"name"`
	Bucket                  string                 `json:"bucket"`
	Generation              string                 `json:"generation"`
	Metageneration          string                 `json:"metageneration"`
	ContentType             string                 `json:"contentType"`
	TimeCreated             time.Time              `json:"timeCreated"`
	Updated                 time.Time              `json:"updated"`
	TemporaryHold           bool                   `json:"temporaryHold"`
	EventBasedHold          bool                   `json:"eventBasedHold"`
	RetentionExpirationTime time.Time              `json:"retentionExpirationTime"`
	StorageClass            string                 `json:"storageClass"`
	TimeStorageClassUpdated time.Time              `json:"timeStorageClassUpdated"`
	Size                    string                 `json:"size"`
	MD5Hash                 string                 `json:"md5Hash"`
	MediaLink               string                 `json:"mediaLink"`
	ContentEncoding         string                 `json:"contentEncoding"`
	ContentDisposition      string                 `json:"contentDisposition"`
	CacheControl            string                 `json:"cacheControl"`
	Metadata                map[string]interface{} `json:"metadata"`
	CRC32C                  string                 `json:"crc32c"`
	ComponentCount          int                    `json:"componentCount"`
	Etag                    string                 `json:"etag"`
	CustomerEncryption      struct {
		EncryptionAlgorithm string `json:"encryptionAlgorithm"`
		KeySha256           string `json:"keySha256"`
	}
	KMSKeyName    string `json:"kmsKeyName"`
	ResourceState string `json:"resourceState"`
}

// HelloGCS consumes a(ny) GCS event.
func HelloGCS(ctx context.Context, e GCSEvent) error {
	meta, err := metadata.FromContext(ctx)
	if err != nil {
		return fmt.Errorf("metadata.FromContext: %w", err)
	}
	log.Printf("Event ID: %v\n", meta.EventID)
	log.Printf("Event type: %v\n", meta.EventType)
	log.Printf("Bucket: %v\n", e.Bucket)
	log.Printf("File: %v\n", e.Name)
	log.Printf("Metageneration: %v\n", e.Metageneration)
	log.Printf("Created: %v\n", e.TimeCreated)
	log.Printf("Updated: %v\n", e.Updated)
	return nil
}

Java

import com.google.cloud.functions.BackgroundFunction;
import com.google.cloud.functions.Context;
import functions.eventpojos.GcsEvent;
import java.util.logging.Logger;

/**
 * Example Cloud Storage-triggered function.
 * This function can process any event from Cloud Storage.
 */
public class HelloGcs implements BackgroundFunction<GcsEvent> {
  private static final Logger logger = Logger.getLogger(HelloGcs.class.getName());

  @Override
  public void accept(GcsEvent event, Context context) {
    logger.info("Event: " + context.eventId());
    logger.info("Event Type: " + context.eventType());
    logger.info("Bucket: " + event.getBucket());
    logger.info("File: " + event.getName());
    logger.info("Metageneration: " + event.getMetageneration());
    logger.info("Created: " + event.getTimeCreated());
    logger.info("Updated: " + event.getUpdated());
  }
}

Ruby

require "functions_framework"

FunctionsFramework.cloud_event "hello_gcs" do |event|
  # This function supports all Cloud Storage events.
  # The `event` parameter is a CloudEvents::Event::V1 object.
  # See https://cloudevents.github.io/sdk-ruby/latest/CloudEvents/Event/V1.html
  payload = event.data

  logger.info "Event: #{event.id}"
  logger.info "Event Type: #{event.type}"
  logger.info "Bucket: #{payload['bucket']}"
  logger.info "File: #{payload['name']}"
  logger.info "Metageneration: #{payload['metageneration']}"
  logger.info "Created: #{payload['timeCreated']}"
  logger.info "Updated: #{payload['updated']}"
end

如要部署函式,請在程式碼範例所在目錄中執行下列指令:

Node.js

gcloud functions deploy helloGCS \
--runtime nodejs22 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize

使用 --runtime 標記指定支援的 Node.js 版本執行階段 ID,以執行函式。

Python

gcloud functions deploy hello_gcs \
--runtime python312 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize

使用 --runtime 標記指定支援的 Python 版本執行階段 ID,以執行函式。

Go

gcloud functions deploy HelloGCS \
--runtime go121 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize

使用 --runtime 標記指定支援的 Go 版本執行階段 ID,以執行函式。

Java

gcloud functions deploy java-gcs-function \
--entry-point functions.HelloGcs \
--runtime java17 \
--memory 512MB \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize

使用 --runtime 標記指定支援的 Java 版本執行函式的執行階段 ID。

Ruby

gcloud functions deploy hello_gcs --runtime ruby33 \
-
-trigger-resource YOUR_TRIGGER_BUCKET_NAME \
-
-trigger-event google.storage.object.finalize

使用 --runtime 標記指定支援的 Ruby 版本執行階段 ID,以執行函式。

其中 YOUR_TRIGGER_BUCKET_NAME 是觸發函式之 Cloud Storage 值區的名稱。

物件建立完成:觸發函式

觸發函式:

  1. 在範例程式碼所在的目錄中,建立空白的 gcf-test.txt 檔案。

  2. 將檔案上傳至 Cloud Storage 以觸發函式:

    gcloud storage cp gcf-test.txt gs://YOUR_TRIGGER_BUCKET_NAME

    其中 YOUR_TRIGGER_BUCKET_NAME 是您將上傳測試檔案之 Cloud Storage 值區的名稱。

  3. 檢查記錄以確定執行已經完成:

    gcloud functions logs read --limit 50
    

物件已刪除

物件遭虛刪除時,系統會觸發物件刪除事件。如果值區未啟用物件版本管理,當物件遭到覆寫或刪除時,就會發生這種情況。指定產生編號刪除物件時,物件也會遭到虛刪除。

物件已刪除:部署函式

使用與完成範例中相同的程式碼範例,將物件已刪除做為觸發事件來部署函式。在程式碼範例所在目錄中執行下列指令:

Node.js

gcloud functions deploy helloGCS \
--runtime nodejs22 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete

使用 --runtime 標記指定支援的 Node.js 版本執行階段 ID,以執行函式。

Python

gcloud functions deploy hello_gcs \
--runtime python312 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete

使用 --runtime 標記指定支援的 Python 版本執行階段 ID,以執行函式。

Go

gcloud functions deploy HelloGCS \
--runtime go121 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete

使用 --runtime 標記指定支援的 Go 版本執行階段 ID,以執行函式。

Java

gcloud functions deploy java-gcs-function \
--entry-point functions.HelloGcs \
--runtime java17 \
--memory 512MB \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete

使用 --runtime 標記指定支援的 Java 版本執行函式的執行階段 ID。

Ruby

gcloud functions deploy hello_gcs --runtime ruby33 \
-
-trigger-resource YOUR_TRIGGER_BUCKET_NAME \
-
-trigger-event google.storage.object.delete

使用 --runtime 標記指定支援的 Ruby 版本執行階段 ID,以執行函式。

其中 YOUR_TRIGGER_BUCKET_NAME 是觸發函式之 Cloud Storage 值區的名稱。

物件已刪除:觸發函式

觸發函式:

  1. 在範例程式碼所在的目錄中,建立空白的 gcf-test.txt 檔案。

  2. 確定您的值區不具有版本管理特性:

    gcloud storage buckets update gs://YOUR_TRIGGER_BUCKET_NAME --no-versioning
  3. 將檔案上傳至 Cloud Storage:

    gcloud storage cp gcf-test.txt gs://YOUR_TRIGGER_BUCKET_NAME

    其中 YOUR_TRIGGER_BUCKET_NAME 是您將上傳測試檔案之 Cloud Storage 值區的名稱。此時,函式應尚未執行。

  4. 刪除檔案以觸發函式:

    gcloud storage rm gs://YOUR_TRIGGER_BUCKET_NAME/gcf-test.txt
  5. 檢查記錄以確定執行已經完成:

    gcloud functions logs read --limit 50
    

請注意,函式可能需要一點時間才能執行完成。

物件已封存

當物件的使用中版本變成非現行版本時,系統會觸發物件封存事件。如果值區已啟用物件版本管理功能,當物件遭到覆寫或刪除時,就會發生這種情況。

物件已封存:部署函式

使用與完成範例中相同的程式碼範例,將物件已封存做為觸發事件來部署函式。在程式碼範例所在目錄中執行下列指令:

Node.js

gcloud functions deploy helloGCS \
--runtime nodejs22 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive

使用 --runtime 標記指定支援的 Node.js 版本執行階段 ID,以執行函式。

Python

gcloud functions deploy hello_gcs \
--runtime python312 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive

使用 --runtime 標記指定支援的 Python 版本執行階段 ID,以執行函式。

Go

gcloud functions deploy HelloGCS \
--runtime go121 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive

使用 --runtime 標記指定支援的 Go 版本執行階段 ID,以執行函式。

Java

gcloud functions deploy java-gcs-function \
--entry-point functions.HelloGcs \
--runtime java17 \
--memory 512MB \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive

使用 --runtime 標記指定支援的 Java 版本執行函式的執行階段 ID。

Ruby

gcloud functions deploy hello_gcs --runtime ruby33 \
-
-trigger-resource YOUR_TRIGGER_BUCKET_NAME \
-
-trigger-event google.storage.object.archive

使用 --runtime 標記指定支援的 Ruby 版本執行階段 ID,以執行函式。

其中 YOUR_TRIGGER_BUCKET_NAME 是觸發函式之 Cloud Storage 值區的名稱。

物件已封存:觸發函式

觸發函式:

  1. 在範例程式碼所在的目錄中,建立空白的 gcf-test.txt 檔案。

  2. 確定您的值區已啟用版本管理:

    gcloud storage buckets update gs://YOUR_TRIGGER_BUCKET_NAME --versioning
  3. 將檔案上傳至 Cloud Storage:

    gcloud storage cp gcf-test.txt gs://YOUR_TRIGGER_BUCKET_NAME

    其中 YOUR_TRIGGER_BUCKET_NAME 是您將上傳測試檔案之 Cloud Storage 值區的名稱。此時,函式應尚未執行。

  4. 封存檔案以觸發函式:

    gcloud storage rm gs://YOUR_TRIGGER_BUCKET_NAME/gcf-test.txt
  5. 觀察記錄以確定執行已經完成:

    gcloud functions logs read --limit 50
    

物件中繼資料已更新

更新現有物件的中繼資料時,便會觸發中繼資料已更新事件。

物件中繼資料已更新:部署函式

使用與完成範例中相同的程式碼範例,將中繼資料已更新做為觸發事件來部署函式。在程式碼範例所在目錄中執行下列指令:

Node.js

gcloud functions deploy helloGCS \
--runtime nodejs22 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate

使用 --runtime 標記指定支援的 Node.js 版本執行階段 ID,以執行函式。

Python

gcloud functions deploy hello_gcs \
--runtime python312 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate

使用 --runtime 標記指定支援的 Python 版本執行階段 ID,以執行函式。

Go

gcloud functions deploy HelloGCS \
--runtime go121 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate

使用 --runtime 標記指定支援的 Go 版本執行階段 ID,以執行函式。

Java

gcloud functions deploy java-gcs-function \
--entry-point functions.HelloGcs \
--runtime java17 \
--memory 512MB \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate

使用 --runtime 標記指定支援的 Java 版本執行函式的執行階段 ID。

Ruby

gcloud functions deploy hello_gcs --runtime ruby33 \
-
-trigger-resource YOUR_TRIGGER_BUCKET_NAME \
-
-trigger-event google.storage.object.metadataUpdate

使用 --runtime 標記指定支援的 Ruby 版本執行階段 ID,以執行函式。

其中 YOUR_TRIGGER_BUCKET_NAME 是觸發函式之 Cloud Storage 值區的名稱。

物件中繼資料已更新:觸發函式

觸發函式:

  1. 在範例程式碼所在的目錄中,建立空白的 gcf-test.txt 檔案。

  2. 確定您的值區不具有版本管理特性:

    gcloud storage buckets update gs://YOUR_TRIGGER_BUCKET_NAME --no-versioning
  3. 將檔案上傳至 Cloud Storage:

    gcloud storage cp gcf-test.txt gs://YOUR_TRIGGER_BUCKET_NAME

    其中 YOUR_TRIGGER_BUCKET_NAME 是您將上傳測試檔案之 Cloud Storage 值區的名稱。此時,函式應尚未執行。

  4. 更新檔案的中繼資料:

    gcloud storage objects update gs://YOUR_TRIGGER_BUCKET_NAME/gcf-test.txt --content-type=text/plain
  5. 觀察記錄以確定執行已經完成:

    gcloud functions logs read --limit 50