diff --git a/docs/discord-integration.md b/docs/discord-integration.md index 4eebb2a..e0af2ea 100644 --- a/docs/discord-integration.md +++ b/docs/discord-integration.md @@ -1,7 +1,7 @@ # Discord announcements MineGeo uses your Discord bot to send messages through Discord's REST API. -It runs on Vercel and does not need a continuously running bot process, Gateway, +It does not need a continuously running bot process, Gateway, Message Content intent, slash commands, an interactions URL, or a Discord webhook. The bot can appear offline while announcements work. @@ -28,7 +28,7 @@ a transfer of lobby ownership. The counts are a snapshot when posted. 1. Open the [Discord Developer Portal](https://discord.com/developers/applications) and select **New Application**. Name it **MineGeo**, or your preferred bot name. 2. Open **Bot**. Create the bot if prompted, then use **Reset Token** to obtain - its bot token. Keep it private; save it directly into Vercel as described below. + its bot token. Keep it private; save it directly in Dokploy as described below. 3. Under **Installation**, enable **Guild Install**. For the guild's install settings, choose the **bot** scope and these permissions: **View Channels**, **Send Messages**, **Embed Links**. You do not need Administrator permission. @@ -46,10 +46,9 @@ a transfer of lobby ownership. The counts are a snapshot when posted. Discord setup references: [application setup](https://docs.discord.com/developers/quick-start/getting-started), [bot permissions](https://docs.discord.com/developers/topics/permissions). -## Add the Vercel environment variables +## Add the Dokploy environment variables -Open [MineGeo's environment settings](https://vercel.com/pavel-melnikovs-projects-74f979c2/minegeo/settings/environment-variables). -Add these for **Production**: +In Dokploy, open the MineGeo application's **Environment** settings and add: | Name | Value | Sensitive? | | --- | --- | --- | @@ -63,9 +62,8 @@ Leave a channel variable blank to disable that announcement type. A Discord invite such as `MINEGEO_DISCORD_URL` controls the footer button only; it cannot send announcements. -After saving, open **Deployments**, choose the newest Production deployment, -select **Redeploy**, and use the current environment variables. Vercel applies -environment changes to new deployments. See [Vercel's environment-variable guide](https://vercel.com/docs/environment-variables). +After saving, redeploy the MineGeo application so the server uses the new +environment values. For local use, put the same variables in ignored `.env.local` (ordinary `.env` also works) and restart the server. Use a publicly reachable HTTPS `MINEGEO_URL` diff --git a/docs/dokploy-deployment.md b/docs/dokploy-deployment.md index b18f4cc..ff2165d 100644 --- a/docs/dokploy-deployment.md +++ b/docs/dokploy-deployment.md @@ -37,7 +37,7 @@ Also set the following in Dokploy's regular runtime environment: - `NEXT_PUBLIC_SUPABASE_URL` - `NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY` - `SUPABASE_SECRET_KEY` (server-only; never a build argument) -- `MINEGEO_URL` (the public HTTPS site origin) +- `MINEGEO_URL=https://minegeo.site` (the public HTTPS site origin) - `MINEGEO_ALLOW_ANY_ORIGIN=false` Add any optional production variables from `.env.example` in Dokploy's diff --git a/worker/main.ts b/worker/main.ts index bd36122..43755c6 100644 --- a/worker/main.ts +++ b/worker/main.ts @@ -30,6 +30,17 @@ function check(r: { if (r.error) throw new Error(r.error.message); return r.data!; } +function summarizeWorkerError(error: unknown) { + const message = (error instanceof Error ? error.message : String(error)) + .replace(/\s+/g, " ") + .trim(); + if (/<(?:!doctype|html|head|body)\b/i.test(message)) { + const status = message.match(/\b([45]\d{2})\b/)?.[1]; + const provider = /cloudflare/i.test(message) ? "Cloudflare" : "upstream"; + return `${provider} returned an HTML error${status ? ` (${status})` : ""}`; + } + return message.length > 500 ? `${message.slice(0, 497)}…` : message; +} async function processJob(job: { id: string; dataset_id: string; @@ -427,7 +438,9 @@ while (!stopping) { if (jobs?.length) await processJob(jobs[0]); else await new Promise((r) => setTimeout(r, 2500)); } catch (error) { - console.error("Worker:", error instanceof Error ? error.message : error); + console.error( + `Worker error (retrying in 5s): ${summarizeWorkerError(error)}`, + ); await new Promise((r) => setTimeout(r, 5000)); } }