From 463cf148ef4c098ddf63bec599e00c81fe8a5aaf Mon Sep 17 00:00:00 2001 From: tbxark Date: Thu, 14 Nov 2024 21:02:00 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E7=AE=80=E5=8C=96vercel=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=E6=B5=81=E7=A8=8B,=E6=B7=BB=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=90=8C=E6=AD=A5=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- doc/cn/VERCEL.md | 5 ++-- doc/en/VERCEL.md | 5 ++-- package.json | 2 ++ packages/apps/vercel/package.json | 3 ++- packages/apps/vercel/src/index.ts | 24 ++++++++++++++----- pnpm-lock.yaml | 3 +++ scripts/gen-vercel-env.ts | 22 ----------------- scripts/vercel-sync-env.ts | 40 +++++++++++++++++++++++++++++++ 9 files changed, 73 insertions(+), 34 deletions(-) delete mode 100644 scripts/gen-vercel-env.ts create mode 100644 scripts/vercel-sync-env.ts diff --git a/.gitignore b/.gitignore index f2960954..d235bf0b 100644 --- a/.gitignore +++ b/.gitignore @@ -152,4 +152,5 @@ wrangler.toml /dist/index.cjs /dist/index.d.ts /dist/src -/packages/**/dist \ No newline at end of file +/packages/**/dist +.env*.local diff --git a/doc/cn/VERCEL.md b/doc/cn/VERCEL.md index 289d5cfe..f6d7d619 100644 --- a/doc/cn/VERCEL.md +++ b/doc/cn/VERCEL.md @@ -4,7 +4,7 @@ ### 自动部署 -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FTBXark%2FChatGPT-Telegram-Workers&env=UPSTASH_REDIS_REST_URL,UPSTASH_REDIS_REST_TOKEN,VERCEL_DOMAIN,TELEGRAM_AVAILABLE_TOKENS&project-name=chatgpt-telegram-workers&repository-name=ChatGPT-Telegram-Workers&demo-title=ChatGPT-Telegram-Workers&demo-description=Deploy%20your%20own%20Telegram%20ChatGPT%20bot%20on%20Cloudflare%20Workers%20with%20ease.&demo-url=https%3A%2F%2Fchatgpt-telegram-workers.vercel.app) +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FTBXark%2FChatGPT-Telegram-Workers&env=UPSTASH_REDIS_REST_URL,UPSTASH_REDIS_REST_TOKEN,TELEGRAM_AVAILABLE_TOKENS&project-name=chatgpt-telegram-workers&repository-name=ChatGPT-Telegram-Workers&demo-title=ChatGPT-Telegram-Workers&demo-description=Deploy%20your%20own%20Telegram%20ChatGPT%20bot%20on%20Cloudflare%20Workers%20with%20ease.&demo-url=https%3A%2F%2Fchatgpt-telegram-workers.vercel.app) ### 手动部署 @@ -14,4 +14,5 @@ pnpm deploy:vercel ``` 1. pnpm deploy:vercel 过程中可能需要登陆Vercel账号 -2. 首次部署由于缺少环境变量,页面会报错,需要手动前往Vercel控制台添加环境变量,然后重新部署生效 \ No newline at end of file +2. 首次部署由于缺少环境变量,页面会报错,需要手动前往Vercel控制台添加环境变量,然后重新部署生效 +3. 你可以复用cloudflare workers的`wrangler.toml`配置文件,只需要执行`pnpm run vercel:syncenv`即可同步环境变量到Vercel, vercel修改环境变量后需要重新部署才能生效 \ No newline at end of file diff --git a/doc/en/VERCEL.md b/doc/en/VERCEL.md index b768a278..2dc1efd3 100644 --- a/doc/en/VERCEL.md +++ b/doc/en/VERCEL.md @@ -4,7 +4,7 @@ The sample code provided in `/packages/app/vercel` can complete the Vercel deplo ### Automatic Deployment -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FTBXark%2FChatGPT-Telegram-Workers&env=UPSTASH_REDIS_REST_URL,UPSTASH_REDIS_REST_TOKEN,VERCEL_DOMAIN,TELEGRAM_AVAILABLE_TOKENS&project-name=chatgpt-telegram-workers&repository-name=ChatGPT-Telegram-Workers&demo-title=ChatGPT-Telegram-Workers&demo-description=Deploy%20your%20own%20Telegram%20ChatGPT%20bot%20on%20Cloudflare%20Workers%20with%20ease.&demo-url=https%3A%2F%2Fchatgpt-telegram-workers.vercel.app) +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FTBXark%2FChatGPT-Telegram-Workers&env=UPSTASH_REDIS_REST_URL,UPSTASH_REDIS_REST_TOKEN,TELEGRAM_AVAILABLE_TOKENS&project-name=chatgpt-telegram-workers&repository-name=ChatGPT-Telegram-Workers&demo-title=ChatGPT-Telegram-Workers&demo-description=Deploy%20your%20own%20Telegram%20ChatGPT%20bot%20on%20Cloudflare%20Workers%20with%20ease.&demo-url=https%3A%2F%2Fchatgpt-telegram-workers.vercel.app) ### Manual deployment @@ -13,4 +13,5 @@ pnpm install pnpm deploy:vercel ``` 1. You may need to log in to your Vercel account during the pnpm deploy:vercel process. -2. For the first deployment, due to missing environment variables, the page will report errors. You need to manually go to the Vercel console to add environment variables, and then redeploy to take effect. \ No newline at end of file +2. For the first deployment, due to missing environment variables, the page will report errors. You need to manually go to the Vercel console to add environment variables, and then redeploy to take effect. +3. You can reuse the `wrangler.toml` configuration file of Cloudflare Workers, just need to execute `pnpm run vercel:syncenv` to synchronize environment variables to Vercel. After Vercel modifies the environment variables, a redeployment is required for them to take effect. \ No newline at end of file diff --git a/package.json b/package.json index aadf1921..35fd61c3 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "deploy:workersnext": "pnpm run build:workersnext && TOML_PATH=$INIT_CWD/wrangler.toml pnpm --filter @chatgpt-telegram-workers/workers-next deploy", "deploy:vercel": "pnpm run build:vercel && vercel --prod", "start:local": "pnpm run build:local && CONFIG_PATH=$INIT_CWD/config.json TOML_PATH=$INIT_CWD/wrangler.toml pnpm --filter @chatgpt-telegram-workers/local start", + "vercel:syncenv": "tsx scripts/vercel-sync-env.ts && vercel --prod", "clean": "pnpm -r run clean", "wrangler": "wrangler" }, @@ -58,6 +59,7 @@ "vite-plugin-dts": "^4.3.0", "wrangler": "^3.86.1", "vercel": "^39.0.0", + "toml": "^3.0.0", "tsx": "^4.19.2" } } diff --git a/packages/apps/vercel/package.json b/packages/apps/vercel/package.json index 1b6c97d3..db649b96 100644 --- a/packages/apps/vercel/package.json +++ b/packages/apps/vercel/package.json @@ -6,7 +6,8 @@ "types": "./dist/index.d.ts", "scripts": { "build": "pnpm vite build", - "clean": "rm -rf dist" + "clean": "rm -rf dist", + "sync": "tsx src/sync.ts" }, "dependencies": { "@chatgpt-telegram-workers/core": "workspace:*", diff --git a/packages/apps/vercel/src/index.ts b/packages/apps/vercel/src/index.ts index eb85673f..a752e3e1 100644 --- a/packages/apps/vercel/src/index.ts +++ b/packages/apps/vercel/src/index.ts @@ -8,11 +8,11 @@ export default async function (request: VercelRequest, response: VercelResponse) const { UPSTASH_REDIS_REST_URL = '', UPSTASH_REDIS_REST_TOKEN = '', - VERCEL_DOMAIN = '', + VERCEL_PROJECT_PRODUCTION_URL = '', } = process.env; - for (const [KEY, VALUE] of Object.entries({ UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN, VERCEL_DOMAIN })) { + for (const [KEY, VALUE] of Object.entries({ UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN })) { if (!VALUE) { - response.status(500).send({ + response.status(500).json({ error: `${KEY} is required`, message: 'Set environment variables and redeploy', }); @@ -29,7 +29,16 @@ export default async function (request: VercelRequest, response: VercelResponse) if (request.body) { body = JSON.stringify(request.body); } - const newReq = new Request(VERCEL_DOMAIN + request.url, { + if (request.url === '/vercel/debug') { + response.status(200).json({ + message: 'OK', + base: VERCEL_PROJECT_PRODUCTION_URL, + }); + return; + } + const url = `https://${VERCEL_PROJECT_PRODUCTION_URL}${request.url}`; + console.log(`Forwarding request to ${url}`); + const newReq = new Request(url, { method: request.method, headers: Object.entries(request.headers).reduce((acc, [key, value]) => { if (value === undefined) { @@ -47,11 +56,14 @@ export default async function (request: VercelRequest, response: VercelResponse) body, }); const res = await router.fetch(newReq); + for (const [key, value] of res.headers.entries()) { + response.setHeader(key, value); + } response.status(res.status).send(await res.text()); } catch (e) { - response.status(500).send(JSON.stringify({ + response.status(500).json({ message: (e as Error).message, stack: (e as Error).stack, - }, null, 2)); + }); } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7854a2c..5ab747f0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ importers: telegram-bot-api-types: specifier: ^7.11.0 version: 7.11.0 + toml: + specifier: ^3.0.0 + version: 3.0.0 tsx: specifier: ^4.19.2 version: 4.19.2 diff --git a/scripts/gen-vercel-env.ts b/scripts/gen-vercel-env.ts deleted file mode 100644 index 6444a6ef..00000000 --- a/scripts/gen-vercel-env.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { execSync } from 'node:child_process'; -import fs from 'node:fs/promises'; -import { parse } from 'toml'; - -async function main() { - const { - TOML_PATH = 'wrangler.toml', - } = process.env; - const { vars } = parse(await fs.readFile(TOML_PATH, 'utf-8')); - for (const [key, value] of Object.entries(vars)) { - try { - execSync(`vercel env add ${key} production --force`, { - input: `${value}`, - encoding: 'utf-8', - }); - } catch (e) { - console.error(e); - } - } -} - -main().catch(console.error); diff --git a/scripts/vercel-sync-env.ts b/scripts/vercel-sync-env.ts new file mode 100644 index 00000000..2f929116 --- /dev/null +++ b/scripts/vercel-sync-env.ts @@ -0,0 +1,40 @@ +import { execSync } from 'node:child_process'; +import fs from 'node:fs/promises'; +import { parse } from 'toml'; + +async function main() { + const { + TOML_PATH = 'wrangler.toml', + VERCEL_ENV = 'production', + VERCEL_BIN = './node_modules/.bin/vercel', + } = process.env; + + const envs = execSync(`${VERCEL_BIN} env ls ${VERCEL_ENV}`, { + encoding: 'utf-8', + }).trim().split('\n').map(l => l.trim()).slice(1).map(l => l.split(/\s+/)[0]).map(l => l.replace(/[^\x20-\x7E]/g, '').replace(/\[\d+m/g, '')); + const usedKeys = new Set(); + usedKeys.add('UPSTASH_REDIS_REST_URL'); + usedKeys.add('UPSTASH_REDIS_REST_TOKEN'); + const { vars } = parse(await fs.readFile(TOML_PATH, 'utf-8')); + for (const [key, value] of Object.entries(vars)) { + try { + usedKeys.add(key); + execSync(`${VERCEL_BIN} env add ${key} ${VERCEL_ENV} --force`, { + input: `${value}`, + encoding: 'utf-8', + }); + } catch (e) { + console.error(e); + } + } + for (const key of envs) { + if (!usedKeys.has(key)) { + console.log(`Delete ${key}?)`); + execSync(`${VERCEL_BIN} env rm ${key} ${VERCEL_ENV}`, { + encoding: 'utf-8', + }); + } + } +} + +main().catch(console.error);