Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

[Node]在Vercel上實作低度頻率排程(Cron-Job)

內容目錄

在Vercel上實作低度頻率排程(Cron-Job)

實作了一個放在Vercel的爬蟲,然後定期去執行,這篇記錄一下在Vercel上實作排程(cron-job)的過程。
原本Vercel就有提供排程的作法,官方說明提到如果是低度頻率排程(例如每天),可以使用GitHub Actions,範例如下:

name: daily-cron
on:
  schedule:
    - cron: '0 1 * * *'
jobs:
  cron:
    runs-on: ubuntu-latest
    steps:
      - name: Call our API route
        run: |
          curl --request POST \
          --url 'https://yoursite.com/api/cron' \
          --header 'Authorization: Bearer ${{ secrets.API_SECRET_KEY }}'

GitHub Actions的作法在這邊就不提了。

概念

其實實作概念很簡單,就是多開一個需要驗證的api,然後排時間去觸發api,進而去執行要做的事情。

排程失效

但我實作完後發現怎樣排程都不會觸發,查了一下找到有個討論說明GitHub Actions的排程其實不穩定,常常會延時或不觸發,連結。因此我改用了另外的免費cron服務,這類服務其實滿多的。

補充:幾天後發現GitHub Actions的排程還是有成功運作,可能是初次觸發會需要一點時間(?,總之相較主打排程的服務,在GitHub Actions使用排程可能會有那麼一點不穩,請注意唷。

Api

官方提供的範例如下,需注意要做驗證所以必須準備API_SECRET_KEY,這個可以寫在Vercel的環境變數(Environment Variables)裡面

export default async function handler(req, res) {
  if (req.method === 'POST') {
    try {
      const { authorization } = req.headers;

      if (authorization === `Bearer ${process.env.API_SECRET_KEY}`) {
        //執行需要的事情
        res.status(200).json({ success: true });
      } else {
        res.status(401).json({ success: false });
      }
    } catch (err) {
      res.status(500).json({ statusCode: 500, message: err.message });
    }
  } else {
    res.setHeader('Allow', 'POST');
    res.status(405).end('Method Not Allowed');
  }
}

像我使用express建置,最後用一個route接這隻api就可以。

app.post('/api/cron', async (req, res) => {
  handler();
});

剛剛有提到這是低度頻率排程的作法,若是高度頻率官方建議用Upstash QStash 函式庫來實作,這部分就要再研究了XD