简体   繁体   中英

Using "return" in Async Google Cloud Functions

I am somewhat new to coding and recently created this script in order to pull data from Zoom and push it to Google Drive via API. I am trying to push this to a Google Cloud Function, but when running it in a Cloud Function it seems to stop the function after the first "return" from one of the async functions. It works fine on my local machine, I am only having issues in Cloud Functions. Any suggestions on how to get this to act right would be super helpful. Thank you!

const axios = require("axios");
require("dotenv").config();
const stream = require("stream");
const request = require("request");
const { google } = require("googleapis");

const KEYFILEPATH = "./credentials.json";
const SCOPES = ["https://www.googleapis.com/auth/drive"];

const auth = new google.auth.GoogleAuth({
  keyFile: KEYFILEPATH,
  scopes: SCOPES,
});

let today = new Date().toISOString();

let zoomAccessToken;
let zoomDownloadUrl;

///////////////////////////////////////////////////////////////// Searching for latest Town Hall recording in Google.
const searchFile = async (auth) => {
  const service = google.drive({ version: "v3", auth });
  const files = [];
  try {
    const res = await service.files.list({
      corpora: "drive",
      includeItemsFromAllDrives: true,
      supportsAllDrives: true,
      driveId: "XXXXXXXXXXXXXXXX",
      q: '"XXXXXXXXXXXXXXX" in parents',
      fields: "nextPageToken, files(id, name)",
      spaces: "drive",
    });
    Array.prototype.push.apply(files, res.files);
    const filesArray = res.data.files;
    const filesName = filesArray.map((x) => x.name).sort().reverse()[0];
    console.log(filesName);
    return filesName;
  } catch (err) {
    throw err;
  }
};

///////////////////////////////////////////////////////////////// Get Zoom OAuth access token.
const getAccessToken = async () => {
  return axios({
    method: "post",
    url: `https://zoom.us/oauth/token?grant_type=account_credentials&account_id=${process.env.ZOOM_ACCOUNT_ID}`,
    headers: {
      Authorization: "Basic" +new Buffer.from(process.env.ZOOM_CLIENT_ID + ":" + process.env.ZOOM_CLIENT_SECRET).toString("base64"),
    },
  });
};

///////////////////////////////////////////////////////////////// Get the latest Town Hall recording's data.
const getRecordingData = async () => {
  const token = await getAccessToken();

  zoomAccessToken = await token.data.access_token;

  return axios({
    method: "get",
    url: "https://api.zoom.us/v2/meetings/XXXXXXXXX/recordings",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${zoomAccessToken}`,
    },
  });
};

///////////////////////////////////////////////////////////////// Get the latest Town Hall recording's date.
const getRecordingDate = async () => {
  const recording = await getRecordingData();
  const lastRecordingDate = await recording.data.start_time;
  const recordingDateFormatted = `${lastRecordingDate.substring(0,4)}.${lastRecordingDate.substring(5, 7)}.${lastRecordingDate.substring(8,10)} - Town Hall.mp4`;
  return recordingDateFormatted;
};

///////////////////////////////////////////////////////////////// Get the latest Town Hall recording's download link.
const zoomDownloadLink = async () => {
  const recording = await getRecordingData();
  zoomDownloadUrl = `${recording.data.recording_files[0].download_url}?access_token=${zoomAccessToken}`;
  return zoomDownloadUrl;
};

///////////////////////////////////////////////////////////////// Upload data from latest Town Hall recording's download link to Google Drive.
const uploadFile = async (auth) => {
  const buffer = await zoomDownloadLink();
  const bs = new stream.PassThrough();
  request(buffer).pipe(bs);

  const drive = google.drive({ version: "v3", auth });
  var fileMetadata = {
    name: `${today.substring(0, 4)}.${today.substring(5, 7)}.${today.substring(8,10)} - Town Hall.mp4`,
    parents: ["XXXXXXXXXXXXXXXXX"],
  };
  var media = {
    mimeType: "video/mp4",
    body: bs,
  };
  drive.files.create(
    {
      resource: fileMetadata,
      media: media,
      fields: "id",
      uploadType: "resumable",
      supportsAllDrives: true,
    },
    function (err, res) {
      if (err) {
        console.log(err);
      } else {
        console.log("File Id: ", res.data.id);
      }
    }
  );
};

///////////////////////////////////////////////////////////////// Compares Town Hall files in Google Drive and Zoom. If different, run uploadFile function.
exports.townHall = async () => {
  const townHallFile = await searchFile(auth);
  const lastRecordingDate = await getRecordingDate();

  if (townHallFile != lastRecordingDate) {
    await uploadFile(auth);
  } else {
    console.log("No Recording Today");
  }
};

As you are calling an API inside a cloud function which is an async function but does not have a return statement, it will only execute the function but doesn't wait for the response, because the drive.files.create call is running.

So to fix that just need to await the result of the API. Just add

return await statement on the API call

like:

const uploadFile = async (auth) => {
  const buffer = await zoomDownloadLink();
  const bs = new stream.PassThrough();
  request(buffer).pipe(bs);

  const drive = google.drive({ version: "v3", auth });
  var fileMetadata = {
    name: `${today.substring(0, 4)}.${today.substring(5, 7)}.${today.substring(8,10)} - Town Hall.mp4`,
    parents: ["XXXXXXXXXXXXXXXXX"],
  };
  var media = {
    mimeType: "video/mp4",
    body: bs,
  };
  return await drive.files.create(
    {
      resource: fileMetadata,
      media: media,
      fields: "id",
      uploadType: "resumable",
      supportsAllDrives: true,
    },
    function (err, res) {
      if (err) {
        console.log(err);
      } else {
        console.log("File Id: ", res.data.id);
      }
    }
  );
};

Also, something important when you are calling APIs inside cloud functions is the time out. Check on your CF time out is enough to wait for the API call response.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM