ক্লাউড স্টোরেজ ট্রিগার

Cloud Storage ফাইল এবং ফোল্ডার আপলোড, আপডেট বা মুছে ফেলার প্রতিক্রিয়ায় আপনি একটি ফাংশন ট্রিগার করতে পারেন।

এই পৃষ্ঠার উদাহরণগুলি একটি নমুনা ফাংশনের উপর ভিত্তি করে তৈরি করা হয়েছে যা Cloud Storage ইমেজ ফাইল আপলোড করার সময় ট্রিগার হয়। এই নমুনা ফাংশনটি ইভেন্ট অ্যাট্রিবিউটগুলি কীভাবে অ্যাক্সেস করতে হয়, Cloud Functions ইনস্ট্যান্সে কীভাবে একটি ফাইল ডাউনলোড করতে হয় এবং Cloud Storage ইভেন্টগুলি পরিচালনা করার অন্যান্য মৌলিক বিষয়গুলি প্রদর্শন করে।

প্রয়োজনীয় মডিউলগুলি আমদানি করুন

শুরু করতে, Cloud Storage ইভেন্ট পরিচালনা করার জন্য প্রয়োজনীয় মডিউলটি আমদানি করুন:

নোড.জেএস

 const {onObjectFinalized} = require("firebase-functions/storage");

পাইথন

 from firebase_functions import storage_fn

সম্পূর্ণ নমুনা তৈরি করতে, Firebase Admin SDK এবং ইমেজ প্রসেসিং টুলের জন্য নির্ভরতাও যোগ করুন:

নোড.জেএস

 const {initializeApp} = require("firebase-admin/app");
const {getStorage} = require("firebase-admin/storage");
const logger = require("firebase-functions/logger");
const path = require("path");

// library for image resizing
const sharp = require("sharp");

initializeApp();

পাইথন

 import io
import pathlib

from PIL import Image

from firebase_admin import initialize_app

initialize_app()
from firebase_admin import storage

Cloud Storage ফাংশনের ব্যাপ্তি

আপনার ফাংশনটিকে একটি নির্দিষ্ট Cloud Storage বাকেটের মধ্যে বিস্তৃত করতে এবং যেকোনো পছন্দসই বিকল্প সেট করতে নিম্নলিখিত প্যাটার্নটি ব্যবহার করুন:

নোড.জেএস

// scope handler to a specific bucket, using storage options parameter
exports.archivedopts = onObjectArchived({ bucket: "myBucket" }, (event) => {
  //…
});

পাইথন

