Cloudflare Pages Build Status Notifications

Hey folks, just looking for some guidance. We’ve got build triggers set up with CloudFlare Pages, and while these do work I don’t currently get any build notifications. I can configure webhooks for both successful and failed build events, but I can’t specify the payload to include the status flag. Example of a correct payload below.

curl -n -X POST https://webhooks.datocms.com/XXXXXXXXXD/deploy-results \
  -H 'Content-Type: application/json' \
  -d '{ "status": "success" }'

Below is an example of what Cloudflare includes in its webhooks for deployment events.

{
  "name": "Webhook Test",
  "text": "\n⚡️ Cloudflare Pages: A production deployment has started for Project Name ⚡️\n\nBuild Link: https://dash.cloudflare.com/xxx/pages/view/Project Name/11111111111\nCommit Hash: b2c77bd4590bdcb0cb4849ced0b9cd08a64963f482d0c0f5d5b3757b730bee15\nEnvironment: ENVIRONMENT_PRODUCTION\nTimestamp: 2022-10-27T06:00:22Z\n\n\n",
  "data": {
    "alert_name": "pages_event_alert",
    "account_tag": "xxx",
    "project_id": "11111111111",
    "deployment_id": "11111111111",
    "project_name": "Project Name",
    "event": "EVENT_DEPLOYMENT_STARTED",
    "environment": "ENVIRONMENT_PRODUCTION",
    "commit_hash": "xxx",
    "custom_domain": "example.com",
    "pages_dev_url": "example.com",
    "branch_alias_url": "example.com",
    "preview_url": "example.com",
    "timestamp": "2022-10-27T06:00:22Z"
  },
  "ts": 1681832973,
  "account_id": "xxx",
  "policy_id": "xxx",
  "alert_type": "pages_event_alert"
}

Is there any known way of configuring notifications from Cloudflare to DatoCMS for these build events?

Hello @macdara and welcome to the community!

From what i understood, Cloudflare pages does not allow you to set a custom payload to the webhook they send, and therefore you can’t send back to Dato the webhook with the payload we specified, is that correct?

Hey @m.finamor - yes, that’s correct. I’m wondering if there’s a known way of changing the webhook Dato expects to receive? Not sure if that’s an option via a plugin or some other settings. It’s not the end of the world right now, as there are only developers working on the site and we can see the build statuses, but it will be quite awkward once we have our marketing team working on the site.

Hello @macdara , for now not unfortunately :frowning:
The webhook expected by Dato is not modifiable for now, but you should open a feature request for it, as i can see how it could be useful specially for cloudflare pages in this case
Sorry about that

We’ve worked around this issue by executing the npm run build script within a bash script that tracks the exit code of that script and triggers the right DatoCMS success / error webhook accordingly:

#!/bin/bash

run() {
    npm run build
    local exit_code=$?

    if [[ "${CF_PAGES}" == "1" && "${CF_PAGES_BRANCH}" == "main" ]]; then
        echo "Production environment."

        [ $exit_code == 0 ] \
            && datocms_status="success" \
            || datocms_status="error"

        notifyDatocms $datocms_status
    else
        echo "Non-production environment."
    fi
}

notifyDatocms() {
    local status=$1
    echo "Notify DatoCMS of deploy status: $status"
    if [ "$status" == "success" ]; then
        curl -n -X POST https://webhooks.datocms.com/XXXXXXXXXX/deploy-results \
            -H 'Content-Type: application/json' \
            -d '{ "status": "success" }'
    else
        curl -n -X POST https://webhooks.datocms.com/XXXXXXXXXX/deploy-results \
            -H 'Content-Type: application/json' \
            -d '{ "status": "error" }'
    fi
}

run
3 Likes

Inspired by @devoorhoede I’ve quickly created a node script myself:

import { exec } from 'child_process';

exec('npm run cloudflare:pages', async (err) => {
  console.log(
    err ?
      `Something went wrong when running cloudflare:pages, exited with error code: ${err.code}` :
      'cloudflare:pages build successfully!'
  );

  const res = await fetch('https://webhooks.datocms.com/XOXOXOXOX/deploy-results', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ status: err ? "error" : "success" }),
  });

  console.log(
    res.ok ?
    'DatoCMS received the status correctly' :
    `Something went wrong when sending the status to DatoCMS, response code: ${res.status}`
  );
});

My package.json has 2 extra scripts:

"cloudflare:build": "node deploy/build-trigger.mjs",
"cloudflare:pages": "npx @cloudflare/next-on-pages@1",

The cloudflare:build is the command I’m supplying to Cloudflare as build command.
The cloudflare:pages is the actual command to run the cloudflare pages build command.

Happy coding yall! <3

2 Likes

Can you explain to me how you did this? We are having the same issue with the build hooks.

As an aside, might it be simpler to just proxy the existing Cloudflare success/failure notification hooks through a serverless function (like a Cloudflare Worker) to have it rewrite it into Dato format?

They provide an example on their blog for similar use cases:
https://blog.cloudflare.com/cloudflare-relay-worker