Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ tests/
.env
.env.*
.dockerignore
bun.lock
docker-compose.yml
35 changes: 35 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Release

on:
push:
tags: ["v*"]

permissions:
contents: read
packages: write

jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=semver,pattern={{version}}
type=raw,value=latest

- uses: docker/build-push-action@v6
with:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
15 changes: 14 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM oven/bun:latest
# Build stage — install dependencies
FROM oven/bun:latest AS builder

WORKDIR /app

Expand All @@ -7,6 +8,18 @@ RUN bun install --frozen-lockfile --production

COPY *.ts ./

# Runtime stage — slim image
FROM oven/bun:slim

WORKDIR /app

COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
COPY --from=builder /app/*.ts ./

EXPOSE 3000

HEALTHCHECK --interval=15s --timeout=5s --start-period=10s --retries=3 \
CMD bun -e "fetch('http://localhost:3000/health').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"

CMD ["bun", "run", "index.ts"]
39 changes: 33 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,34 @@ Discord REST API caching proxy — polls Discord once, caches responses, serves

## Quick Start

### Docker

```bash
# Run with Bun
DISCORD_BOT_TOKEN=your-token DISCORD_GUILD_ID=your-guild-id bun run start
docker run -d \
-e DISCORD_BOT_TOKEN=your-token \
-e DISCORD_GUILD_ID=your-guild-id \
-p 3000:3000 \
ghcr.io/wave-engineering/scream-hole:latest
```

### Docker Compose (local dev)

# Run with Docker
docker build -t scream-hole .
docker run -e DISCORD_BOT_TOKEN=your-token -e DISCORD_GUILD_ID=your-guild-id -p 3000:3000 scream-hole
Create a `.env` file:

```env
DISCORD_BOT_TOKEN=your-token
DISCORD_GUILD_ID=your-guild-id
```

```bash
docker compose up
```

### Bun (direct)

```bash
bun install
DISCORD_BOT_TOKEN=your-token DISCORD_GUILD_ID=your-guild-id bun run start
```

## Configuration
Expand All @@ -20,14 +41,18 @@ docker run -e DISCORD_BOT_TOKEN=your-token -e DISCORD_GUILD_ID=your-guild-id -p
| `DISCORD_BOT_TOKEN` | Yes | — | Discord bot token (or `~/secrets/discord-bot-token`) |
| `DISCORD_GUILD_ID` | Yes | — | Discord server ID to proxy |
| `POLL_INTERVAL_MS` | No | `15000` | How often to poll Discord (ms) |
| `CACHE_WINDOW_MS` | No | `14400000` | Cache window — messages older than this are evicted (default 4h) |
| `PORT` | No | `3000` | HTTP server port |
| `LOG_LEVEL` | No | `info` | Log level: debug, info, warn, error |

## Endpoints

| Method | Path | Description |
|--------|------|-------------|
| GET | `/health` | Health check — returns status, uptime, version |
| GET | `/health` | Health check — status, uptime, version, cache stats |
| GET | `/api/v10/guilds/{id}/channels` | Cached channel list |
| GET | `/api/v10/channels/{id}/messages?after=SNOWFLAKE` | Cached messages (`after` required) |
| POST | `/api/v10/channels/{id}/messages` | Write pass-through — forwards to Discord |

## Development

Expand All @@ -46,6 +71,8 @@ Consumer C ──┘ │
cache
```

Single poller fetches channels and messages on a configurable interval. Consumers read from the cache via Discord-compatible REST endpoints. Writes are forwarded to Discord and injected into the cache immediately.

## License

MIT
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
services:
scream-hole:
build: .
ports:
- "3000:3000"
env_file: .env
restart: unless-stopped
Loading