Skip to content

Cloudflare Worker Handbook

This document serves as the official handbook for the qubital-upload-pipeline Cloudflare Worker configuration. Its purpose is to listen for webhooks from a LiveKit instance, process egress_ended events received, retrieve recorded video files from a Cloudflare R2 bucket, and upload them to YouTube, updating Google Sheets and Slack upon success.

This handbook covers project structure, deployment, configuration, and troubleshooting common issues.


1. Overview

Project Structure

The project is a pnpm monorepo with the following key components:

  • package.json (Root): Contains workspace definitions and high-level scripts for deploying specific workers
  • pkg/upload-worker/: The directory for this specific worker
  • package.json: Defines worker-specific dependencies and scripts. The name field here is what pnpm --filter uses
  • wrangler.toml: Configuration for the deployed worker service name, compatibility dates, and local-only variables
  • pkg/shared/: A shared library for common code like types and middleware

2. Prerequisites & Credential Gathering

Wrangler is the official CLI tool for managing Cloudflare Workers. It is a devDependency in our project, so it will be installed automatically with our other project dependencies.

Requirements: - Node.js (≥22) - pnpm package manager

2.1. Cloudflare

  • Cloudflare Account: You need an active account.

  • R2 Bucket: Go to R2 in the dashboard and create a new bucket (e.g., my-project-recordings) with default options. Note the bucket name.

  • R2 API Token:

  • Go to R2 → Manage R2 API Tokens

  • Click Create API Token
  • Give it a name and select Read & Write permissions
  • Click Create API Token and copy the Account ID, Access Key ID, and Secret Access Key. Store them securely

Gather all this information as you'll need: - Bucket name - Access Key ID (key) - Secret Access Key (secret) - Region (set to auto)

Important

Save the R2 endpoint without the extension in the URL (e.g., https://123abc.r2.cloudflarestorage.com). DO NOT add /your-storage-name at the end, as it will break the upload process by searching for a nested folder that doesn't exist.

2.2. LiveKit

  • LiveKit Cloud Project: You need an active project.

  • API Credentials:

  • In your LiveKit Cloud project, go to Settings → Keys

  • Copy the API Key and API Secret. Store them securely
  • Copy the Host / URL (e.g., wss://my-project.livekit.cloud)

Gather all this information as you'll need: - LiveKit API Key - LiveKit API Secret - LiveKit URL

3. Cloudflare Configuration & Deployment

This phase connects your code to the Cloudflare platform.

3.1. Create the Worker Project

  1. In the Cloudflare dashboard, go to Workers & Pages
  2. Click Create application → Import a Repository
  3. Select your GitHub repository
  4. In the build settings, choose Cloudflare Workers as the framework

Build Settings:

  • Build command: (leave empty)
  • Deploy command: pnpm install && pnpm deploy:upload:staging
  • Root directory: /

  • Click Save and Deploy

Note: The first deployment will fail because it's missing environment variables. This is expected.

3.2. Configure Environment Variables & Secrets

  1. Go to your newly created worker's Settings → Variables and Secrets
  2. All credentials and configuration must be set in the dashboard
  3. Secrets (e.g., API keys, auth tokens) must be encrypted by checking the Secret box

Warning

A typo or a missing variable here is the #1 cause of deployment failures. Double-check everything. When deploying with GitHub automation, it will remove all plain text vars, so we put all vars as Secrets.

4. Connecting LiveKit

The final step is to tell LiveKit where to send its webhooks.

Setup Steps

  1. Go to your project in the LiveKit Cloud Dashboard
  2. Navigate to Settings → Webhooks
  3. Click Add Webhook
  4. Webhook URL: Enter the URL of your deployed worker:
https://qubital-upload-pipeline-staging.your-subdomain.workers.dev/livekit/webhook

Warning

When you configure the webhook in the LiveKit Cloud dashboard, you must provide the full, complete URL to your worker's endpoint. For this project, the correct format is:

https://..workers.dev/livekit/webhook

Be sure to include the /livekit/webhook path at the end, as this is the specific route our Hono application is listening on.

5. Final Deployment and Verification

Deployment Steps

  1. Commit all your code changes (like the wrangler.jsonc name update) and push to your GitHub repository's staging branch
  2. This will trigger a new deployment in the Cloudflare dashboard
  3. Watch the deployment log. It should now succeed

End-to-End Test

Perform the following test to verify everything is working:

  1. Start a LiveKit session in your application
  2. Trigger a recording via your Go backend
  3. Stop the recording
  4. Wait a minute or two
  5. Check for:
  6. A new unlisted video on your YouTube channel
  7. A new row in your Google Sheet
  8. A notification in your Slack channel

Appendix: Troubleshooting

Common Issues

Seeing an OLD BUILD?

Solution: Go to Settings → Builds & deployments → Clear build cache in Cloudflare and retry the deployment.

Deployment Fails with Reserved Command Errors?

Solution: Ensure your worker's deploy script is not named deploy or publish (e.g., use deploy:wrangler).

Worker Fails with "Resolved credential object is not valid"?

Solution: You are missing one or more secrets/variables in the Cloudflare dashboard settings. Double-check all required environment variables.

Worker Fails with "NoSuchKey" from R2?

Solution: This means the file wasn't found. Check that: - Your LiveKit Server's config.yaml is pointing to the correct R2 bucket - Your Go backend's filepath template is a relative path (e.g., out/...)