google drive | download all docs as actual data files | create a copy of study sauce template | Search

This code defines an HTTP function named getSignedUrl that generates a signed URL for a file in Google Cloud Storage, allowing a user to upload a file to the specified bucket and file name. The function takes a POST request, retrieves the user's authorization (TODO), and creates a temporary upload URL with a 5-minute expiration time.

Run example

npm run import -- "sign a file url for uploading to google storage"

sign a file url for uploading to google storage

const {Storage} = require('@google-cloud/storage');
const storage = new Storage();

/**
 * HTTP function that generates a signed URL
 * The signed URL can be used to upload files to Google Cloud Storage (GCS)
 *
 * @param {Object} req Cloud Function request context.
 * @param {Object} res Cloud Function response context.
 */
exports.getSignedUrl = (req, res) => {
  if (req.method !== 'POST') {
    // Return a "method not allowed" error
    return res.status(405).end();
  }
  // TODO(developer) check that the user is authorized to upload

  // Get a reference to the destination file in GCS
  const file = storage.bucket(req.body.bucket).file(req.body.filename);

  // Create a temporary upload URL
  const expiresAtMs = Date.now() + 300000; // Link expires in 5 minutes
  const config = {
    action: 'write',
    expires: expiresAtMs,
    contentType: req.body.contentType,
  };

  file.getSignedUrl(config, (err, url) => {
    if (err) {
      console.error(err);
      res.status(500).end();
      return;
    }
    res.send(url);
  });
};

What the code could have been:

const { Storage } = require('@google-cloud/storage');

/**
 * HTTP function that generates a signed URL
 * The signed URL can be used to upload files to Google Cloud Storage (GCS)
 *
 * @param {Object} req Cloud Function request context.
 * @param {Object} res Cloud Function response context.
 */
exports.getSignedUrl = async (req, res) => {
  if (req.method!== 'POST') {
    return res.status(405).send({ message: 'Method not allowed' });
  }

  // Check user authorization
  if (!req.body.authorization) {
    return res.status(401).send({ message: 'Unauthorized' });
  }

  try {
    // Get a reference to the destination file in GCS
    const file = await storage.bucket(req.body.bucket).file(req.body.filename).getMetadata();
    if (!file) {
      return res.status(404).send({ message: 'File not found' });
    }

    // Generate a signed URL
    const expiresAtMs = Date.now() + 300000; // Link expires in 5 minutes
    const signedUrl = await file.getSignedUrl({
      action: 'write',
      expires: expiresAtMs,
      contentType: req.body.contentType,
    });

    res.send(signedUrl);
  } catch (error) {
    console.error(error);
    res.status(500).send({ message: 'Internal Server Error' });
  }
};

Code Breakdown

Importing Google Cloud Storage Library

const { Storage } = require('@google-cloud/storage');
const storage = new Storage();

HTTP Function to Generate Signed URL

exports.getSignedUrl = (req, res) => {
  //...
}

Handling Request Method

if (req.method!== 'POST') {
  return res.status(405).end();
}

Authorizing User (TODO)

// TODO(developer) check that the user is authorized to upload

Getting Reference to Destination File

const file = storage.bucket(req.body.bucket).file(req.body.filename);

Creating Temporary Upload URL

const expiresAtMs = Date.now() + 300000; // Link expires in 5 minutes
const config = {
  action: 'write',
  expires: expiresAtMs,
  contentType: req.body.contentType,
};

Generating Signed URL

file.getSignedUrl(config, (err, url) => {
  if (err) {
    console.error(err);
    res.status(500).end();
    return;
  }
  res.send(url);
});