mirror of
https://github.com/System-End/cdn.git
synced 2026-04-19 16:18:17 +00:00
Simplify readme & put usage example up top
Also fix the broken file links!
This commit is contained in:
parent
c809ebcf4b
commit
312d34d103
1 changed files with 16 additions and 166 deletions
182
README.md
182
README.md
|
|
@ -1,7 +1,6 @@
|
|||
<div align="center">
|
||||
<img src="https://assets.hackclub.com/flag-standalone.svg" width="100" alt="flag">
|
||||
<h1>CDN</h1>
|
||||
<p>A CDN solution for Hack Club!</p>
|
||||
<h1>cdn.hackclub.com</h1>
|
||||
</div>
|
||||
|
||||
<p align="center"><i>Deep under the waves and storms there lies a <a href="https://app.slack.com/client/T0266FRGM/C016DEDUL87">vault</a>...</i></p>
|
||||
|
|
@ -15,111 +14,10 @@
|
|||
</a>
|
||||
</div>
|
||||
|
||||
## 🚀 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](https://api.slack.com/apps)
|
||||
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. Storage Configuration
|
||||
|
||||
This CDN supports any S3-compatible storage service. Here's how to set it up using Cloudflare R2 as an example:
|
||||
|
||||
#### Setting up Cloudflare R2 (Example)
|
||||
|
||||
1. **Create R2 Bucket**
|
||||
- Go to Cloudflare Dashboard > R2
|
||||
- Click "Create Bucket"
|
||||
- Name your bucket
|
||||
- Enable public access
|
||||
|
||||
2. **Generate API Credentials**
|
||||
- Go to R2
|
||||
- Click "Manage API tokens" in API
|
||||
- Click "Create API Token"
|
||||
- Permissions: "Object Read & Write"
|
||||
- Save both Access Key ID and Secret Access Key (S3)
|
||||
|
||||
3. **Get Your URL**
|
||||
- Go to R2
|
||||
- Click "Use R2 with APIs" in API
|
||||
- Select S3 Compatible API
|
||||
- The URL is your Endpoint
|
||||
|
||||
|
||||
4. **Configure Custom Domain (Optional)**
|
||||
- Go to R2 > Bucket Settings > Custom Domains
|
||||
- Add your domain (e.g., cdn.beans.com)
|
||||
- Follow DNS configuration steps
|
||||
|
||||
### 3. Environment Setup
|
||||
|
||||
Check out the `example.env` file for getting started!
|
||||
|
||||
### **4. Installation & Running**
|
||||
|
||||
#### **Install Dependencies**
|
||||
Make sure you have [Bun](https://bun.sh/) installed, then run:
|
||||
|
||||
```bash
|
||||
bun install
|
||||
```
|
||||
|
||||
#### **Run the Application**
|
||||
You can start the application using any of the following methods:
|
||||
|
||||
```bash
|
||||
# Using Node.js
|
||||
node index.js
|
||||
|
||||
# Using Bun
|
||||
bun index.js
|
||||
|
||||
# Using Bun with script
|
||||
bun run start
|
||||
```
|
||||
|
||||
#### **Using PM2 (Optional)**
|
||||
For auto-starting the application, you can use PM2:
|
||||
|
||||
```bash
|
||||
pm2 start bun --name "HC-CDN1" -- run start
|
||||
|
||||
# Optionally, save the process list
|
||||
pm2 save
|
||||
|
||||
# Optionally, generate startup script
|
||||
pm2 startup
|
||||
```
|
||||
|
||||
## 📡 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
|
||||
|
||||
|
|
@ -141,8 +39,7 @@ curl --location 'https://cdn.hackclub.com/api/v3/new' \
|
|||
--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"
|
||||
"https://assets.hackclub.com/flag-orpheus-left.png"
|
||||
]'
|
||||
```
|
||||
|
||||
|
|
@ -151,31 +48,19 @@ curl --location 'https://cdn.hackclub.com/api/v3/new' \
|
|||
{
|
||||
"files": [
|
||||
{
|
||||
"deployedUrl": "https://cdn.example.dev/s/v3/3e48b91a4599a3841c028e9a683ef5ce58cea372_flag-standalone.svg",
|
||||
"file": "0_16361167e11b0d172a47e726b40d70e9873c792b_upload_1736985095691",
|
||||
"sha": "16361167e11b0d172a47e726b40d70e9873c792b",
|
||||
"size": 90173
|
||||
"deployedUrl": "https://hc-cdn.hel1.your-objectstorage.com/s/v3/64a9472006c4472d7ac75f2d4d9455025d9838d6_flag-standalone.svg",
|
||||
"file": "0_64a9472006c4472d7ac75f2d4d9455025d9838d6_flag-standalone.svg",
|
||||
"sha": "64a9472006c4472d7ac75f2d4d9455025d9838d6",
|
||||
"size": 4365
|
||||
},
|
||||
{
|
||||
"deployedUrl": "https://cdn.example.dev/s/v3/4e48b91a4599a3841c028e9a683ef5ce58cea372_flag-orpheus-left.png",
|
||||
"file": "1_16361167e11b0d172a47e726b40d70e9873c792b_upload_1736985095692",
|
||||
"sha": "16361167e11b0d172a47e726b40d70e9873c792b",
|
||||
"size": 80234
|
||||
},
|
||||
{
|
||||
"deployedUrl": "https://cdn.example.dev/s/v3/5e48b91a4599a3841c028e9a683ef5ce58cea372_icon-progress-marker.svg",
|
||||
"file": "2_16361167e11b0d172a47e726b40d70e9873c792b_upload_1736985095693",
|
||||
"sha": "16361167e11b0d172a47e726b40d70e9873c792b",
|
||||
"size": 70345
|
||||
},
|
||||
{
|
||||
"deployedUrl": "https://cdn.example.dev/s/v3/6e48b91a4599a3841c028e9a683ef5ce58cea372_flag-orpheus-right.png",
|
||||
"file": "3_16361167e11b0d172a47e726b40d70e9873c792b_upload_1736985095694",
|
||||
"sha": "16361167e11b0d172a47e726b40d70e9873c792b",
|
||||
"size": 60456
|
||||
"deployedUrl": "https://hc-cdn.hel1.your-objectstorage.com/s/v3/d926bfd9811ebfe9172187793a171a5cbcc61992_flag-orpheus-left.png",
|
||||
"file": "1_d926bfd9811ebfe9172187793a171a5cbcc61992_flag-orpheus-left.png",
|
||||
"sha": "d926bfd9811ebfe9172187793a171a5cbcc61992",
|
||||
"size": 8126
|
||||
}
|
||||
],
|
||||
"cdnBase": "https://cdn.example.dev"
|
||||
"cdnBase": "https://hc-cdn.hel1.your-objectstorage.com"
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -196,8 +81,7 @@ Content-Type: application/json
|
|||
```json
|
||||
[
|
||||
"https://assets.hackclub.com/flag-standalone.svg",
|
||||
"https://assets.hackclub.com/flag-orpheus-left.png",
|
||||
"https://assets.hackclub.com/icon-progress-marker.svg"
|
||||
"https://assets.hackclub.com/flag-orpheus-left.png"
|
||||
]
|
||||
```
|
||||
|
||||
|
|
@ -205,8 +89,7 @@ Content-Type: application/json
|
|||
```json
|
||||
{
|
||||
"flag-standalone.svg": "https://cdn.example.dev/s/v2/flag-standalone.svg",
|
||||
"flag-orpheus-left.png": "https://cdn.example.dev/s/v2/flag-orpheus-left.png",
|
||||
"icon-progress-marker.svg": "https://cdn.example.dev/s/v2/icon-progress-marker.svg"
|
||||
"flag-orpheus-left.png": "https://cdn.example.dev/s/v2/flag-orpheus-left.png"
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
|
@ -228,8 +111,7 @@ Content-Type: application/json
|
|||
```json
|
||||
[
|
||||
"https://assets.hackclub.com/flag-standalone.svg",
|
||||
"https://assets.hackclub.com/flag-orpheus-left.png",
|
||||
"https://assets.hackclub.com/icon-progress-marker.svg"
|
||||
"https://assets.hackclub.com/flag-orpheus-left.png"
|
||||
]
|
||||
```
|
||||
|
||||
|
|
@ -237,49 +119,17 @@ Content-Type: application/json
|
|||
```json
|
||||
[
|
||||
"https://cdn.example.dev/s/v1/0_flag-standalone.svg",
|
||||
"https://cdn.example.dev/s/v1/1_flag-orpheus-left.png",
|
||||
"https://cdn.example.dev/s/v1/2_icon-progress-marker.svg"
|
||||
"https://cdn.example.dev/s/v1/1_flag-orpheus-left.png"
|
||||
]
|
||||
```
|
||||
</details>
|
||||
|
||||
## 🤖 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
|
||||
# Technical Details
|
||||
|
||||
- **Storage Structure:** `/s/v3/{HASH}_{filename}`
|
||||
- **File Naming:** `/s/{slackUserId}/{unix}_{sanitizedFilename}`
|
||||
- **Cost Efficiency:** Uses object 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 Object storage
|
||||
- 87-98% cost reduction compared to Vercel CDN
|
||||
|
||||
<div align="center">
|
||||
<br>
|
||||
<p>Made with 💜 for Hack Club</p>
|
||||
<p>All illustrations by <a href="https://gh.maxwofford.com">@maxwofford</a></p>
|
||||
</div>
|
||||
Loading…
Add table
Reference in a new issue