# Scope handler to a specific bucket using storage options parameter
@storage_fn.on_object_archived(bucket="myBucket")
def archived_bucket(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
    # ...

বিপরীতে, উদাহরণ থাম্বনেইল জেনারেটর ফাংশনটি প্রকল্পের জন্য ডিফল্ট বাকেটের সাথে সংযুক্ত:

নোড.জেএস

exports.generateThumbnail = onObjectFinalized({cpu: 2}, async (event) => {
// ...
});

পাইথন

@storage_fn.on_object_archived()
def generatethumbnail(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
    # ...

ফাংশনের অবস্থান সেট করুন

অবস্থানগুলির মধ্যে অমিলের ফলে স্থাপনা ব্যর্থ হতে পারে। এছাড়াও, Cloud Storage বাকেটের অবস্থান এবং ফাংশনের অবস্থানের মধ্যে দূরত্ব উল্লেখযোগ্য নেটওয়ার্ক ল্যাটেন্সি তৈরি করতে পারে। এই পরিস্থিতিগুলি এড়াতে, ফাংশনের অবস্থানটি নির্দিষ্ট করুন যাতে এটি নিম্নলিখিত উপায়গুলির মধ্যে একটিতে বাকেট/ট্রিগার অবস্থানের সাথে মেলে:

  • ফাংশনের অবস্থান এবং ট্রিগারের অবস্থান একই
  • ফাংশন লোকেশন ট্রিগার লোকেশনের ভিতরে থাকে (যখন ট্রিগার রিজিয়ন ডুয়াল/মাল্টি রিজিয়ন হয়)
  • ট্রিগার অঞ্চলটি us-central1 এ সেট করা থাকলে ফাংশন যেকোনো স্থানে থাকতে পারে।

Cloud Storage ইভেন্টগুলি পরিচালনা করুন

Cloud Storage ইভেন্টগুলিতে সাড়া দেওয়ার জন্য এই হ্যান্ডলারগুলি উপলব্ধ:

নোড.জেএস

  • onObjectArchived শুধুমাত্র তখনই পাঠানো হয় যখন একটি বাকেট অবজেক্ট ভার্সনিং সক্ষম করে। এই ইভেন্টটি নির্দেশ করে যে একটি অবজেক্টের লাইভ ভার্সনটি একটি আর্কাইভড ভার্সনে পরিণত হয়েছে, হয় এটি আর্কাইভ করা হয়েছিল অথবা একই নামের একটি অবজেক্টের আপলোড দ্বারা এটি ওভাররাইট করা হয়েছিল।
  • onObjectDeleted যখন কোনও বস্তু স্থায়ীভাবে মুছে ফেলা হয় তখন পাঠানো হয়। এর মধ্যে এমন বস্তু অন্তর্ভুক্ত থাকে যা ওভাররাইট করা হয় বা বাকেটের জীবনচক্র কনফিগারেশনের অংশ হিসাবে মুছে ফেলা হয়। অবজেক্ট ভার্সনিং সক্ষম করা বাকেটের জন্য, যখন কোনও বস্তু সংরক্ষণাগারভুক্ত করা হয় তখন এটি পাঠানো হয় না ( onArchive দেখুন), এমনকি যদি সংরক্ষণাগার storage.objects.delete পদ্ধতির মাধ্যমে ঘটে।
  • onObjectFinalized যখন বাকেটে একটি নতুন অবজেক্ট (অথবা বিদ্যমান অবজেক্টের একটি নতুন প্রজন্ম) সফলভাবে তৈরি করা হয় তখন পাঠানো হয়। এর মধ্যে একটি বিদ্যমান অবজেক্ট অনুলিপি করা বা পুনর্লিখন করা অন্তর্ভুক্ত। একটি ব্যর্থ আপলোড এই ইভেন্টটিকে ট্রিগার করে না।
  • onMetadataUpdated একটি বিদ্যমান বস্তুর মেটাডেটা পরিবর্তন হলে পাঠানো হয়।

পাইথন

  • on_object_archived শুধুমাত্র তখনই পাঠানো হয় যখন একটি বাকেট অবজেক্ট ভার্সনিং সক্ষম করে। এই ইভেন্টটি নির্দেশ করে যে একটি অবজেক্টের লাইভ ভার্সনটি একটি আর্কাইভড ভার্সনে পরিণত হয়েছে, হয় এটি আর্কাইভ করা হয়েছিল অথবা একই নামের একটি অবজেক্টের আপলোড দ্বারা এটি ওভাররাইট করা হয়েছিল।
  • on_object_deleted যখন কোনও বস্তু স্থায়ীভাবে মুছে ফেলা হয় তখন পাঠানো হয়। এর মধ্যে এমন বস্তু অন্তর্ভুক্ত থাকে যা ওভাররাইট করা হয় বা বাকেটের জীবনচক্র কনফিগারেশনের অংশ হিসাবে মুছে ফেলা হয়। অবজেক্ট ভার্সনিং সক্ষম করা বাকেটের জন্য, যখন কোনও বস্তু সংরক্ষণাগারভুক্ত করা হয় তখন এটি পাঠানো হয় না ( onArchive দেখুন), এমনকি যদি সংরক্ষণাগার storage.objects.delete পদ্ধতির মাধ্যমে ঘটে।
  • on_object_finalized যখন বাকেটে একটি নতুন অবজেক্ট (অথবা বিদ্যমান অবজেক্টের একটি নতুন প্রজন্ম) সফলভাবে তৈরি করা হয় তখন পাঠানো হয়। এর মধ্যে একটি বিদ্যমান অবজেক্ট অনুলিপি করা বা পুনর্লিখন করা অন্তর্ভুক্ত। একটি ব্যর্থ আপলোড এই ইভেন্টটিকে ট্রিগার করে না।
  • on_metadata_updated একটি বিদ্যমান বস্তুর মেটাডেটা পরিবর্তন হলে পাঠানো হয়।

Cloud Storage অবজেক্ট অ্যাট্রিবিউট অ্যাক্সেস করুন

Cloud Functions আপডেট করা ফাইলের জন্য অবজেক্টের আকার এবং কন্টেন্টের ধরণ সহ বেশ কয়েকটি Cloud Storage অবজেক্ট অ্যাট্রিবিউট প্রকাশ করে। অবজেক্টের মেটাডেটাতে কোনও পরিবর্তন হলে metageneration অ্যাট্রিবিউট বৃদ্ধি করা হয়। নতুন অবজেক্টের জন্য, metageneration মান হল 1

নোড.জেএস

const fileBucket = event.data.bucket; // Storage bucket containing the file.
const filePath = event.data.name; // File path in the bucket.
const contentType = event.data.contentType; // File content type.

পাইথন

bucket_name = event.data.bucket
file_path = pathlib.PurePath(event.data.name)
content_type = event.data.content_type

থাম্বনেইল জেনারেশন নমুনাটি ফাংশনটি ফেরত পাঠানোর ক্ষেত্রে প্রস্থান সনাক্ত করতে এই বৈশিষ্ট্যগুলির কিছু ব্যবহার করে:

নোড.জেএস

// Exit if this is triggered on a file that is not an image.
if (!contentType.startsWith("image/")) {
  return logger.log("This is not an image.");
}
// Exit if the image is already a thumbnail.
const fileName = path.basename(filePath);
if (fileName.startsWith("thumb_")) {
  return logger.log("Already a Thumbnail.");
}

পাইথন

# Exit if this is triggered on a file that is not an image.
if not content_type or not content_type.startswith("image/"):
    print(f"This is not an image. ({content_type})")
    return

# Exit if the image is already a thumbnail.
if file_path.name.startswith("thumb_"):
    print("Already a thumbnail.")
    return

একটি ফাইল ডাউনলোড, রূপান্তর এবং আপলোড করুন

কিছু ক্ষেত্রে, Cloud Storage থেকে ফাইল ডাউনলোড করার প্রয়োজন নাও হতে পারে। তবে, Cloud Storage সংরক্ষিত ফাইল থেকে থাম্বনেইল ইমেজ তৈরি করার মতো জটিল কাজগুলি সম্পাদন করার জন্য, আপনাকে ফাংশন ইনস্ট্যান্সে ফাইল ডাউনলোড করতে হবে - অর্থাৎ, আপনার কোড চালানো ভার্চুয়াল মেশিনে।

Node.js এর জন্য sharp এবং Pillow এর জন্য Pillow এর মতো ইমেজ-প্রসেসিং প্রোগ্রামের সাথে Cloud Functions ব্যবহার করে, আপনি গ্রাফিক্যাল ইমেজ ফাইলগুলিতে ম্যানিপুলেশন করতে পারেন। আপলোড করা ইমেজ ফাইলের জন্য থাম্বনেইল ইমেজ কীভাবে তৈরি করবেন তার একটি উদাহরণ নিচে দেওয়া হল:

নোড.জেএস

/**
 * When an image is uploaded in the Storage bucket,
 * generate a thumbnail automatically using sharp.
 */
exports.generateThumbnail = onObjectFinalized({cpu: 2}, async (event) => {

  const fileBucket = event.data.bucket; // Storage bucket containing the file.
  const filePath = event.data.name; // File path in the bucket.
  const contentType = event.data.contentType; // File content type.

  // Exit if this is triggered on a file that is not an image.
  if (!contentType.startsWith("image/")) {
    return logger.log("This is not an image.");
  }
  // Exit if the image is already a thumbnail.
  const fileName = path.basename(filePath);
  if (fileName.startsWith("thumb_")) {
    return logger.log("Already a Thumbnail.");
  }

  // Download file into memory from bucket.
  const bucket = getStorage().bucket(fileBucket);
  const downloadResponse = await bucket.file(filePath).download();
  const imageBuffer = downloadResponse[0];
  logger.log("Image downloaded!");

  // Generate a thumbnail using sharp.
  const thumbnailBuffer = await sharp(imageBuffer).resize({
    width: 200,
    height: 200,
    withoutEnlargement: true,
  }).toBuffer();
  logger.log("Thumbnail created");

  // Prefix 'thumb_' to file name.
  const thumbFileName = `thumb_${fileName}`;
  const thumbFilePath = path.join(path.dirname(filePath), thumbFileName);

  // Upload the thumbnail.
  const metadata = {contentType: contentType};
  await bucket.file(thumbFilePath).save(thumbnailBuffer, {
    metadata: metadata,
  });
  return logger.log("Thumbnail uploaded!");
});

আপনার Cloud Functions ইনস্ট্যান্সের একটি অস্থায়ী ডিরেক্টরিতে ফাইলটি ডাউনলোড করুন। এই অবস্থানে, আপনি প্রয়োজন অনুসারে ফাইলটি প্রক্রিয়া করতে পারেন এবং তারপর Cloud Storage আপলোড করতে পারেন। অ্যাসিঙ্ক্রোনাস কাজগুলি সম্পাদন করার সময়, আপনার কলব্যাকে একটি জাভাস্ক্রিপ্ট প্রতিশ্রুতি ফেরত দেওয়ার বিষয়টি নিশ্চিত করুন।

পাইথন

@storage_fn.on_object_finalized()
def generatethumbnail(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]):
    """When an image is uploaded in the Storage bucket, generate a thumbnail
    automatically using Pillow."""

    bucket_name = event.data.bucket
    file_path = pathlib.PurePath(event.data.name)
    content_type = event.data.content_type

    # Exit if this is triggered on a file that is not an image.
    if not content_type or not content_type.startswith("image/"):
        print(f"This is not an image. ({content_type})")
        return

    # Exit if the image is already a thumbnail.
    if file_path.name.startswith("thumb_"):
        print("Already a thumbnail.")
        return

    bucket = storage.bucket(bucket_name)

    image_blob = bucket.blob(str(file_path))
    image_bytes = image_blob.download_as_bytes()
    image = Image.open(io.BytesIO(image_bytes))

    image.thumbnail((200, 200))
    thumbnail_io = io.BytesIO()
    image.save(thumbnail_io, format="png")
    thumbnail_path = file_path.parent / pathlib.PurePath(f"thumb_{file_path.stem}.png")
    thumbnail_blob = bucket.blob(str(thumbnail_path))
    thumbnail_blob.upload_from_string(thumbnail_io.getvalue(), content_type="image/png")

এই কোডটি একটি অস্থায়ী ডিরেক্টরিতে সংরক্ষিত ছবির জন্য 200x200 থাম্বনেইল তৈরি করে, তারপর এটিকে Cloud Storage আবার আপলোড করে।