cdn/README.md
Tom (Whity) 09441c495b Codebase Rewrite – Slack Bot, Backblaze B2 Migration, API v3
This update is a full rewrite of the codebase with major improvements 💪 :

- Slack Bot Integration – Added now built-in Slack bot!
- Backblaze B2 Migration – Switched from Vercel to B2, cutting storage / egress costs by around 90%.
- API v3 – New version includes file hashes, sizes, and additional metadata.
- API Token Requirement – ⚠️ All older API versions (v1, v2) now require authentication tokens. ⚠️

-- Deployor 💜
2025-01-18 03:49:27 +01:00

7 KiB

CDN

A CDN solution for Hack Club!

Deep under the waves and storms there lies a vault...

Banner illustration by @maxwofford.

Slack Channel

🚀 Features

  • Multi-version API Support (v1, v2, v3)
  • Slack Bot Integration
    • Upload up to 10 files per message
    • Automatic file sanitization
    • file organization
  • Secure API Endpoints
  • Cost-Effective Storage (87-98% cost reduction vs. Vercel CDN)
  • Prevent File Deduplication
  • Organized Storage Structure

🔧 Setup

1. Slack App Configuration

  1. Create a new Slack App at api.slack.com
  2. Enable Socket Mode in the app settings
  3. Add the following Bot Token Scopes:
    • channels:history
    • channels:read
    • chat:write
    • files:read
    • files:write
    • groups:history
    • reactions:write
  4. Enable Event Subscriptions and subscribe to file_shared event
  5. Install the app to your workspace

2. CDN Configuration (Cloudflare + Backblaze)

  1. Create a Backblaze B2 bucket
  2. Set up Cloudflare DNS:
    • Add a CNAME record pointing to your B2 bucket (e.g., f003.backblazeb2.com) you can upload a file and check in info!
    • Enable Cloudflare proxy
  3. Configure SSL/TLS:
    • Set SSL mode to "Full (strict)"
    • ⚠️ WARNING: This setting may break other configurations on your domain! You could use another domain!
  4. Create a Transform Rule:
    • Filter: hostname equals "your-cdn.example.com"
    • Rewrite to: concat("/file/(bucket name)", http.request.uri.path) (make sure u get the bucket name)
    • Preserve query string

3. Environment Setup

Create a .env file with:

# Slack
SLACK_BOT_TOKEN=xoxb-                 # From OAuth & Permissions
SLACK_SIGNING_SECRET=                 # From Basic Information
SLACK_APP_TOKEN=xapp-                 # From Basic Information (for Socket Mode)
SLACK_CHANNEL_ID=channel-id           # Channel where bot operates

# Backblaze (Public Bucket)
B2_APP_KEY_ID=key-id                  # From B2 Application Keys
B2_APP_KEY=app-key                    # From B2 Application Keys
B2_BUCKET_ID=bucket-id                # From B2 Bucket Settings
B2_CDN_URL=https://cdn.example.com

# API
API_TOKEN=beans                       # Set a secure random string
PORT=3000                             

4. Installation & Running

npm install
node index.js

Feel free to use pm2!

📡 API Usage

⚠️ IMPORTANT SECURITY NOTE:

  • All API endpoints require authentication via Authorization: Bearer api-token header
  • This includes all versions (v1, v2, v3) - no exceptions!
  • Use the API_TOKEN from your environment configuration
  • Failure to include a valid token will result in 401 Unauthorized responses

V3 API (Latest)

Version 3

Endpoint: POST https://e2.deployor.hackclub.app/api/v3/new

Headers:

Authorization: Bearer api-token
Content-Type: application/json

Request Example:

curl --location 'https://e2.deployor.hackclub.app/api/v3/new' \
--header 'Authorization: Bearer beans' \
--header 'Content-Type: application/json' \
--data '[
  "https://assets.hackclub.com/flag-standalone.svg",
  "https://assets.hackclub.com/flag-orpheus-left.png",
  "https://assets.hackclub.com/icon-progress-marker.svg"
]'

Response:

{
    "files": [
        {
            "deployedUrl": "https://cdn.deployor.dev/s/v3/3e48b91a4599a3841c028e9a683ef5ce58cea372_flag-standalone.svg",
            "file": "0_16361167e11b0d172a47e726b40d70e9873c792b_upload_1736985095691",
            "sha": "16361167e11b0d172a47e726b40d70e9873c792b",
            "size": 90173
        }
        // Other files
    ],
    "cdnBase": "https://cdn.deployor.dev"
}
V2 API Version 2

Endpoint: POST https://e2.deployor.hackclub.app/api/v2/new

Headers:

Authorization: Bearer api-token
Content-Type: application/json

Request Example:

[
  "https://assets.hackclub.com/flag-standalone.svg",
  "https://assets.hackclub.com/flag-orpheus-left.png",
  "https://assets.hackclub.com/icon-progress-marker.svg"
]

Response:

{
  "flag-standalone.svg": "https://cdn.deployor.dev/s/v2/flag-standalone.svg",
  "flag-orpheus-left.png": "https://cdn.deployor.dev/s/v2/flag-orpheus-left.png",
  "icon-progress-marker.svg": "https://cdn.deployor.dev/s/v2/icon-progress-marker.svg"
}
V1 API Version 1

Endpoint: POST https://e2.deployor.hackclub.app/api/v1/new

Headers:

Authorization: Bearer api-token
Content-Type: application/json

Request Example:

[
  "https://assets.hackclub.com/flag-standalone.svg",
  "https://assets.hackclub.com/flag-orpheus-left.png",
  "https://assets.hackclub.com/icon-progress-marker.svg"
]

Response:

[
  "https://cdn.deployor.dev/s/v1/0_flag-standalone.svg",
  "https://cdn.deployor.dev/s/v1/1_flag-orpheus-left.png",
  "https://cdn.deployor.dev/s/v1/2_icon-progress-marker.svg"
]

🤖 Slack Bot Features

  • Multi-file Upload: Upload up to 10 files in a single message no more than 3 messages at a time!
  • File Organization: Files are stored as /s/{slackUserId}/{timestamp}_{sanitizedFilename}
  • Error Handling: Error Handeling
  • File Sanitization: Automatic filename cleaning
  • Size Limits: Enforces files to be under 2GB

Legacy API Notes

  • V1 and V2 APIs are maintained for backwards compatibility
  • All versions now require authentication via Bearer token
  • We recommend using V3 API for new implementations

Technical Details

  • Storage Structure: /s/v3/{HASH}_{filename}
  • File Naming: /s/{slackUserId}/{unix}_{sanitizedFilename}
  • Cost Efficiency: Uses B2 storage for significant cost savings
  • Security: Token-based authentication for API access

💻 Slack Bot Behavior

  • Reacts to file uploads with status emojis:
    • Processing
    • Success
    • Error
  • Supports up to 10 files per message
  • Max 3 messages concurrently!
  • Maximum file size: 2GB per file

💰 Cost Optimization

  • Uses Cloudflare CDN with Backblaze B2 storage
  • Free egress thanks to Cloudflare-Backblaze Alliance
  • 87-98% cost reduction compared to Vercel CDN

Made with 💜 for Hack Club

All illustrations by @maxwofford