From bf5d61ffca148bad6a4aa26dc780b4b470c689bf Mon Sep 17 00:00:00 2001 From: Minz Date: Wed, 30 Sep 2026 23:45:38 +0200 Subject: [PATCH] Fetch vrc.tl events via Cloudflare Worker relay vrc.tl returns 403 for the VPS IP range. Route lookups through a relay Worker (relay/), configured via vrctl.relayUrl/relaySecret in config.json. Also handle events without eventSlots/performers instead of crashing. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01MrxnVXujrZqNrENxJZfVkU --- config.json.example | 6 +++++- events/vrcTlEvents.js | 11 +++++++---- relay/README.md | 10 ++++++++++ relay/src/index.js | 20 ++++++++++++++++++++ relay/wrangler.toml | 3 +++ 5 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 relay/README.md create mode 100644 relay/src/index.js create mode 100644 relay/wrangler.toml diff --git a/config.json.example b/config.json.example index ef5725d..a99331f 100644 --- a/config.json.example +++ b/config.json.example @@ -6,5 +6,9 @@ "clientID": "", "clientSecret": "" }, - "lfmKey": "" + "lfmKey": "", + "vrctl": { + "relayUrl": "", + "relaySecret": "" + } } \ No newline at end of file diff --git a/events/vrcTlEvents.js b/events/vrcTlEvents.js index 26479aa..a1107e6 100644 --- a/events/vrcTlEvents.js +++ b/events/vrcTlEvents.js @@ -1,5 +1,6 @@ const { Events } = require('discord.js'); const axios = require('axios').default; +const { vrctl } = require(process.env.CONFIG_FILE ? `../${process.env.CONFIG_FILE}` : '../config.json'); const SWARM_EVENTS_CHANNEL_ID = '1536067515115905155'; const VRC_CROSSPOST_CHANNEL_ID = '1438261670916133055'; @@ -19,15 +20,17 @@ module.exports = { for (const eventId of eventIds) { try { - const { data } = await axios.get(`https://vrc.tl/api/v1/events/${eventId}`); + const { data } = await axios.get(`${vrctl.relayUrl}/events/${eventId}`, { + headers: { 'x-relay-secret': vrctl.relaySecret }, + }); const event = data.events?.[0]; if (!event) continue; - const performersById = new Map(data.performers.map(performer => [performer.id, performer.name])); + const performersById = new Map((data.performers ?? []).map(performer => [performer.id, performer.name])); - const lineup = [...event.eventSlots] + const lineup = [...(event.eventSlots ?? [])] .sort((a, b) => a.start - b.start) - .flatMap(slot => [...slot.performers] + .flatMap(slot => [...(slot.performers ?? [])] .sort((a, b) => a.order - b.order) .map(slotPerformer => performersById.get(slotPerformer.performerId))) .filter(Boolean); diff --git a/relay/README.md b/relay/README.md new file mode 100644 index 0000000..f318201 --- /dev/null +++ b/relay/README.md @@ -0,0 +1,10 @@ +# vrc.tl relay + +Cloudflare Worker that proxies vrc.tl event lookups (vrc.tl blocks the VPS IP range). +Only serves `GET /events/` and requires an `x-relay-secret` header. + + cd relay + npx wrangler deploy + npx wrangler secret put RELAY_SECRET + +Set `vrctl.relayUrl` and `vrctl.relaySecret` in the bot's config.json. diff --git a/relay/src/index.js b/relay/src/index.js new file mode 100644 index 0000000..e8b750b --- /dev/null +++ b/relay/src/index.js @@ -0,0 +1,20 @@ +// Minimal relay for vrc.tl event lookups. Only GET /events/, requires secret header. +export default { + async fetch(request, env) { + if (request.method !== 'GET') return new Response('Method not allowed', { status: 405 }); + if (!env.RELAY_SECRET || request.headers.get('x-relay-secret') !== env.RELAY_SECRET) { + return new Response('Unauthorized', { status: 401 }); + } + const match = new URL(request.url).pathname.match(/^\/events\/(\d{1,10})$/); + if (!match) return new Response('Not found', { status: 404 }); + + const upstream = await fetch(`https://vrc.tl/api/v1/events/${match[1]}`, { + headers: { accept: 'application/json' }, + cf: { cacheTtl: 300, cacheEverything: true }, + }); + return new Response(upstream.body, { + status: upstream.status, + headers: { 'content-type': upstream.headers.get('content-type') ?? 'application/json' }, + }); + }, +}; diff --git a/relay/wrangler.toml b/relay/wrangler.toml new file mode 100644 index 0000000..c65a93d --- /dev/null +++ b/relay/wrangler.toml @@ -0,0 +1,3 @@ +name = "vrctl-relay" +main = "src/index.js" +compatibility_date = "2026-09-01"