Ampliar o Cloud Storage com o Cloud Functions

Você pode acionar uma função em resposta ao upload, à atualização ou à exclusão de arquivos e pastas no Cloud Storage.

Os exemplos desta página são baseados em uma função de amostra acionada com o upload de arquivos de imagem no Cloud Storage. Essa função demonstra como acessar atributos de evento, como fazer o download de um arquivo para uma instância do Cloud Functions e outros princípios básicos de gerenciamento de eventos do Cloud Storage.

Para mais exemplos de casos de uso, veja O que posso fazer com o Cloud Functions?.

Acionar uma função quando há alterações no Cloud Storage

Use functions.storage para criar uma função que gerencie eventos do Cloud Storage. É possível dimensionar sua função de acordo com um bucket específico do Cloud Storage ou usar o bucket padrão. Dependendo da sua escolha, use uma das seguintes opções:

Por exemplo, a amostra do gerador de miniaturas é dimensionada de acordo com o bucket padrão do projeto:

exports.generateThumbnail = functions.storage.object().onFinalize(async (object) => {
  // ...
});

O Cloud Storage é compatível com os seguintes eventos:

  • onArchive: enviado apenas depois que o controle de versões do objeto é ativado no bucket. Este evento indica que a versão ativa de um objeto se tornou uma versão arquivada por ter sido arquivada ou substituída pelo upload de um objeto de mesmo nome.
  • onDelete: enviado quando um objeto é excluído permanentemente. Isso inclui objetos que são substituídos ou são excluídos como parte da configuração do ciclo de vida do bucket. Nos buckets com o controle de versões de objetos ativado, ele não é enviado quando um objeto é arquivado (ver onArchive), mesmo que o arquivamento ocorra através do método storage.objects.delete.
  • onFinalize: enviado quando um novo objeto ou nova geração de um objeto é criada com sucesso no bucket. Isso inclui copiar ou reescrever um objeto. Um upload com falha não aciona esse evento.
  • onMetadataUpdate: enviado quando os metadados de um objeto são alterados.

Defina o evento dentro do manipulador de eventos on, como mostrado acima em onFinalize.

Acessar atributos de objetos do Cloud Storage

O Cloud Functions fornece ao arquivo atualizado diversos atributos de objeto do Cloud Storage, como size e contentType. O atributo metageneration será incrementado sempre que houver uma alteração nos metadados do objeto. Para novos objetos, o valor de metageneration é 1.

const fileBucket = object.bucket; // The Storage bucket that contains the file.
const filePath = object.name; // File path in the bucket.
const contentType = object.contentType; // File content type.
const metageneration = object.metageneration; // Number of times metadata has been generated. New objects have a value of 1.

A amostra de geração de miniaturas usa alguns desses atributos para detectar casos de saída em que a função retorna:

// Exit if this is triggered on a file that is not an image.
if (!contentType.startsWith('image/')) {
  return functions.logger.log('This is not an image.');
}

// Get the file name.
const fileName = path.basename(filePath);
// Exit if the image is already a thumbnail.
if (fileName.startsWith('thumb_')) {
  return functions.logger.log('Already a Thumbnail.');
}

Fazer o download, transformar e fazer upload de um arquivo

Para alguns casos, pode não ser necessário fazer o download de arquivos do Cloud Storage. No entanto, para tarefas intensivas como gerar uma imagem em miniatura a partir de um arquivo armazenado no Cloud Storage, é necessário fazer o download dos arquivos para a instância das funções, ou seja, para a máquina virtual que executa seu código.

Para fazer o download e um novo upload dos objetos para o Cloud Storage, instale o pacote do Google Cloud Storage (em inglês) usando o comando npm install --save @google-cloud/storage e depois o importe. Importe também child-process-promise para usar promessas de JavaScript a fim de lidar com processos externos, como tarefas de processamento de miniaturas, na amostra:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp()
const spawn = require('child-process-promise').spawn;
const path = require('path');
const os = require('os');
const fs = require('fs');

Use o gcs.bucket.file(filePath).download para fazer o download de um arquivo para um diretório temporário na sua instância do Cloud Functions. Nesse local, é possível processar o arquivo conforme necessário e depois fazer o upload para o Cloud Storage. Ao executar tarefas assíncronas, certifique-se de retornar uma promessa de JavaScript no seu retorno de chamada.

Exemplo: transformação de imagem

O Cloud Functions disponibiliza um programa de processamento de imagens chamado ImageMagick (em inglês) que pode editar arquivos de imagens gráficas. Veja abaixo um exemplo de como criar uma imagem em miniatura para um arquivo de imagem:

// Download file from bucket.
const bucket = admin.storage().bucket(fileBucket);
const tempFilePath = path.join(os.tmpdir(), fileName);
const metadata = {
  contentType: contentType,
};
await bucket.file(filePath).download({destination: tempFilePath});
functions.logger.log('Image downloaded locally to', tempFilePath);
// Generate a thumbnail using ImageMagick.
await spawn('convert', [tempFilePath, '-thumbnail', '200x200>', tempFilePath]);
functions.logger.log('Thumbnail created at', tempFilePath);
// We add a 'thumb_' prefix to thumbnails file name. That's where we'll upload the thumbnail.
const thumbFileName = `thumb_${fileName}`;
const thumbFilePath = path.join(path.dirname(filePath), thumbFileName);
// Uploading the thumbnail.
await bucket.upload(tempFilePath, {
  destination: thumbFilePath,
  metadata: metadata,
});
// Once the thumbnail has been uploaded delete the local file to free up disk space.
return fs.unlinkSync(tempFilePath);

Esse código executa o programa de linha de comando convert do ImageMagick para criar uma miniatura de 200 x 200 da imagem salva em um diretório temporário e, em seguida, fazer upload da imagem de volta ao Cloud Storage.

Explorar mais exemplos

Veja outros exemplos de funções comuns de transformação de mídia, incluindo transcodificação de imagens, moderação de conteúdo e extração de metadados EXIF (todos em inglês). A lista completa de exemplos (em inglês) está disponível no GitHub.

Para mais informações, consulte a documentação completa de gatilhos do Google Cloud Storage.