Step by step · With analogies

How we built
Morning Brief

Every step explained in plain English — what we ran, why we ran it, and what real-world thing it's most like. No technical background needed to follow this.

What's in this guide
01
Install Node.js
The engine that runs the tools

Before we could do anything, we needed to install Node.js on the laptop. Node.js is a program that lets your computer run JavaScript outside of a browser. Wrangler (the tool we use to talk to Cloudflare) is written in JavaScript — so Node.js is what makes Wrangler work on your machine.

The analogy
Node.js is like the engine in a car. You needed it installed to drive, but you don't think about it while driving. Once it's there, it just works in the background. You install it once and never touch it again.
Why we needed it
Wrangler is the tool that sends our code to Cloudflare. Wrangler is a JavaScript program. To run JavaScript programs on your laptop (outside a browser), you need Node.js. Without it, Wrangler simply won't start.

We went to nodejs.org, downloaded the LTS version, ran the installer with all defaults, and confirmed it worked:

Terminal / PowerShell
$ node --version v24.15.0 ← any number here means it worked
02
Install Wrangler
The delivery truck to Cloudflare

Wrangler is Cloudflare's command-line tool. It's what lets you send your code from your laptop to Cloudflare's computers. You type one command and it packages your code, uploads it, and activates it — all in under 10 seconds.

The analogy
Wrangler is the delivery truck. You write the recipe (code) on your laptop. Wrangler picks it up and delivers it to Cloudflare's kitchen (their servers). Once it's delivered, the truck goes home. Cloudflare cooks from there.
Terminal / PowerShell
$ npm install -g wrangler $ wrangler --version 4.83.0 ← confirmed Wrangler is installed

The -g flag means "install globally" — meaning Wrangler is available everywhere on your laptop, not just in one folder.

03
Log in to Cloudflare
Connecting the truck to the right warehouse

Wrangler needed to know which Cloudflare account to deploy to. This command opened a browser window, asked us to log in to Cloudflare, and then connected that account to Wrangler on the laptop permanently.

The analogy
Like giving the delivery truck driver the address of your specific warehouse. Without this step, the truck has no idea where to go. You do this once — after that, Wrangler always knows where to deliver.
Terminal / PowerShell
$ wrangler login ← browser opens, you click Allow, done
04
Create the project
Building the sorting office structure

This command created a folder on the laptop with the basic structure Cloudflare expects: a code file and a settings file. Think of it as Cloudflare handing you a blank template and saying "write your instructions here."

The analogy
Like getting a blank instruction card from the sorting office manager. The card has a space for your name at the top (the settings file) and lines to write the instructions on (the code file). We just filled in the blanks.
Terminal / PowerShell
$ mkdir morning-brief && cd morning-brief $ npm create cloudflare@latest .

It asked a few questions. We answered:

This created two important files: src/index.js (where the code goes) and wrangler.jsonc (the settings — name, schedule, etc).

05
Add the Worker code
Writing the sorting office instructions

We replaced the default code in src/index.js with the Morning Brief Worker — the actual logic that runs every morning. This file contains all the instructions: get a Gmail access token, find the NB Projects label, pull emails from the last 24 hours, send to Claude, post to Slack.

The analogy
The default code is like an empty instruction card that just says "Hello." We replaced it with the actual standing instructions: "Every morning, go to the mailroom, pick up the red-tagged pile, give it to the colleague in the next room, and pin what she writes to the noticeboard." Step by step, in order.

We also updated wrangler.jsonc to set the schedule:

wrangler.jsonc — the settings file
{ "name": "morning-brief", "main": "src/index.js", "compatibility_date": "2024-01-01", "triggers": { "crons": ["30 4 * * 1-5"] ← 4:30am UTC = 10am IST, Mon–Fri } }
What the cron means
30 4 * * 1-5 reads as: "at minute 30, hour 4, any day of month, any month, Monday through Friday." Cloudflare uses UTC time — 4:30am UTC is 10:00am IST. So the alarm rings every weekday morning at 10am your time.
06
Add the secrets
Putting the keycards in Cloudflare's safe

The Worker needs permission to get into Gmail, talk to Claude, and post to Slack. Those permissions come as API keys — long strings of letters and numbers that act like passwords. We stored them in Cloudflare's encrypted secret vault using five separate commands.

The analogy
Imagine a keycard system. The sorting office worker needs a keycard to get into the mailroom (Gmail), another to talk to the senior colleague (Claude), and another to access the noticeboard (Slack). We put all three keycards in Cloudflare's safe. The Worker knows to use them — but the card numbers are never written anywhere visible. Even if someone reads the code, they see no passwords. Just "use the keycard."
Terminal / PowerShell — run each one separately
$ wrangler secret put ANTHROPIC_API_KEY ← paste your Anthropic key, press Enter $ wrangler secret put SLACK_WEBHOOK_URL ← paste the Slack webhook URL, press Enter $ wrangler secret put GMAIL_CLIENT_ID $ wrangler secret put GMAIL_CLIENT_SECRET $ wrangler secret put GMAIL_REFRESH_TOKEN ← Gmail credentials from the existing SHI Worker
Why not just write them in the code?
If API keys are written in the code file, anyone who reads the file can steal them and use your Gmail, run up your Claude bill, or post to your Slack. Cloudflare's secret store keeps them encrypted. The Worker can use them at runtime without anyone — including us — being able to see them afterwards.

The Gmail credentials were the same ones already stored in the SHI v2 Worker — we found them in the Cloudflare dashboard under Workers & Pages → shi-worker → Settings → Variables and Secrets.

07
Deploy
Sending the instructions to Cloudflare

One command. Wrangler took everything — the code, the settings, the schedule — and uploaded it to Cloudflare's servers. From this moment, the Worker existed on Cloudflare's infrastructure, not just on the laptop.

The analogy
The delivery truck picks up the instruction card, drives to Cloudflare's sorting office, hands it to the manager, and comes home. The sorting office now has the instructions. The truck's job is done. The Worker runs from Cloudflare's building from now on.
Terminal / PowerShell
$ wrangler deploy Deployed morning-brief triggers (8.08 sec) https://morning-brief.rey619-ms.workers.dev schedule: 30 4 * * 1-5 ← live and scheduled
What the output means
The URL is the manual trigger — hit it in a browser any time to run the pipeline on demand. The schedule line confirms the cron is active — Cloudflare will wake the Worker at 10am IST every weekday without any further input from anyone.
08
Test
Making sure the sorting office is actually open

We didn't wait for 8am to see if it worked. We opened a browser and hit the Worker URL. In about 15 seconds, the Morning Brief appeared in Slack — exactly as designed.

The analogy
Like pressing the test button on a fire alarm right after installation. You don't wait for an actual fire — you just verify the system works. The Worker URL is the test button. Hit it any time to run the full pipeline immediately, regardless of what time it is.
Browser URL — manual trigger
https://morning-brief.rey619-ms.workers.dev ← opens in any browser ← pulls last 24h of NB Projects emails ← Claude reads and structures them ← brief appears in Slack within 15 seconds
From this point on
The Worker runs automatically every weekday at 10am. Nobody presses anything. The brief arrives whether you're in a meeting, on a call, or still asleep. The manual URL still works any time you want an on-demand brief — before a client call, mid-afternoon, whenever.
That's the full build — 8 steps, one pipeline, runs forever.
← Back to overview