A Cloudflare Worker with a cron trigger that monitors one or more Cloudflare Pages projects and posts a message to a Discord channel when a deployment starts and again when it finishes (success, failure, or skipped).
Cloudflare’s free plan doesn’t offer deploy notifications out-of-the-box. Netlify used to have this, but apparently not anymore (unless you had one in before they remove the interface).
If you’ve switched to Cloudflare Pages (or started there) and miss getting notified about deploy successes and failures, this Worker fills that gap — giving you free, automated Discord notifications without upgrading to a paid Cloudflare plan.
An screenshot example of what the Discord bot message looks like:
- ✨ Features
- 🛠 Requirements
- 🏁 Getting Started (Login)
- 🏗 Provisioning a New Worker Project
- 📂 Project Structure
- ⚙️ Configuration
- 🚀 Deployment
- 📊 Usage Limits
- 🧪 Testing and Troubleshooting (Optional)
- 🛡 Security
⚠️ Disclaimer- 📄 License
- 🕒 Scheduled polling (every minute, or whatever interval you set via wrangler.toml)
- 📢 Discord notifications for:
- 🚧 Deploy started
- ✅ Successful deployments
- ❌ Failed deployments
- ⏭️ Skipped deployments (e.g. no changes detected)
- 🔑 Uses Cloudflare KV to remember the last deployment per project, so it only posts once per deploy
- 🔗 Supports multiple Pages projects in a single Worker (configured in wrangler.toml)
- 🔒 Secure secrets — no tokens or webhooks are committed to source control
Before using this project, make sure you have:
- One or more projects deployed on Cloudflare Pages
(This Worker monitors those projects for new deployments) - Node.js & npm – Install from nodejs.org
(Recommended: use an LTS version such as 20.x or 22.x) - npx – Comes with npm 5.2+ (used to run Wrangler without a global install)
- Wrangler – Installed as a dev dependency. See: Install/Update Wrangler
- A Cloudflare account with:
- Access to Cloudflare Pages
- An API token with
Account → Cloudflare Pages → Readpermission
- A Discord webhook URL for the channel you want notifications to appear in
Before configuring anything, make sure Wrangler is logged in to your Cloudflare account. It helps if you are already logged into Cloudflare in your default web browser.
Run:
npx wrangler loginYour browser should open up with Wrangler asking to make changes to your Cloudflare account. Click 'Allow'.
If you ever need to switch accounts or reset authentication, run:
npx wrangler logoutRecommended: Clone this repository and follow the instructions below.
That ensures you have the correct src/index.ts, wrangler.toml, and project structure for this notifier.
When you add your secrets with npx wrangler secret put (or when you run npx wrangler deploy), Wrangler will prompt you to create the Worker project automatically using the name from wrangler.toml.
This is the easiest way to provision everything with the right name and bindings.
If you want to start from scratch rather than cloning this repo, you can bootstrap a new Worker project with Wrangler:
npm create cloudflare@latestFollow the prompts to:
- Choose “Hello World” Worker template
- Select TypeScript (recommended)
- Name the project (e.g., cloudflare-pages-discord-notifier)
- Install dependencies
Then copy this repository’s src/index.ts and wrangler.example.toml as references to configure your project.
cloudflare-pages-discord-notifier/
├── wrangler.toml # Worker config (cron schedule, KV binding, vars)
├── package.json # Dev dependencies & scripts
├── package-lock.json # (auto-generated by npm)
├── src/
│ └── index.ts # Worker code (cron handler + Discord posting)
└── README.md
Before continuing, make sure you have a real wrangler.toml file in place.
If you cloned this repo, copy the example file:
cp wrangler.example.toml wrangler.tomlThen edit wrangler.toml and fill in the placeholders as you follow the steps below.
Your ACCOUNT_ID is required to call the Pages API.
You can find it in a few ways:
- Dashboard URL:
Log into the Cloudflare dashboard → go to Workers & Pages.
Look at the browser URL:https://dash.cloudflare.com/<ACCOUNT_ID>/workers-and-pagesCopy the long hex string afterdash.cloudflare.com/. - CLI (Wrangler):
npx wrangler whoamiThis lists your accounts and their IDs.
You’ll use this value in wrangler.toml under [vars].
Your Worker needs a Cloudflare API token with read-only access to your Pages projects.
- Go to Cloudflare Dashboard → My Profile → API Tokens
- Click Create Token → Create Custom Token
- Add 1 permission:
- Account → Cloudflare Pages → Read
- Scope to your account under Account Resources → Include → Specific Account
- No Zone resources needed — leave them blank.
- Name it (e.g. pages-read-worker) and create it.
- Copy the token value — you’ll store it securely later.
Your Worker uses Cloudflare KV to remember the last deployment ID per project.
Create the namespace:
npx wrangler kv namespace create STATEYou’ll see output like:
kv_namespaces = [
{ binding = "STATE", id = "e3a9b123456f4a9db5e12345678a9b12" }
]
Copy the id value exactly into wrangler.toml.
If you wish to delete the namespace, first let's list what's there:
npx wrangler kv namespace listDelete it.
npx wrangler kv namespace delete --namespace-id <THE_ID>Edit wrangler.toml and fill in placeholders:
name = "cloudflare-pages-discord-notifier"
main = "src/index.ts"
compatibility_date = "2024-11-01"
kv_namespaces = [
{ binding = "STATE", id = "e3a9b123456f4a9db5e12345678a9b12" }
]
[vars]
ACCOUNT_ID = "your_cloudflare_account_id"
PROJECTS = """["small-site","docs-site","big-gallery"]"""
[triggers]
crons = ["*/5 * * * *"] # every 5 minutes (can be every minute)
How to create Discord webhooks: Intro to Webhooks
This project uses a Discord webhook to send deployment notifications into a channel of your choice.
- Open Discord and go to the server where you want notifications.
- Create or choose a text channel for deploy notifications.
- Go to Channel Settings → Integrations → Webhooks.
- Click New Webhook.
- Give it a name (e.g.,
Cloudflare Deploy Bot) - Choose the channel
- (Optional) Set an avatar to make notifications look nicer
- Give it a name (e.g.,
- Copy the Webhook URL (it will look like
https://discord.com/api/webhooks/...).
You will use this URL when storing the DISCORD_WEBHOOK secret:
Use Wrangler to securely store your API token and Discord webhook:
npx wrangler secret put CF_API_TOKEN
npx wrangler secret put DISCORD_WEBHOOKPaste the values when prompted. Wrangler will encrypt and store them in Cloudflare.
💡 Note: If this is the first time you are interacting with this Worker (and it hasn’t been deployed yet), Wrangler will prompt you to create the Worker project using the name defined in wrangler.toml. Choose Yes — this is expected and will create the Worker in your account.
npm install
npx wrangler deploy✅ Note: On your first successful deploy, this Worker will not yet have any recorded state in KV.
That means for each project listed in PROJECTS, you’ll immediately receive:
- 🚧 A "Deploy started" notification (if the latest deploy is still running)
- ✅/❌/⏭️ A notification when the same deploy finishes (success, failure, or skipped)
Subsequent runs will only notify when new deployments start or finish.
Cloudflare Workers on the free plan are limited to 100,000 requests per day. Each cron trigger execution counts as a request, so make sure your crons schedule in wrangler.toml (e.g. every minute) won’t exceed this quota.
See Cloudflare Functions Pricing for details.
This section is for verifying your configuration or debugging issues if something goes wrong.
If npx wrangler deploy worked and your Worker was created successfully, you can skip this section entirely.
If npx wrangler deploy fails, or if you want to confirm your credentials before deploying,
you can manually test your API token, account ID, and project name with a curl request:
curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/pages/projects/$PROJECT_NAME/deployments?per_page=1" --request GET --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"Replace:
- $ACCOUNT_ID with the value you got earlier
- $PROJECT_NAME with the exact case-sensitive name of one Pages project you want to monitor (if you have multiple projects, just pick one to test with)
- $CLOUDFLARE_API_TOKEN with the token you created
You should get JSON back with a result array containing your latest deployment(s).
For reference, see Cloudflare Pages API documentation.
You can simulate the cron run locally:
npx wrangler dev --test-scheduledStream live logs after deploying:
npx wrangler tailDelete the last-known deployment ID in KV to trigger a new notification on the next run:
npx wrangler kv key delete "last:project-name" --binding=STATE- API Token: Use a custom token with Account → Cloudflare Pages → Read permission only.
- Webhook URL: Keep it secret (anyone with it can post to your Discord channel).
- KV Data: Stores only the last deployment ID per project.
This project was "vibe-coded" with the assistance of ChatGPT.
While functional and tested, parts of the code were generated with AI suggestions,
so you may want to review it carefully before using in production or extending it.
This project is licensed under the MIT License.



