Google 用于 API 调用的 Cloud Functions Cron 作业

Google Cloud Functions Cron Job for API Call

我正在尝试设置一个定期对 Feedly API 进行 api 调用的 firebase 云函数。

但是,它不起作用,我不确定为什么。这是代码:

const functions = require('firebase-functions')
const express = require('express')
const fetch = require('node-fetch')
const admin = require('firebase-admin')

admin.initializeApp()
const db = admin.firestore()

const app = express()

exports.getNewsArticles = functions.pubsub
  .schedule('every 5 minutes')
  .onRun(() => {
    app.get('/feedly', async (request, response) => {

      const apiUrl = `https://cloud.feedly.com/v3/streams/contents?streamId=user/[USER_ID_NUMBER]/category/global.all&count=100&ranked=newest&newThan=300000`

      const fetchResponse = await fetch(apiUrl, {
        headers: {
          Authorization: `Bearer ${functions.config().feedly.access}`
        }
      })

      const json = await fetchResponse.json()

      json.items.forEach(item => {
        db.collection('news').add({
          status: 'pending',
          author: item.author || '',
          content: item.content || '',
          published: item.published || '',
          summary: item.summary || '',
          title: item.title || '',
        })
      })
    })
  })

知道我需要做什么才能让它工作吗?

您的 Cloud Function 中可能存在三个问题:

1。您将 Schedule Functions 的代码与 HTTPS Functions

查看 Schedule Functions and HTTPS Functions 的文档。在计划函数中,您不应该使用 app.get() 而只是使用,例如:

exports.scheduledFunction = functions.pubsub.schedule('every 5 minutes').onRun((context) => {
  console.log('This will be run every 5 minutes!');
  return null;
});

2。您必须 return 一个 Promise(或一个值)

您必须 return Cloud Function 中的 Promise(或值),以向平台指示 Cloud Function 已完成。如果 Cloud Function 中的任务是同步的,您可以 return 一个值,例如return null; 如上例所示。如果一个或多个任务是异步的,您必须 return 一个 Promise。

因此,在您的情况下,您需要按如下方式使用 Promise.all(),因为您正在并行执行多个(异步)写入:

exports.getNewsArticles = functions.pubsub
  .schedule('every 5 minutes')
  .onRun((context) => {

      const apiUrl = `https://cloud.feedly.com/v3/streams/contents?streamId=user/[USER_ID_NUMBER]/category/global.all&count=100&ranked=newest&newThan=300000`

      const fetchResponse = await fetch(apiUrl, {
        headers: {
          Authorization: `Bearer ${functions.config().feedly.access}`
        }
      })

      const json = await fetchResponse.json()

      const promises = [];

      json.items.forEach(item => {
        promises.push(
          db.collection('news').add({
            status: 'pending',
            author: item.author || '',
            content: item.content || '',
            published: item.published || '',
            summary: item.summary || '',
            title: item.title || '',
          }))
      })

      return Promise.all(promises)
  })

3。您可能需要升级您的定价计划

您需要加入 "Flame" 或 "Blaze" 定价计划。

事实上,免费 "Spark" 计划 "allows outbound network requests only to Google-owned services"。请参阅 https://firebase.google.com/pricing/(将鼠标悬停在 "Cloud Functions" 标题后面的问号上)

由于 Feedly API 不是 Google-owned 服务,您可能 需要切换到 "Flame" 或 "Blaze"计划。