storage-label-images/functions/src/index.ts (57 lines of code) (raw):

/* * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as functions from 'firebase-functions'; import * as admin from 'firebase-admin'; import {ImageAnnotatorClient} from '@google-cloud/vision'; import * as logs from './logs'; import config from './config'; import {formatLabels, getVisionRequest, shouldLabelImage} from './util'; import {IAnnotatedImageResponse} from './types'; admin.initializeApp(); const client = new ImageAnnotatorClient(); export const labelImage = functions.storage .bucket(process.env.IMG_BUCKET) .object() .onFinalize(async object => { logs.functionTriggered(config); if (!shouldLabelImage(object)) { return; } const bucket = admin.storage().bucket(object.bucket); const imageContents = await bucket.file(object.name!).download(); const imageBase64 = Buffer.from(imageContents[0]).toString('base64'); const request = getVisionRequest(imageBase64); logs.labelingImage(object.name!); let results: IAnnotatedImageResponse; try { [results] = await client.annotateImage(request); } catch (error) { logs.labelingError(object.name!, error); return; } logs.labelingComplete(object.name!); let labelAnnotations = results.labelAnnotations; if (!labelAnnotations) { logs.noLabels(object.name!); labelAnnotations = []; } logs.writingToFirestore(object.name!); // prevent from creating a document with a slash in the name const filePath = `gs://${object.bucket}/${object.name}`; const data = { file: filePath, labels: formatLabels(labelAnnotations), }; const snapshot = await admin .firestore() .collection(config.collectionPath) .where('file', '==', filePath) .get(); // if document with file field filePath already exists, overwrite it if (!snapshot.empty) { const docId = snapshot.docs[0].id; await admin .firestore() .collection(config.collectionPath) .doc(docId) .set(data, {merge: true}); } else { await admin.firestore().collection(config.collectionPath).add(data); } });