diff --git a/.env.deploy.example b/.env.deploy.example index 3d04af5..d0b9b78 100644 --- a/.env.deploy.example +++ b/.env.deploy.example @@ -10,7 +10,9 @@ TELEGRAM_WEBHOOK_SECRET= # Variable name kept as WORKER_URL for register-webhook.js compatibility. WORKER_URL=https://store-scraper-bot.vercel.app/api/webhook -# Upstash Redis credentials — required by migrate-atlas-to-upstash.js +# Upstash Redis credentials — required by migrate-atlas-to-upstash.js. +# If the Vercel Marketplace Upstash integration is set up, the bot also +# accepts KV_REST_API_URL / KV_REST_API_TOKEN as fallbacks (see upstash.js). UPSTASH_REDIS_REST_URL= UPSTASH_REDIS_REST_TOKEN= KEY_PREFIX=store-scraper-bot: diff --git a/.env.example b/.env.example index 9f190ce..4878d05 100644 --- a/.env.example +++ b/.env.example @@ -4,7 +4,10 @@ TELEGRAM_BOT_USERNAME=your_bot_username TELEGRAM_WEBHOOK_SECRET=generate_a_random_string_at_least_32_chars # Upstash Redis (REST API; same DB can be shared with other Vercel projects -# because KEY_PREFIX namespaces this bot's keys) +# because KEY_PREFIX namespaces this bot's keys). +# If the Vercel Marketplace Upstash integration is enabled, the project will +# already have KV_REST_API_URL and KV_REST_API_TOKEN — the adapter accepts +# those as fallbacks, so duplication is optional. UPSTASH_REDIS_REST_URL=https://xxx.upstash.io UPSTASH_REDIS_REST_TOKEN=your_upstash_rest_token KEY_PREFIX=store-scraper-bot: diff --git a/scripts/migrate-atlas-to-upstash.js b/scripts/migrate-atlas-to-upstash.js index d775dbd..db6fe33 100644 --- a/scripts/migrate-atlas-to-upstash.js +++ b/scripts/migrate-atlas-to-upstash.js @@ -45,12 +45,14 @@ async function main() { const mongoUri = process.env.MONGODB_URI; if (!mongoUri) exitWith('MONGODB_URI not set; check .env.deploy'); - const upstashUrl = process.env.UPSTASH_REDIS_REST_URL; - const upstashToken = process.env.UPSTASH_REDIS_REST_TOKEN; + // Accept either Upstash naming convention (vanilla signup) or Vercel + // Marketplace integration names — same as the runtime adapter. + const upstashUrl = process.env.UPSTASH_REDIS_REST_URL ?? process.env.KV_REST_API_URL; + const upstashToken = process.env.UPSTASH_REDIS_REST_TOKEN ?? process.env.KV_REST_API_TOKEN; const dryRun = process.argv.includes('--dry-run'); if (!dryRun) { - if (!upstashUrl) exitWith('UPSTASH_REDIS_REST_URL not set; check .env.deploy'); - if (!upstashToken) exitWith('UPSTASH_REDIS_REST_TOKEN not set; check .env.deploy'); + if (!upstashUrl) exitWith('UPSTASH_REDIS_REST_URL (or KV_REST_API_URL) not set; check .env.deploy'); + if (!upstashToken) exitWith('UPSTASH_REDIS_REST_TOKEN (or KV_REST_API_TOKEN) not set; check .env.deploy'); } const includeCache = process.argv.includes('--include-cache'); diff --git a/src/repository/upstash.js b/src/repository/upstash.js index 3f772a3..7304f79 100644 --- a/src/repository/upstash.js +++ b/src/repository/upstash.js @@ -29,13 +29,18 @@ export class UpstashUnavailable extends Error { // Build a handle bundling the Redis client and the key prefix together. // The handle is what callers pass into getJson/putJson/del/scan — it stays // opaque so repositories never need to know about prefixing themselves. +// +// Accepts both env var naming conventions: +// - UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN (vanilla Upstash signup) +// - KV_REST_API_URL / KV_REST_API_TOKEN (Vercel Marketplace integration) +// so the operator doesn't have to duplicate vars when the bot shares an +// Upstash DB provisioned via Vercel. export function createUpstashClient(env) { - if (!env?.UPSTASH_REDIS_REST_URL) throw new UpstashUnavailable('UPSTASH_REDIS_REST_URL'); - if (!env?.UPSTASH_REDIS_REST_TOKEN) throw new UpstashUnavailable('UPSTASH_REDIS_REST_TOKEN'); - const client = new Redis({ - url: env.UPSTASH_REDIS_REST_URL, - token: env.UPSTASH_REDIS_REST_TOKEN, - }); + const url = env?.UPSTASH_REDIS_REST_URL ?? env?.KV_REST_API_URL; + const token = env?.UPSTASH_REDIS_REST_TOKEN ?? env?.KV_REST_API_TOKEN; + if (!url) throw new UpstashUnavailable('UPSTASH_REDIS_REST_URL or KV_REST_API_URL'); + if (!token) throw new UpstashUnavailable('UPSTASH_REDIS_REST_TOKEN or KV_REST_API_TOKEN'); + const client = new Redis({ url, token }); const prefix = env.KEY_PREFIX ?? DEFAULT_KEY_PREFIX; return { client, prefix }; }