-
-
Notifications
You must be signed in to change notification settings - Fork 50
Expand file tree
/
Copy path.env.example
More file actions
176 lines (154 loc) · 8.89 KB
/
Copy path.env.example
File metadata and controls
176 lines (154 loc) · 8.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# MongoDB connection details
MONGODB_URI="mongodb://localhost:27017/"
# Redis connection details
REDIS_URI="redis://localhost:6379"
REDIS_TTL_SECONDS=3600 # 1 hour
# Sentry configuration (error tracking & performance monitoring)
SENTRY_DSN="" # Leave empty to disable Sentry
SENTRY_SEND_PII="false" # Send user emails/IPs (consider GDPR implications)
SENTRY_TRACES_SAMPLE_RATE=0.1 # % of transactions to capture (1.0 in dev, 0.05-0.1 in prod to reduce costs)
SENTRY_PROFILE_SAMPLE_RATE=0.05 # % of profiling sessions to capture (1.0 in dev, 0.01-0.05 in prod, very expensive)
# Analytics & tracking (leave empty to disable)
CLARITY_ID="" # Microsoft Clarity tracking ID
HCAPTCHA_SITEKEY="" # hCaptcha site key (public, used in templates)
# App configs
SECRET_KEY="" # To generate: python -c "import os; print(os.urandom(32).hex())"
HOST_URI="127.0.0.1:8000"
ENV="development" # change to "production" in production
# none = self-host (every account holds every feature); paddle = spoo.me cloud.
# Production refuses to boot unless this is set explicitly.
BILLING_PROVIDER="none"
# CORS — allowed origins for private routes (auth, oauth, dashboard)
# Public API routes (/api/v1/*) always allow all origins.
# Set to your frontend domain(s) in production. Leave empty to block all cross-origin
# requests to private routes (safe default).
# Example: CORS_PRIVATE_ORIGINS='["https://spoo.me","chrome-extension://your-ext-id"]'
CORS_PRIVATE_ORIGINS='[]'
# Logging Configuration
LOG_LEVEL=DEBUG # DEBUG, INFO, WARNING, ERROR, CRITICAL
LOG_FORMAT=console # json (prod) or console (dev)
# Sampling Rates (0.0 to 1.0)
SAMPLE_RATE_REDIRECT=0.05 # 5% of URL redirects
SAMPLE_RATE_STATS=0.20 # 20% of stats queries
SAMPLE_RATE_CACHE=0.01 # 1% of cache operations
SAMPLE_RATE_EXPORT=0.80 # 80% of exports
# Configs for the contact and report forms
CONTACT_WEBHOOK=""
URL_REPORT_WEBHOOK=""
HCAPTCHA_SECRET=""
# JWT configs
JWT_ISSUER=
JWT_AUDIENCE=
ACCESS_TOKEN_TTL_SECONDS=3600
REFRESH_TOKEN_TTL_SECONDS=2592000
COOKIE_SECURE="false" # false: for local dev, true: for production
JWT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n.....\n-----END PRIVATE KEY-----"
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n.....\n-----END PUBLIC KEY-----"
JWT_SECRET=""
# To generate these private key run this commands:
# openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out jwt_private_key.pem
# for public key:
# openssl rsa -pubout -in jwt_private_key.pem -out jwt_public_key.pem
# for JWT_SECRET (if not using RSA keys):
# import os; print(os.urandom(32).hex())
# Use JWT_SECRET only if you are not using RSA keys (JWT_PRIVATE_KEY and JWT_PUBLIC_KEY)
# OAuth configs
# Google OAuth
# How to generate these keys:
# 1. Go to https://console.cloud.google.com/apis/credentials
# 2. Create a new project (if you don't have one)
# 3. Enable the Google+ API
# 4. Configure OAuth consent screen (make sure to add http://localhost:8000 and http://127.0.0.1:8000)
# 5. Create OAuth 2.0 Client IDs and get the client ID and client secret
# 6. Set the authorized redirect URIs / Redirect URIs to:
# http://localhost:8000/oauth/google/callback (for local dev)
# http://127.0.0.1:8000/oauth/google/callback (for local dev)
# http://your-production-domain.com/oauth/google/callback (for production)
GOOGLE_OAUTH_CLIENT_ID=""
GOOGLE_OAUTH_CLIENT_SECRET=""
GOOGLE_OAUTH_REDIRECT_URI="http://127.0.0.1:8000/oauth/google/callback"
# GitHub OAuth
# How to generate these keys:
# 1. Go to https://github.com/settings/developers
# 2. Create a new OAuth App (Not GitHub App !important)
# 3. Set the homepage URL to http://127.0.0.1:8000 or http://localhost:8000 for local dev
# 4. Set the authorization callback URI to http://127.0.0.1:8000/oauth/github/callback
# For production, set it to http://your-production-domain.com/oauth/github/callback
# 5. Make sure, where this app can be installed, "Any account" is selected
# 6. click on "Generate a new Client Secret" to get the client secret
GITHUB_OAUTH_CLIENT_ID=""
GITHUB_OAUTH_CLIENT_SECRET=""
GITHUB_OAUTH_REDIRECT_URI="http://127.0.0.1:8000/oauth/github/callback"
# Discord OAuth
# How to generate these keys:
# 1. Go to https://discord.com/developers/applications
# 2. Create a new application
# 3. Go to OAuth2 section and add a redirect URI:
# http://localhost:8000/oauth/discord/callback (for local dev)
# http://your-production-domain.com/oauth/discord/callback (for production)
# 4. In the scopes section, select "identify" and "email"
DISCORD_OAUTH_CLIENT_ID=""
DISCORD_OAUTH_CLIENT_SECRET=""
DISCORD_OAUTH_REDIRECT_URI="http://127.0.0.1:8000/oauth/discord/callback"
# ZeptoMail Configuration (for transactional emails)
# How to get these credentials:
# 1. Sign up at https://www.zoho.com/zeptomail/
# 2. Add and verify your domain (DKIM + CNAME records)
# 3. Create a Mail Agent
# 4. Go to SMTP/API section and copy your Send Mail Token
# 5. Set ZEPTO_API_TOKEN to the token value
ZEPTO_API_TOKEN=""
ZEPTO_FROM_EMAIL="noreply@your-domain.com"
ZEPTO_FROM_NAME="Your App Name"
APP_URL="http://127.0.0.1:8000"
GITHUB_REPO="" # org/repo format
# ── Click Event Pipeline (optional — leave unset for classic inline tracking) ──
# Decouples click analytics from the redirect hot path: the app appends each
# click to a Redis Stream (~1ms) and a worker container processes it
# out-of-band. Requires a DEDICATED queue Redis (noeviction + AOF) — never
# reuse the cache Redis, its allkeys-lru policy would evict in-flight events.
# Start locally with: docker compose --profile click-events up
# CLICK_EVENTS_SINK="stream" # "inline" (default) | "stream"
# CLICK_EVENTS_QUEUE_REDIS_URI="redis://redis-queue:6379/0"
# CLICK_EVENTS_HOTNESS_ENABLED="false" # hot-URL detection consumer
# CLICK_EVENTS_HOT_THRESHOLD="50" # clicks per window = hot
# CLICK_EVENTS_HOT_WINDOW_SECONDS="60"
# CLICK_EVENTS_WORKER_GROUPS='["stats", "hotness"]' # groups THIS worker hosts
# REDIS_QUEUE_PASSWORD="" # compose-level (prod redis-queue)
# ── Webhooks (optional — off by default) ──────────────────────────────────────
# Real-time event deliveries to subscriber URLs (Standard Webhooks spec).
# Needs only Mongo to run: with the click pipeline's queue Redis present,
# events ride streams and the worker delivers; without it, dispatch happens
# in-process and the app runs the delivery loop itself — no extra services.
# Access is feature-flag gated per user on top of this master switch.
# WEBHOOKS_ENABLED="false"
# WEBHOOKS_RUNTIME="auto" # auto | worker | embedded | off
# WEBHOOKS_MAX_ENDPOINTS="5" # per user
# WEBHOOKS_DELIVERY_TIMEOUT_SECONDS="15"
# WEBHOOKS_MAX_CONSECUTIVE_FAILURES="10" # exhausted deliveries → auto-disable
# WEBHOOKS_DELIVERY_LOG_TTL_DAYS="30" # events + delivery log retention
# WEBHOOKS_MAX_PENDING_PER_ENDPOINT="1000" # backlog cap; beyond = drop+count
# WEBHOOKS_EXECUTOR_CONCURRENCY="8" # delivery attempts in flight per process
# WEBHOOKS_EXECUTOR_PER_ENDPOINT_CONCURRENCY="2" # of those, max held by one endpoint
# ── URL safety pipeline ──────────────────────────────────────────────────
# Report-triggered destination analysis, per-host verdicts, and automatic
# enforcement (blocklisted destinations get all their links blocked, caches
# evicted, and an operator embed). With queue Redis the click worker
# analyzes async; without it, analysis runs inline in the app process.
# SAFETY_ENABLED="false"
# SAFETY_REVERDICT_TTL_HOURS="24" # skip re-analysis fresher than this
# SAFETY_FISHFISH_ENABLED="true" # fishfish.gg feed (free, no auth)
# GCP key enabling Google Web Risk lookups, for both the safety analyzer and
# the URL expander tool's displayed verdict.
# SAFETY_WEB_RISK_API_KEY=""
# The expander is public and shares this quota, so its share is capped.
# SAFETY_WEB_RISK_EXPANDER_DAILY_BUDGET="1000"
# ── Scheduled tasks ──────────────────────────────────────────────────────
# Recurring background jobs (feed syncs, sweeps, archival) on a Mongo-backed
# runner. Needs only Mongo: with a queue Redis configured the click worker
# hosts the loop, without one the app process runs it — no extra services.
# Enabled by default; individual tasks gate themselves on their own settings.
# SCHEDULER_ENABLED="true"
# SCHEDULER_RUNTIME="auto" # auto | worker | embedded | off
# SCHEDULER_POLL_SECONDS="5" # claim-poll granularity
# SCHEDULER_LEASE_SECONDS="600" # crashed-run re-claim window