How to Publish Scheduled Posts in Hugo With Firebase Cloud Functions


firebase cloud serverless hugo cron cloud function

Table of contents

Intro

Recently I migrated my blog from WordPress to Hugo and faced an issue with scheduled posts. In WordPress, we can schedule posts using the admin UI. But how we can schedule posts for the static site? Hugo has publishDate property and you can set any date from the future. The only thing that we need to rebuild your site frequently.

Because the blog hosts and builds on Netlify we can schedule the building of the blog using the build hooks. Netlify provides an URL for each project that we can use to trigger build. Need only send POST-request.

In this tutorial we will implement our build-scheduler using the Firebase Cloud Function.

For sending requests we will use the scheduled Firebase Cloud Function. It will send POST-request to the Netlify webhook every day at the same time.

Prerequisites

  • Firebase account (with Blaze billing plan)
  • Firebase CLI - v8.10.0
  • node - v12.8.0
  • npm - v6.14.8
  • axios - v0.20.0

We will use the Cloud Schedule API and be careful it may require some funds. Also, make sure that you enabled Blaze billing plan for the project.

Creating build hook

Go to the Netlify project with your Hugo blog, open “Settings”, then go to “Build & deploy” section. In “Build hooks” section press the “Add build hook” button:

Add build hook

Enter “build hook name” and choose the branch to build. Press “Save”:

Build hook creation

The new webhook URL will appear in the list. Copy it and don’t share it on the internet:

Build hooks

Creating Firebase Cloud Function

Create the folder “blog-helpers” and open it:

mkdir blog-helpers
cd blog-helpers

Run firebase init:

firebase init

Follow the wizard and complete all points.

After project creation, go to Firebase project settings and set the GCP resource location. This is the location of our project. I already wrote a post on how to do this, so you can check it.

Make our function scheduled

In this section, we will make schedule our function and run it everyday at 9am in the GMT+3 timezone.

Open the created Firebase project and start to edit the funtions/index.js file. It already has some predefined logic, but we will put our new:

const functions = require('firebase-functions');

exports.triggerBlogBuild = functions.pubsub
  .schedule('0 9 * * *')
  .timeZone('Europe/Kiev')
  .onRun(context => {
  	functions.logger.info("Trigger build every day at 9 am in Ukraine timezone!", {structuredData: true});
  });

We have called schedule method of Pub/Sub trigger type with a cron expression. This expression means “every day at 9 am. Then we have called timeZone method where we define the time zone for our function.

The logic of sending POST request to netlify we will put inside callback function that passed into onRun method.

Making a scheduled request to Netlify

To make request we will install Axios. You can use another library or even pure Node.js request logic. Inside functions/ folder just run:

npm i axios -s

We will connect the Axios library inside functions/index.js and add the logic of making POST request. The full function code will look like this:

const functions = require('firebase-functions');
const axios = require('axios');
const WEBHOOK_URL = `<your-netlify-webhook-url>`;

exports.triggerBlogBuild = functions.pubsub
    .schedule('0 9 * * *')
    .timeZone('Europe/Kiev')
    .onRun(context => {
        functions.logger.info("Trigger build every day at 9 am in Ukraine timezone!", { structuredData: true });
        return axios.post(WEBHOOK_URL);
    });

The WEBHOOK_URL it’s a secret value, so it’s better to add it to environment variables. If you don’t know how to do this, you can read my tutorial.

Deploy function

To deploy function go to the project folder inside the terminal and run:

firebase deploy

If deployment was successful the output will be like the following:

Successful deployment

If you see the message:

Error: Cloud resource location is not set for this project but scheduled functions requires it. Please see this documentation for more details: https://firebase.google.com/docs/projects/locations.

you can fix it by setting the GCP resource location.

Now we can go to the Firebase project and see our function:

Created Function on Firebase

It will send the request to Webhook URL every day at 9 am and rebuild a Hugo blog:

Triggered build by hook

Conclusion

In this post, we scheduled the building of a static Hugo blog using the Firebase Cloud Functions. If you have a specific schedule for your posts, for example, you post 2 times per week you can configure the cron expression and decrease the job executions.

Also, this issue with scheduled posts can be resolved in other ways, for example with postponed commits or configuring your own pipelines.

comments powered by Disqus