Skip to content

Commit ba9d944

Browse files
committed
Add Vercel setup
1 parent 97f3381 commit ba9d944

File tree

8 files changed

+101
-20
lines changed

8 files changed

+101
-20
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,7 @@ data/
135135

136136
# Ignore SQLite database
137137
*.db
138-
*.db-journal
138+
*.db-journal
139+
140+
# Vercel project configuration
141+
.vercel

.vercelignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.env*

README.md

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,55 @@ Follow these steps to set up and run your bot using this template:
5454
npm run dev
5555
```
5656

57-
**Production Mode:**
57+
**Production Mode:**
5858

59-
Install only production dependencies:
59+
Install Vercel CLI:
6060
```bash
61-
npm install --only=prod
61+
npm i -g vercel
6262
```
6363

64-
Set `DEBUG` environment variable to `false` in your `.env` file.
64+
Create a project:
65+
```bash
66+
vercel link
67+
```
68+
69+
Set `NODEJS_HELPERS` environment variable to `0`:
70+
```bash
71+
vercel env add NODEJS_HELPERS
72+
```
73+
74+
Set `BOT_MODE` environment variable to `webhook`:
75+
```bash
76+
vercel env add BOT_MODE
77+
```
6578

66-
Start the bot in production mode:
79+
Set `BOT_TOKEN` environment variable:
80+
```bash
81+
vercel env add BOT_TOKEN --sensitive
82+
```
83+
84+
Set `BOT_WEBHOOK_SECRET` environment variable to a random secret token:
85+
```bash
86+
# Generate and set secret token using Node
87+
node -e "console.log(crypto.randomBytes(256*0.75).toString('base64url'))" | vercel env add BOT_WEBHOOK_SECRET --sensitive production
88+
```
89+
```bash
90+
# OR using Python
91+
python3 -c "import secrets; print(secrets.token_urlsafe(256))" | vercel env add BOT_WEBHOOK_SECRET --sensitive production
92+
```
6793
```bash
68-
npm run start:force # skip type checking and start
69-
# or
70-
npm start # with type checking (requires development dependencies)
94+
# OR set manually:
95+
vercel env add BOT_WEBHOOK_SECRET --sensitive
96+
```
97+
98+
Deploy your bot:
99+
```bash
100+
vercel
101+
```
102+
103+
After successful deployment, set up a webhook to connect your Vercel app with Telegram, modify the below URL to your credentials and visit it from your browser:
104+
```
105+
https://APP_NAME.vercel.app/BOT_TOKEN
71106
```
72107

73108
### List of Available Commands
@@ -302,16 +337,6 @@ bun add -d @types/bun
302337
Enables debug mode. You may use <code>config.isDebug</code> flag to enable debugging functions.
303338
</td>
304339
</tr>
305-
<tr>
306-
<td>BOT_WEBHOOK</td>
307-
<td>
308-
String
309-
</td>
310-
<td>
311-
<i>Optional in <code>polling</code> mode.</i>
312-
Webhook endpoint URL, used to configure webhook.
313-
</td>
314-
</tr>
315340
<tr>
316341
<td>BOT_WEBHOOK_SECRET</td>
317342
<td>

api/index.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import process from 'node:process'
2+
import { handle } from '@hono/node-server/vercel'
3+
import { createBot } from '#root/bot/index.js'
4+
import { createConfig } from '#root/config.js'
5+
import { createServer } from '#root/server/index.js'
6+
import { createLogger } from '#root/logger.js'
7+
8+
// @ts-expect-error create config from environment variables
9+
const config = createConfig(convertKeysToCamelCase(process.env))
10+
const logger = createLogger(config)
11+
12+
const bot = createBot(config.botToken, {
13+
config,
14+
logger,
15+
})
16+
const server = createServer({
17+
bot,
18+
config,
19+
logger,
20+
})
21+
22+
export default handle(server)

src/config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ const configSchema = v.variant('botMode', [
2929
v.object({
3030
botMode: v.literal('webhook'),
3131
...baseConfigSchema.entries,
32-
botWebhook: v.pipe(v.string(), v.url()),
3332
botWebhookSecret: v.pipe(v.string(), v.minLength(12)),
3433
serverHost: v.optional(v.string(), '0.0.0.0'),
3534
serverPort: v.optional(v.pipe(v.string(), v.transform(Number), v.number()), '80'),

src/server/index.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,24 @@ export function createServer(dependencies: Dependencies) {
5858
server.get('/', c => c.json({ status: true }))
5959

6060
if (config.isWebhookMode) {
61+
server.get(`/${bot.token}`, async (c) => {
62+
const hostname = c.req.header('x-forwarded-host')
63+
if (typeof hostname === 'string') {
64+
const webhookUrl = new URL('webhook', `https://${hostname}`).href
65+
await bot.api.setWebhook(webhookUrl, {
66+
allowed_updates: config.botAllowedUpdates,
67+
secret_token: config.botWebhookSecret,
68+
})
69+
return c.json({
70+
status: true,
71+
})
72+
}
73+
c.status(500)
74+
return c.json({
75+
status: false,
76+
})
77+
})
78+
6179
server.post(
6280
'/webhook',
6381
webhookCallback(bot, 'hono', {

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"preserveWatchOutput": true
1919
},
2020
"include": [
21+
"api/**/*",
2122
"src/**/*"
2223
]
2324
}

vercel.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"installCommand": "npm install",
3+
"buildCommand": "npm run build",
4+
"devCommand": "npm run dev",
5+
"outputDirectory": "build",
6+
"rewrites": [
7+
{
8+
"source": "/(.*)",
9+
"destination": "/api"
10+
}
11+
]
12+
}

0 commit comments

Comments
 (0)