create-bunspace 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +181 -0
- package/dist/bin.js +5755 -0
- package/dist/templates/monorepo/CLAUDE.md +164 -0
- package/dist/templates/monorepo/LICENSE +21 -0
- package/dist/templates/monorepo/MUST-FOLLOW-GUIDELINES.md +269 -0
- package/dist/templates/monorepo/README.md +74 -0
- package/dist/templates/monorepo/SYNC_VERIFICATION.md +1 -0
- package/dist/templates/monorepo/apps/example/package.json +19 -0
- package/dist/templates/monorepo/apps/example/src/index.ts +23 -0
- package/dist/templates/monorepo/apps/example/src/types/index.ts +7 -0
- package/dist/templates/monorepo/apps/example/src/utils/index.ts +7 -0
- package/dist/templates/monorepo/core/packages/main/package.json +41 -0
- package/dist/templates/monorepo/core/packages/main/rolldown.config.ts +24 -0
- package/dist/templates/monorepo/core/packages/main/src/index.ts +80 -0
- package/dist/templates/monorepo/core/packages/main/src/types/constants.ts +15 -0
- package/dist/templates/monorepo/core/packages/main/src/types/index.ts +8 -0
- package/dist/templates/monorepo/core/packages/main/src/types/main.types.ts +25 -0
- package/dist/templates/monorepo/core/packages/main/src/utils/index.ts +5 -0
- package/dist/templates/monorepo/core/packages/utils/package.json +43 -0
- package/dist/templates/monorepo/core/packages/utils/rolldown.config.ts +34 -0
- package/dist/templates/monorepo/core/packages/utils/src/index.ts +2 -0
- package/dist/templates/monorepo/core/packages/utils/src/logger.ts +68 -0
- package/dist/templates/monorepo/core/packages/utils/src/result.ts +146 -0
- package/dist/templates/monorepo/core/packages/utils/src/types/constants.ts +15 -0
- package/dist/templates/monorepo/core/packages/utils/src/types/index.ts +8 -0
- package/dist/templates/monorepo/core/packages/utils/src/types/utils.types.ts +32 -0
- package/dist/templates/monorepo/core/packages/utils/src/utils/index.ts +5 -0
- package/dist/templates/monorepo/oxlint.json +14 -0
- package/dist/templates/monorepo/package.json +39 -0
- package/dist/templates/monorepo/tsconfig.json +35 -0
- package/dist/templates/telegram-bot/.oxlintrc.json +33 -0
- package/dist/templates/telegram-bot/.prettierignore +5 -0
- package/dist/templates/telegram-bot/.prettierrc +26 -0
- package/dist/templates/telegram-bot/CLAUDE.deploy.md +356 -0
- package/dist/templates/telegram-bot/CLAUDE.dev.md +266 -0
- package/dist/templates/telegram-bot/CLAUDE.md +280 -0
- package/dist/templates/telegram-bot/Dockerfile +46 -0
- package/dist/templates/telegram-bot/README.md +245 -0
- package/dist/templates/telegram-bot/apps/.gitkeep +0 -0
- package/dist/templates/telegram-bot/bun.lock +208 -0
- package/dist/templates/telegram-bot/core/.env.example +71 -0
- package/dist/templates/telegram-bot/core/README.md +1067 -0
- package/dist/templates/telegram-bot/core/package.json +15 -0
- package/dist/templates/telegram-bot/core/src/config/env.ts +131 -0
- package/dist/templates/telegram-bot/core/src/config/index.ts +97 -0
- package/dist/templates/telegram-bot/core/src/config/logging.ts +110 -0
- package/dist/templates/telegram-bot/core/src/handlers/control.ts +85 -0
- package/dist/templates/telegram-bot/core/src/handlers/health.ts +83 -0
- package/dist/templates/telegram-bot/core/src/handlers/logs.ts +126 -0
- package/dist/templates/telegram-bot/core/src/index.ts +161 -0
- package/dist/templates/telegram-bot/core/src/middleware/auth.ts +41 -0
- package/dist/templates/telegram-bot/core/src/middleware/error-handler.ts +41 -0
- package/dist/templates/telegram-bot/core/src/middleware/logging.ts +1 -0
- package/dist/templates/telegram-bot/core/src/middleware/topics.ts +55 -0
- package/dist/templates/telegram-bot/core/src/types/bot.ts +92 -0
- package/dist/templates/telegram-bot/core/src/types/constants.ts +50 -0
- package/dist/templates/telegram-bot/core/src/types/result.ts +1 -0
- package/dist/templates/telegram-bot/core/src/utils/bot-manager.test.ts +111 -0
- package/dist/templates/telegram-bot/core/src/utils/bot-manager.ts +201 -0
- package/dist/templates/telegram-bot/core/src/utils/commands.ts +63 -0
- package/dist/templates/telegram-bot/core/src/utils/formatters.ts +82 -0
- package/dist/templates/telegram-bot/core/src/utils/instance-manager.ts +189 -0
- package/dist/templates/telegram-bot/core/src/utils/memory.ts +33 -0
- package/dist/templates/telegram-bot/core/src/utils/result.ts +26 -0
- package/dist/templates/telegram-bot/core/src/utils/telegram.ts +31 -0
- package/dist/templates/telegram-bot/core/src/utils/type-guards.ts +71 -0
- package/dist/templates/telegram-bot/core/tsconfig.json +9 -0
- package/dist/templates/telegram-bot/docker-compose.yml +37 -0
- package/dist/templates/telegram-bot/docs/cli-commands.md +377 -0
- package/dist/templates/telegram-bot/docs/development.md +363 -0
- package/dist/templates/telegram-bot/docs/environment.md +460 -0
- package/dist/templates/telegram-bot/docs/examples/middleware-auth.md +335 -0
- package/dist/templates/telegram-bot/docs/examples/simple-command.md +207 -0
- package/dist/templates/telegram-bot/docs/examples/webhook-setup.md +362 -0
- package/dist/templates/telegram-bot/docs/getting-started.md +223 -0
- package/dist/templates/telegram-bot/docs/troubleshooting.md +489 -0
- package/dist/templates/telegram-bot/package.json +49 -0
- package/dist/templates/telegram-bot/packages/utils/package.json +12 -0
- package/dist/templates/telegram-bot/packages/utils/src/index.ts +2 -0
- package/dist/templates/telegram-bot/packages/utils/src/logger.ts +72 -0
- package/dist/templates/telegram-bot/packages/utils/src/result.ts +80 -0
- package/dist/templates/telegram-bot/tools/README.md +47 -0
- package/dist/templates/telegram-bot/tools/commands/doctor.ts +460 -0
- package/dist/templates/telegram-bot/tools/commands/index.ts +35 -0
- package/dist/templates/telegram-bot/tools/commands/ngrok.ts +207 -0
- package/dist/templates/telegram-bot/tools/commands/setup.ts +368 -0
- package/dist/templates/telegram-bot/tools/commands/status.ts +140 -0
- package/dist/templates/telegram-bot/tools/index.ts +16 -0
- package/dist/templates/telegram-bot/tools/package.json +12 -0
- package/dist/templates/telegram-bot/tools/utils/index.ts +13 -0
- package/dist/templates/telegram-bot/tsconfig.json +22 -0
- package/dist/templates/telegram-bot/vitest.config.ts +29 -0
- package/package.json +35 -0
- package/templates/monorepo/CLAUDE.md +164 -0
- package/templates/monorepo/LICENSE +21 -0
- package/templates/monorepo/MUST-FOLLOW-GUIDELINES.md +269 -0
- package/templates/monorepo/README.md +74 -0
- package/templates/monorepo/apps/example/package.json +19 -0
- package/templates/monorepo/apps/example/src/index.ts +23 -0
- package/templates/monorepo/apps/example/src/types/index.ts +7 -0
- package/templates/monorepo/apps/example/src/utils/index.ts +7 -0
- package/templates/monorepo/core/packages/main/package.json +41 -0
- package/templates/monorepo/core/packages/main/rolldown.config.ts +24 -0
- package/templates/monorepo/core/packages/main/src/index.ts +80 -0
- package/templates/monorepo/core/packages/main/src/types/constants.ts +15 -0
- package/templates/monorepo/core/packages/main/src/types/index.ts +8 -0
- package/templates/monorepo/core/packages/main/src/types/main.types.ts +25 -0
- package/templates/monorepo/core/packages/main/src/utils/index.ts +5 -0
- package/templates/monorepo/core/packages/utils/package.json +43 -0
- package/templates/monorepo/core/packages/utils/rolldown.config.ts +34 -0
- package/templates/monorepo/core/packages/utils/src/index.ts +2 -0
- package/templates/monorepo/core/packages/utils/src/logger.ts +68 -0
- package/templates/monorepo/core/packages/utils/src/result.ts +146 -0
- package/templates/monorepo/core/packages/utils/src/types/constants.ts +15 -0
- package/templates/monorepo/core/packages/utils/src/types/index.ts +8 -0
- package/templates/monorepo/core/packages/utils/src/types/utils.types.ts +32 -0
- package/templates/monorepo/core/packages/utils/src/utils/index.ts +5 -0
- package/templates/monorepo/oxlint.json +14 -0
- package/templates/monorepo/package.json +39 -0
- package/templates/monorepo/tsconfig.json +35 -0
- package/templates/telegram-bot/.oxlintrc.json +33 -0
- package/templates/telegram-bot/.prettierignore +5 -0
- package/templates/telegram-bot/.prettierrc +26 -0
- package/templates/telegram-bot/CLAUDE.deploy.md +356 -0
- package/templates/telegram-bot/CLAUDE.dev.md +266 -0
- package/templates/telegram-bot/CLAUDE.md +280 -0
- package/templates/telegram-bot/Dockerfile +46 -0
- package/templates/telegram-bot/README.md +245 -0
- package/templates/telegram-bot/apps/.gitkeep +0 -0
- package/templates/telegram-bot/bun.lock +208 -0
- package/templates/telegram-bot/core/.env.example +71 -0
- package/templates/telegram-bot/core/README.md +1067 -0
- package/templates/telegram-bot/core/package.json +15 -0
- package/templates/telegram-bot/core/src/config/env.ts +131 -0
- package/templates/telegram-bot/core/src/config/index.ts +97 -0
- package/templates/telegram-bot/core/src/config/logging.ts +110 -0
- package/templates/telegram-bot/core/src/handlers/control.ts +85 -0
- package/templates/telegram-bot/core/src/handlers/health.ts +83 -0
- package/templates/telegram-bot/core/src/handlers/logs.ts +126 -0
- package/templates/telegram-bot/core/src/index.ts +161 -0
- package/templates/telegram-bot/core/src/middleware/auth.ts +41 -0
- package/templates/telegram-bot/core/src/middleware/error-handler.ts +41 -0
- package/templates/telegram-bot/core/src/middleware/logging.ts +1 -0
- package/templates/telegram-bot/core/src/middleware/topics.ts +55 -0
- package/templates/telegram-bot/core/src/types/bot.ts +92 -0
- package/templates/telegram-bot/core/src/types/constants.ts +50 -0
- package/templates/telegram-bot/core/src/types/result.ts +1 -0
- package/templates/telegram-bot/core/src/utils/bot-manager.test.ts +111 -0
- package/templates/telegram-bot/core/src/utils/bot-manager.ts +201 -0
- package/templates/telegram-bot/core/src/utils/commands.ts +63 -0
- package/templates/telegram-bot/core/src/utils/formatters.ts +82 -0
- package/templates/telegram-bot/core/src/utils/instance-manager.ts +189 -0
- package/templates/telegram-bot/core/src/utils/memory.ts +33 -0
- package/templates/telegram-bot/core/src/utils/result.ts +26 -0
- package/templates/telegram-bot/core/src/utils/telegram.ts +31 -0
- package/templates/telegram-bot/core/src/utils/type-guards.ts +71 -0
- package/templates/telegram-bot/core/tsconfig.json +9 -0
- package/templates/telegram-bot/docker-compose.yml +37 -0
- package/templates/telegram-bot/docs/cli-commands.md +377 -0
- package/templates/telegram-bot/docs/development.md +363 -0
- package/templates/telegram-bot/docs/environment.md +460 -0
- package/templates/telegram-bot/docs/examples/middleware-auth.md +335 -0
- package/templates/telegram-bot/docs/examples/simple-command.md +207 -0
- package/templates/telegram-bot/docs/examples/webhook-setup.md +362 -0
- package/templates/telegram-bot/docs/getting-started.md +223 -0
- package/templates/telegram-bot/docs/troubleshooting.md +489 -0
- package/templates/telegram-bot/package.json +49 -0
- package/templates/telegram-bot/packages/utils/package.json +12 -0
- package/templates/telegram-bot/packages/utils/src/index.ts +2 -0
- package/templates/telegram-bot/packages/utils/src/logger.ts +72 -0
- package/templates/telegram-bot/packages/utils/src/result.ts +80 -0
- package/templates/telegram-bot/tools/README.md +47 -0
- package/templates/telegram-bot/tools/commands/doctor.ts +460 -0
- package/templates/telegram-bot/tools/commands/index.ts +35 -0
- package/templates/telegram-bot/tools/commands/ngrok.ts +207 -0
- package/templates/telegram-bot/tools/commands/setup.ts +368 -0
- package/templates/telegram-bot/tools/commands/status.ts +140 -0
- package/templates/telegram-bot/tools/index.ts +16 -0
- package/templates/telegram-bot/tools/package.json +12 -0
- package/templates/telegram-bot/tools/utils/index.ts +13 -0
- package/templates/telegram-bot/tsconfig.json +22 -0
- package/templates/telegram-bot/vitest.config.ts +29 -0
|
@@ -0,0 +1,1067 @@
|
|
|
1
|
+
# Telegram Bot Template
|
|
2
|
+
|
|
3
|
+
[English](#english) | [Español](#español)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## English
|
|
8
|
+
|
|
9
|
+
Production-ready Telegram bot template built with Telegraf, TypeScript, and
|
|
10
|
+
Better Logger. Designed for Bun workspace monorepos.
|
|
11
|
+
|
|
12
|
+
**Note:** This is a reusable template that can be extracted to a separate
|
|
13
|
+
repository.
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- **Dual Mode**: Supports both polling and webhook update modes
|
|
18
|
+
- **Topic Support**: Optional Telegram topics for logs and control commands
|
|
19
|
+
- **Health Monitoring**: Built-in `/health`, `/uptime`, and `/stats` commands
|
|
20
|
+
- **Control Commands**: `/stop`, `/restart`, `/mode` switching
|
|
21
|
+
- **Log Streaming**: Real-time log forwarding to Telegram topics
|
|
22
|
+
- **Type Safety**: Full TypeScript strict mode with Zod validation
|
|
23
|
+
- **Better Logger**: Integrated with cyberpunk preset for beautiful logs
|
|
24
|
+
- **Authorization**: User-based auth middleware for restricted commands
|
|
25
|
+
- **Error Handling**: Global error catching with user-friendly messages
|
|
26
|
+
|
|
27
|
+
## Prerequisites
|
|
28
|
+
|
|
29
|
+
- Bun 1.3+
|
|
30
|
+
- Telegram bot token (get from [@BotFather](https://t.me/botfather))
|
|
31
|
+
- (Optional) Public HTTPS URL for webhook mode
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Clone repository
|
|
37
|
+
git clone https://github.com/mks2508/bun-soulseek.git
|
|
38
|
+
cd apps/telegram-bot
|
|
39
|
+
|
|
40
|
+
# Install dependencies
|
|
41
|
+
bun install
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Configuration
|
|
45
|
+
|
|
46
|
+
Create a `.env` file in `apps/telegram-bot/`:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Required: Bot token from @BotFather
|
|
50
|
+
TG_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
|
|
51
|
+
|
|
52
|
+
# Required: Bot operation mode (polling or webhook)
|
|
53
|
+
TG_MODE=polling
|
|
54
|
+
|
|
55
|
+
# Required if TG_MODE=webhook
|
|
56
|
+
TG_WEBHOOK_URL=https://your-domain.com/webhook
|
|
57
|
+
TG_WEBHOOK_SECRET=random_secret_token
|
|
58
|
+
|
|
59
|
+
# Optional: Log topic configuration (for logs streaming)
|
|
60
|
+
TG_LOG_CHAT_ID=-1001234567890
|
|
61
|
+
TG_LOG_TOPIC_ID=123
|
|
62
|
+
|
|
63
|
+
# Optional: Control topic configuration (for health/commands)
|
|
64
|
+
TG_CONTROL_CHAT_ID=-1001234567890
|
|
65
|
+
TG_CONTROL_TOPIC_ID=124
|
|
66
|
+
|
|
67
|
+
# Optional: Authorized user IDs (comma-separated)
|
|
68
|
+
TG_AUTHORIZED_USER_IDS=123456789,987654321
|
|
69
|
+
|
|
70
|
+
# Optional: Log level (debug, info, warn, error)
|
|
71
|
+
LOG_LEVEL=info
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Environment Variables
|
|
75
|
+
|
|
76
|
+
| Variable | Required | Description |
|
|
77
|
+
| ------------------------ | ---------- | ----------------------------------------------------- |
|
|
78
|
+
| `TG_BOT_TOKEN` | Yes | Bot token from @BotFather |
|
|
79
|
+
| `TG_MODE` | Yes | `polling` or `webhook` |
|
|
80
|
+
| `TG_WEBHOOK_URL` | If webhook | Public HTTPS URL for webhook |
|
|
81
|
+
| `TG_WEBHOOK_SECRET` | No | Secret token for webhook validation |
|
|
82
|
+
| `TG_LOG_CHAT_ID` | No | Chat ID for log streaming |
|
|
83
|
+
| `TG_LOG_TOPIC_ID` | No | Topic ID for log streaming |
|
|
84
|
+
| `TG_CONTROL_CHAT_ID` | No | Chat ID for control commands |
|
|
85
|
+
| `TG_CONTROL_TOPIC_ID` | No | Topic ID for control commands |
|
|
86
|
+
| `TG_AUTHORIZED_USER_IDS` | No | Comma-separated authorized user IDs |
|
|
87
|
+
| `LOG_LEVEL` | No | `debug`, `info`, `warn`, or `error` (default: `info`) |
|
|
88
|
+
|
|
89
|
+
## Usage
|
|
90
|
+
|
|
91
|
+
### Development
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Start bot in development mode (hot reload)
|
|
95
|
+
bun run dev:bot
|
|
96
|
+
|
|
97
|
+
# Type-check only
|
|
98
|
+
bun run typecheck:bot
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Production
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Start bot
|
|
105
|
+
bun run --filter telegram-bot start
|
|
106
|
+
|
|
107
|
+
# Build (if needed)
|
|
108
|
+
bun run --filter telegram-bot build
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Commands
|
|
112
|
+
|
|
113
|
+
### General Commands (Available to all users)
|
|
114
|
+
|
|
115
|
+
| Command | Description |
|
|
116
|
+
| --------- | ---------------------------------- |
|
|
117
|
+
| `/start` | Welcome message with command list |
|
|
118
|
+
| `/health` | Check bot health status |
|
|
119
|
+
| `/uptime` | Show how long bot has been running |
|
|
120
|
+
| `/stats` | Show bot statistics |
|
|
121
|
+
| `/logs` | Check log streaming status |
|
|
122
|
+
|
|
123
|
+
### Control Commands (Authorized users only)
|
|
124
|
+
|
|
125
|
+
Control commands require `TG_CONTROL_CHAT_ID` and `TG_AUTHORIZED_USER_IDS` to be
|
|
126
|
+
configured.
|
|
127
|
+
|
|
128
|
+
| Command | Description |
|
|
129
|
+
| --------------- | ---------------------------------- | ---------------------- |
|
|
130
|
+
| `/stop` | Gracefully shutdown bot |
|
|
131
|
+
| `/restart` | Restart bot with stats reset |
|
|
132
|
+
| `/mode <polling | webhook>` | Change bot update mode |
|
|
133
|
+
| `/webhook` | Show current webhook configuration |
|
|
134
|
+
|
|
135
|
+
## Authorization
|
|
136
|
+
|
|
137
|
+
Control commands are restricted to authorized users:
|
|
138
|
+
|
|
139
|
+
1. Set `TG_CONTROL_CHAT_ID` to your group/channel ID
|
|
140
|
+
2. Set `TG_AUTHORIZED_USER_IDS` with your Telegram user ID (get from
|
|
141
|
+
[@userinfobot](https://t.me/userinfobot))
|
|
142
|
+
3. Only authorized users can run `/stop`, `/restart`, `/mode`, `/webhook`
|
|
143
|
+
|
|
144
|
+
**Important**: Set `TG_CONTROL_CHAT_ID` even for private chats to enable control
|
|
145
|
+
commands.
|
|
146
|
+
|
|
147
|
+
## Architecture
|
|
148
|
+
|
|
149
|
+
### Component Overview
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
153
|
+
│ Telegram API (Telegraf) │
|
|
154
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
155
|
+
│
|
|
156
|
+
│
|
|
157
|
+
┌───────────────┴───────────────┐
|
|
158
|
+
│ │
|
|
159
|
+
┌────▼────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
160
|
+
│ Middleware │ │ Handlers │ │ BotManager │
|
|
161
|
+
│ │ │ │ │ │
|
|
162
|
+
│ • auth │ │ • health │ │ • getStatus() │
|
|
163
|
+
│ • error │ │ • control │ │ • getStats() │
|
|
164
|
+
│ • logging │ │ • logs │ │ • start() │
|
|
165
|
+
│ │ │ │ │ • stop() │
|
|
166
|
+
│ │ │ │ │ • restart() │
|
|
167
|
+
│ │ │ │ │ │
|
|
168
|
+
└────────────┘ └─────────────────┘ └──────────────────┘
|
|
169
|
+
│
|
|
170
|
+
│
|
|
171
|
+
▼
|
|
172
|
+
┌─────────────────────┐
|
|
173
|
+
│ Config Manager │
|
|
174
|
+
│ • getConfig() │
|
|
175
|
+
│ • updateConfig() │
|
|
176
|
+
│ • loadEnvConfig() │
|
|
177
|
+
└─────────────────────┘
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Component Details
|
|
181
|
+
|
|
182
|
+
**BotManager**
|
|
183
|
+
|
|
184
|
+
- Manages bot lifecycle (start, stop, restart)
|
|
185
|
+
- Tracks statistics (messages, commands, errors)
|
|
186
|
+
- Provides status information
|
|
187
|
+
- Methods: `start()`, `stop()`, `restart()`, `getStatus()`, `getStats()`,
|
|
188
|
+
`resetStats()`
|
|
189
|
+
|
|
190
|
+
**Config System**
|
|
191
|
+
|
|
192
|
+
- Environment variable validation with Zod
|
|
193
|
+
- Caching of configuration
|
|
194
|
+
- Functions: `getConfig()`, `updateConfig()`, `loadEnvConfig()`
|
|
195
|
+
|
|
196
|
+
**Handlers**
|
|
197
|
+
|
|
198
|
+
- `/health`, `/uptime`, `/stats` - Health and stats commands
|
|
199
|
+
- `/stop`, `/restart`, `/mode`, `/webhook` - Control commands (require auth)
|
|
200
|
+
- `/logs` - Log streaming handler
|
|
201
|
+
|
|
202
|
+
**Middleware**
|
|
203
|
+
|
|
204
|
+
- `errorHandler()` - Global error catching
|
|
205
|
+
- `auth()` - User authorization validation
|
|
206
|
+
- `topicValidation()` - Topic ID validation
|
|
207
|
+
- `logging()` - Better Logger integration
|
|
208
|
+
|
|
209
|
+
### Data Flow
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
Telegram Update → Error Handler → Topic Validation → Auth Middleware → Handler → BotManager → Response
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Webhook Mode
|
|
216
|
+
|
|
217
|
+
For webhook mode, you need:
|
|
218
|
+
|
|
219
|
+
1. **Public HTTPS URL** (e.g., using ngrok, Cloudflare Tunnel, or VPS)
|
|
220
|
+
2. **Port 80/443** accessible from internet
|
|
221
|
+
3. **Firewall rules** allowing incoming traffic
|
|
222
|
+
|
|
223
|
+
Example setup with ngrok:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
# Run ngrok
|
|
227
|
+
ngrok http 3000
|
|
228
|
+
|
|
229
|
+
# Set env
|
|
230
|
+
TG_WEBHOOK_URL=https://your-ngrok-url.ngrok-free.app/webhook
|
|
231
|
+
TG_MODE=webhook
|
|
232
|
+
|
|
233
|
+
# Start bot
|
|
234
|
+
bun run dev:bot
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Log Streaming
|
|
238
|
+
|
|
239
|
+
Logs are streamed to Telegram when `TG_LOG_CHAT_ID` is configured:
|
|
240
|
+
|
|
241
|
+
- **Buffering**: Logs are buffered (max 10 messages, 5 second timeout)
|
|
242
|
+
- **Rate Limiting**: Automatic rate limiting to prevent spam
|
|
243
|
+
- **Levels**: Only logs matching `LOG_LEVEL` are streamed
|
|
244
|
+
|
|
245
|
+
Disable log streaming by removing `TG_LOG_CHAT_ID` from `.env`.
|
|
246
|
+
|
|
247
|
+
## Troubleshooting
|
|
248
|
+
|
|
249
|
+
### Bot doesn't respond to commands
|
|
250
|
+
|
|
251
|
+
**Problem**: Bot receives commands but doesn't respond
|
|
252
|
+
|
|
253
|
+
**Solutions:**
|
|
254
|
+
|
|
255
|
+
- Verify `TG_BOT_TOKEN` is correct
|
|
256
|
+
- Check bot is running with `/health` command
|
|
257
|
+
- Ensure you're messaging the correct bot account
|
|
258
|
+
- Verify `TG_AUTHORIZED_USER_IDS` for control commands
|
|
259
|
+
|
|
260
|
+
### Webhook not receiving updates
|
|
261
|
+
|
|
262
|
+
**Problem**: Webhook configured but Telegram doesn't send updates
|
|
263
|
+
|
|
264
|
+
**Solutions:**
|
|
265
|
+
|
|
266
|
+
- Verify `TG_WEBHOOK_URL` is publicly accessible
|
|
267
|
+
```bash
|
|
268
|
+
curl https://your-webhook-url.com/webhook
|
|
269
|
+
```
|
|
270
|
+
- Check firewall allows incoming connections
|
|
271
|
+
- Verify URL uses HTTPS (required by Telegram)
|
|
272
|
+
- Check bot logs for webhook setup errors
|
|
273
|
+
- Use a Telegram bot API tester to verify webhook URL
|
|
274
|
+
|
|
275
|
+
### Log streaming not working
|
|
276
|
+
|
|
277
|
+
**Problem**: Logs aren't being sent to Telegram
|
|
278
|
+
|
|
279
|
+
**Solutions:**
|
|
280
|
+
|
|
281
|
+
- Verify `TG_LOG_CHAT_ID` is set correctly
|
|
282
|
+
- Check bot has permission to send messages in the chat
|
|
283
|
+
- Verify `TG_LOG_TOPIC_ID` matches topic ID (get from Telegram)
|
|
284
|
+
- Check `LOG_LEVEL` is appropriate for logs you expect
|
|
285
|
+
|
|
286
|
+
### Typecheck errors
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
# Install dependencies
|
|
290
|
+
bun install
|
|
291
|
+
|
|
292
|
+
# Run typecheck
|
|
293
|
+
bun run typecheck:bot
|
|
294
|
+
|
|
295
|
+
# Format code
|
|
296
|
+
bun run format
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Permission denied errors
|
|
300
|
+
|
|
301
|
+
**Problem**: Bot returns "not enough rights" or similar errors
|
|
302
|
+
|
|
303
|
+
**Solutions:**
|
|
304
|
+
|
|
305
|
+
- Verify bot is admin of the group/channel
|
|
306
|
+
- Check bot has permission to send messages
|
|
307
|
+
- Verify topic IDs are correct (topics require bot admin rights)
|
|
308
|
+
- Remove and re-add bot to the chat to refresh permissions
|
|
309
|
+
|
|
310
|
+
## Development
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# Install dependencies
|
|
314
|
+
bun install
|
|
315
|
+
|
|
316
|
+
# Run in watch mode
|
|
317
|
+
bun run dev:bot
|
|
318
|
+
|
|
319
|
+
# Type-check only
|
|
320
|
+
bun run typecheck:bot
|
|
321
|
+
|
|
322
|
+
# Run linter
|
|
323
|
+
bun run lint
|
|
324
|
+
|
|
325
|
+
# Format code
|
|
326
|
+
bun run format
|
|
327
|
+
|
|
328
|
+
# Check formatting
|
|
329
|
+
bun run format:check
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Project Structure
|
|
333
|
+
|
|
334
|
+
```
|
|
335
|
+
apps/telegram-bot/
|
|
336
|
+
├── src/
|
|
337
|
+
│ ├── index.ts # Bot entry point
|
|
338
|
+
│ ├── config/
|
|
339
|
+
│ │ ├── env.ts # Environment validation
|
|
340
|
+
│ │ └── index.ts # Config management
|
|
341
|
+
│ ├── middleware/
|
|
342
|
+
│ │ ├── auth.ts # Authorization middleware
|
|
343
|
+
│ │ ├── error-handler.ts # Global error handling
|
|
344
|
+
│ │ ├── logging.ts # Better Logger integration
|
|
345
|
+
│ │ └── topics.ts # Topic validation
|
|
346
|
+
│ ├── handlers/
|
|
347
|
+
│ │ ├── health.ts # Health & stats commands
|
|
348
|
+
│ │ ├── control.ts # Control commands
|
|
349
|
+
│ │ └── logs.ts # Log streaming
|
|
350
|
+
│ ├── utils/
|
|
351
|
+
│ │ ├── bot-manager.ts # Bot lifecycle management
|
|
352
|
+
│ │ └── formatters.ts # Message formatters
|
|
353
|
+
│ └── types/
|
|
354
|
+
│ ├── bot.ts # TypeScript interfaces
|
|
355
|
+
│ ├── result.ts # Result monad
|
|
356
|
+
│ └── constants.ts # Constants
|
|
357
|
+
├── package.json
|
|
358
|
+
├── tsconfig.json
|
|
359
|
+
├── .env.example
|
|
360
|
+
└── README.md
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Customization
|
|
364
|
+
|
|
365
|
+
### Adding New Commands
|
|
366
|
+
|
|
367
|
+
1. Create handler function in `src/handlers/`:
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
// src/handlers/custom.ts
|
|
371
|
+
import type { Context } from 'telegraf'
|
|
372
|
+
|
|
373
|
+
export async function handleCustom(ctx: Context): Promise<void> {
|
|
374
|
+
await ctx.reply('Custom command response')
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
2. Register in `src/index.ts`:
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
import { handleCustom } from './handlers/custom.js'
|
|
382
|
+
|
|
383
|
+
bot.command('custom', handleCustom)
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Adding Custom Middleware
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
// src/middleware/custom.ts
|
|
390
|
+
import type { Context, Middleware } from 'telegraf'
|
|
391
|
+
|
|
392
|
+
export function customMiddleware(): Middleware<Context> {
|
|
393
|
+
return async (ctx, next) => {
|
|
394
|
+
// Your logic here
|
|
395
|
+
return next()
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Register in src/index.ts
|
|
400
|
+
import { customMiddleware } from './middleware/custom.js'
|
|
401
|
+
bot.use(customMiddleware())
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Customizing Log Levels
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
// src/middleware/logging.ts
|
|
408
|
+
import { getConfig } from '../config/index.js'
|
|
409
|
+
import logger from '@mks2508/better-logger'
|
|
410
|
+
|
|
411
|
+
const config = getConfig()
|
|
412
|
+
|
|
413
|
+
if (config.logLevel === 'debug') {
|
|
414
|
+
logger.preset('debug')
|
|
415
|
+
logger.showLocation()
|
|
416
|
+
} else {
|
|
417
|
+
logger.preset('cyberpunk')
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
logger.showTimestamp()
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## Public API: BotManager
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
import { botManager } from './utils/bot-manager.js'
|
|
427
|
+
|
|
428
|
+
// Start bot
|
|
429
|
+
await botManager.start(bot, 'polling')
|
|
430
|
+
|
|
431
|
+
// Get current status
|
|
432
|
+
const statusResult = botManager.getStatus()
|
|
433
|
+
if (statusResult.ok) {
|
|
434
|
+
console.log(`Bot status: ${statusResult.value.status}`)
|
|
435
|
+
console.log(`Mode: ${statusResult.value.mode}`)
|
|
436
|
+
console.log(`Uptime: ${statusResult.value.uptime}ms`)
|
|
437
|
+
console.log(`Memory:`, statusResult.value.memoryUsage)
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Get statistics
|
|
441
|
+
const statsResult = botManager.getStats()
|
|
442
|
+
if (statsResult.ok) {
|
|
443
|
+
console.log(`Messages: ${statsResult.value.messagesProcessed}`)
|
|
444
|
+
console.log(`Commands: ${statsResult.value.commandsExecuted}`)
|
|
445
|
+
console.log(`Errors: ${statsResult.value.errorsEncountered}`)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Restart bot
|
|
449
|
+
await botManager.restart()
|
|
450
|
+
|
|
451
|
+
// Stop bot
|
|
452
|
+
await botManager.stop('reason')
|
|
453
|
+
|
|
454
|
+
// Reset statistics
|
|
455
|
+
await botManager.resetStats()
|
|
456
|
+
|
|
457
|
+
// Check authorization
|
|
458
|
+
const isAuth = botManager.authorize(userId)
|
|
459
|
+
if (isAuth.ok) {
|
|
460
|
+
console.log('User is authorized')
|
|
461
|
+
} else {
|
|
462
|
+
console.log('User is not authorized')
|
|
463
|
+
}
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
## Monitoring
|
|
467
|
+
|
|
468
|
+
### Health Check
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
# In Telegram (any chat)
|
|
472
|
+
/health
|
|
473
|
+
|
|
474
|
+
# Shows:
|
|
475
|
+
# - Bot status (running/stopped)
|
|
476
|
+
# - Current mode (polling/webhook)
|
|
477
|
+
# - Uptime
|
|
478
|
+
# - Memory usage
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### Statistics
|
|
482
|
+
|
|
483
|
+
```bash
|
|
484
|
+
/uptime
|
|
485
|
+
|
|
486
|
+
/stats
|
|
487
|
+
|
|
488
|
+
# Shows:
|
|
489
|
+
# - Messages processed
|
|
490
|
+
# - Commands executed
|
|
491
|
+
# - Errors encountered
|
|
492
|
+
# - Configuration overview
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
## Resources
|
|
496
|
+
|
|
497
|
+
- [Telegraf Documentation](https://telegraf.js.org/)
|
|
498
|
+
- [Telegram Bot API](https://core.telegram.org/bots/api)
|
|
499
|
+
- [Better Logger](https://github.com/mks2508/better-logger)
|
|
500
|
+
- [Bun Documentation](https://bun.sh/docs)
|
|
501
|
+
|
|
502
|
+
## License
|
|
503
|
+
|
|
504
|
+
MIT
|
|
505
|
+
|
|
506
|
+
## Author
|
|
507
|
+
|
|
508
|
+
MKS2508
|
|
509
|
+
|
|
510
|
+
## Contributing
|
|
511
|
+
|
|
512
|
+
This is a template. Feel free to fork and customize for your use case.
|
|
513
|
+
|
|
514
|
+
### Best Practices
|
|
515
|
+
|
|
516
|
+
- Use TypeScript strict mode
|
|
517
|
+
- Add JSDoc to public functions
|
|
518
|
+
- Follow existing code patterns
|
|
519
|
+
- Test before committing
|
|
520
|
+
- Keep commits atomic and descriptive
|
|
521
|
+
|
|
522
|
+
## Updates
|
|
523
|
+
|
|
524
|
+
To update dependencies:
|
|
525
|
+
|
|
526
|
+
```bash
|
|
527
|
+
bun install
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
To add new dependencies:
|
|
531
|
+
|
|
532
|
+
```bash
|
|
533
|
+
cd apps/telegram-bot
|
|
534
|
+
bun add package-name
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
## Reporting Issues
|
|
538
|
+
|
|
539
|
+
For issues specific to this template, open an issue in the repository.
|
|
540
|
+
|
|
541
|
+
For Telegraf issues: https://github.com/telegraf/telegraf/issues For Better
|
|
542
|
+
Logger issues: https://github.com/mks2508/better-logger/issues
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
## Español
|
|
547
|
+
|
|
548
|
+
Plantilla de bot de Telegram lista para producción construida con Telegraf,
|
|
549
|
+
TypeScript y Better Logger. Diseñada para monorepos de Bun workspace.
|
|
550
|
+
|
|
551
|
+
**Nota:** Esta es una plantilla reutilizable que puede ser extraída a un
|
|
552
|
+
repositorio separado.
|
|
553
|
+
|
|
554
|
+
## Características
|
|
555
|
+
|
|
556
|
+
- **Modo Dual**: Soporte para ambos modos de actualización (polling y webhook)
|
|
557
|
+
- **Soporte de Topics**: Topics opcionales de Telegram para logs y comandos de
|
|
558
|
+
control
|
|
559
|
+
- **Monitoreo de Salud**: Comandos incorporados `/health`, `/uptime`, `/stats`
|
|
560
|
+
- **Comandos de Control**: `/stop`, `/restart`, `/mode` para cambio de modo
|
|
561
|
+
- **Streaming de Logs**: Reenvío en tiempo real de logs a topics de Telegram
|
|
562
|
+
- **Type Safety**: Modo estricto de TypeScript completo con validación Zod
|
|
563
|
+
- **Better Logger**: Integrado con preset cyberpunk para logs hermosos
|
|
564
|
+
- **Autorización**: Middleware de autorización basada en usuarios para comandos
|
|
565
|
+
restringidos
|
|
566
|
+
- **Manejo de Errores**: Captura global de errores con mensajes amigables al
|
|
567
|
+
usuario
|
|
568
|
+
|
|
569
|
+
## Requisitos
|
|
570
|
+
|
|
571
|
+
- Bun 1.3+
|
|
572
|
+
- Token de bot de Telegram (obtener de [@BotFather](https://t.me/botfather))
|
|
573
|
+
- (Opcional) URL HTTPS pública para modo webhook
|
|
574
|
+
|
|
575
|
+
## Instalación
|
|
576
|
+
|
|
577
|
+
```bash
|
|
578
|
+
# Clonar repositorio
|
|
579
|
+
git clone https://github.com/mks2508/bun-soulseek.git
|
|
580
|
+
cd apps/telegram-bot
|
|
581
|
+
|
|
582
|
+
# Instalar dependencias
|
|
583
|
+
bun install
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
## Configuración
|
|
587
|
+
|
|
588
|
+
Crear un archivo `.env` en `apps/telegram-bot/`:
|
|
589
|
+
|
|
590
|
+
```bash
|
|
591
|
+
# Requerido: Token de bot de @BotFather
|
|
592
|
+
TG_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
|
|
593
|
+
|
|
594
|
+
# Requerido: Modo de operación del bot (polling o webhook)
|
|
595
|
+
TG_MODE=polling
|
|
596
|
+
|
|
597
|
+
# Requerido si TG_MODE=webhook
|
|
598
|
+
TG_WEBHOOK_URL=https://tu-dominio.com/webhook
|
|
599
|
+
TG_WEBHOOK_SECRET=token_secreto_aleatorio
|
|
600
|
+
|
|
601
|
+
# Opcional: Configuración de topic de logs (para streaming)
|
|
602
|
+
TG_LOG_CHAT_ID=-1001234567890
|
|
603
|
+
TG_LOG_TOPIC_ID=123
|
|
604
|
+
|
|
605
|
+
# Opcional: Configuración de topic de control (para salud/comandos)
|
|
606
|
+
TG_CONTROL_CHAT_ID=-1001234567890
|
|
607
|
+
TG_CONTROL_TOPIC_ID=124
|
|
608
|
+
|
|
609
|
+
# Opcional: IDs de usuarios autorizados (separados por comas)
|
|
610
|
+
TG_AUTHORIZED_USER_IDS=123456789,987654321
|
|
611
|
+
|
|
612
|
+
# Opcional: Nivel de log (debug, info, warn, error)
|
|
613
|
+
LOG_LEVEL=info
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### Variables de Entorno
|
|
617
|
+
|
|
618
|
+
| Variable | Requerida | Descripción |
|
|
619
|
+
| ------------------------ | ------------- | ---------------------------------------------------- |
|
|
620
|
+
| `TG_BOT_TOKEN` | Sí | Token de bot de @BotFather |
|
|
621
|
+
| `TG_MODE` | Sí | `polling` o `webhook` |
|
|
622
|
+
| `TG_WEBHOOK_URL` | Si es webhook | URL HTTPS pública para webhook |
|
|
623
|
+
| `TG_WEBHOOK_SECRET` | No | Token secreto para validación de webhook |
|
|
624
|
+
| `TG_LOG_CHAT_ID` | No | Chat ID para streaming de logs |
|
|
625
|
+
| `TG_LOG_TOPIC_ID` | No | Topic ID para streaming de logs |
|
|
626
|
+
| `TG_CONTROL_CHAT_ID` | No | Chat ID para comandos de control |
|
|
627
|
+
| `TG_CONTROL_TOPIC_ID` | No | Topic ID para comandos de control |
|
|
628
|
+
| `TG_AUTHORIZED_USER_IDS` | No | IDs de usuarios autorizados (separados por comas) |
|
|
629
|
+
| `LOG_LEVEL` | No | `debug`, `info`, `warn`, o `error` (default: `info`) |
|
|
630
|
+
|
|
631
|
+
## Uso
|
|
632
|
+
|
|
633
|
+
### Desarrollo
|
|
634
|
+
|
|
635
|
+
```bash
|
|
636
|
+
# Iniciar bot en modo desarrollo (recarga en caliente)
|
|
637
|
+
bun run dev:bot
|
|
638
|
+
|
|
639
|
+
# Solo verificar tipos
|
|
640
|
+
bun run typecheck:bot
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Producción
|
|
644
|
+
|
|
645
|
+
```bash
|
|
646
|
+
# Iniciar bot
|
|
647
|
+
bun run --filter telegram-bot start
|
|
648
|
+
|
|
649
|
+
# Construir (si es necesario)
|
|
650
|
+
bun run --filter telegram-bot build
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
## Comandos
|
|
654
|
+
|
|
655
|
+
### Comandos Generales (Disponibles para todos los usuarios)
|
|
656
|
+
|
|
657
|
+
| Comando | Descripción |
|
|
658
|
+
| --------- | ------------------------------------------- |
|
|
659
|
+
| `/start` | Mensaje de bienvenida con lista de comandos |
|
|
660
|
+
| `/health` | Verificar estado de salud del bot |
|
|
661
|
+
| `/uptime` | Mostrar tiempo de ejecución del bot |
|
|
662
|
+
| `/stats` | Mostrar estadísticas del bot |
|
|
663
|
+
| `/logs` | Verificar estado de streaming de logs |
|
|
664
|
+
|
|
665
|
+
### Comandos de Control (Solo usuarios autorizados)
|
|
666
|
+
|
|
667
|
+
Los comandos de control requieren `TG_CONTROL_CHAT_ID` y
|
|
668
|
+
`TG_AUTHORIZED_USER_IDS` configurados.
|
|
669
|
+
|
|
670
|
+
| Comando | Descripción |
|
|
671
|
+
| --------------- | ---------------------------------------- | ------------------------------------- |
|
|
672
|
+
| `/stop` | Apagar bot graciosamente |
|
|
673
|
+
| `/restart` | Reiniciar bot con reset de estadísticas |
|
|
674
|
+
| `/mode <polling | webhook>` | Cambiar modo de actualización del bot |
|
|
675
|
+
| `/webhook` | Mostrar configuración actual del webhook |
|
|
676
|
+
|
|
677
|
+
## Autorización
|
|
678
|
+
|
|
679
|
+
Los comandos de control están restringidos a usuarios autorizados:
|
|
680
|
+
|
|
681
|
+
1. Configura `TG_CONTROL_CHAT_ID` con tu ID de grupo/canal
|
|
682
|
+
2. Configura `TG_AUTHORIZED_USER_IDS` con tu ID de usuario de Telegram (obtener
|
|
683
|
+
de [@userinfobot](https://t.me/userinfobot))
|
|
684
|
+
3. Solo los usuarios autorizados pueden ejecutar `/stop`, `/restart`, `/mode`,
|
|
685
|
+
`/webhook`
|
|
686
|
+
|
|
687
|
+
**Importante**: Configura `TG_CONTROL_CHAT_ID` incluso para chats privados para
|
|
688
|
+
habilitar comandos de control.
|
|
689
|
+
|
|
690
|
+
## Arquitectura
|
|
691
|
+
|
|
692
|
+
### Visión General de Componentes
|
|
693
|
+
|
|
694
|
+
```
|
|
695
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
696
|
+
│ API de Telegram (Telegraf) │
|
|
697
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
698
|
+
│
|
|
699
|
+
│
|
|
700
|
+
┌───────────────┴───────────────┐
|
|
701
|
+
│ │
|
|
702
|
+
┌────▼────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
703
|
+
│ Middleware │ │ Handlers │ │ BotManager │
|
|
704
|
+
│ │ │ │ │ │
|
|
705
|
+
│ • auth │ │ • health │ │ • getStatus() │
|
|
706
|
+
│ • error │ │ • control │ │ • getStats() │
|
|
707
|
+
│ • logging │ │ • logs │ │ • start() │
|
|
708
|
+
│ │ │ │ │ • stop() │
|
|
709
|
+
│ │ │ │ │ • restart() │
|
|
710
|
+
└────────────┘ └─────────────────┘ └──────────────────┘
|
|
711
|
+
│
|
|
712
|
+
▼
|
|
713
|
+
┌─────────────────────┐
|
|
714
|
+
│ Config Manager │
|
|
715
|
+
│ • getConfig() │
|
|
716
|
+
│ • updateConfig() │
|
|
717
|
+
│ • loadEnvConfig() │
|
|
718
|
+
└─────────────────────┘
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
### Detalles de Componentes
|
|
722
|
+
|
|
723
|
+
**BotManager**
|
|
724
|
+
|
|
725
|
+
- Gestiona el ciclo de vida del bot (start, stop, restart)
|
|
726
|
+
- Rastrea estadísticas (mensajes, comandos, errores)
|
|
727
|
+
- Proporciona información de estado
|
|
728
|
+
- Métodos: `start()`, `stop()`, `restart()`, `getStatus()`, `getStats()`,
|
|
729
|
+
`resetStats()`
|
|
730
|
+
|
|
731
|
+
**Sistema de Configuración**
|
|
732
|
+
|
|
733
|
+
- Validación de variables de entorno con Zod
|
|
734
|
+
- Caching de configuración
|
|
735
|
+
- Funciones: `getConfig()`, `updateConfig()`, `loadEnvConfig()`
|
|
736
|
+
|
|
737
|
+
**Handlers**
|
|
738
|
+
|
|
739
|
+
- `/health`, `/uptime`, `/stats` - Comandos de salud y estadísticas
|
|
740
|
+
- `/stop`, `/restart`, `/mode`, `/webhook` - Comandos de control (requieren
|
|
741
|
+
auth)
|
|
742
|
+
- `/logs` - Handler de streaming de logs
|
|
743
|
+
|
|
744
|
+
**Middleware**
|
|
745
|
+
|
|
746
|
+
- `errorHandler()` - Captura global de errores
|
|
747
|
+
- `auth()` - Validación de autorización de usuarios
|
|
748
|
+
- `topicValidation()` - Validación de IDs de topics
|
|
749
|
+
- `logging()` - Integración con Better Logger
|
|
750
|
+
|
|
751
|
+
### Flujo de Datos
|
|
752
|
+
|
|
753
|
+
```
|
|
754
|
+
Actualización de Telegram → Handler de Errores → Validación de Topics → Middleware de Auth → Handler → BotManager → Respuesta
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
## Modo Webhook
|
|
758
|
+
|
|
759
|
+
Para modo webhook, necesitas:
|
|
760
|
+
|
|
761
|
+
1. **URL HTTPS pública** (ej. usando ngrok, Cloudflare Tunnel, o VPS)
|
|
762
|
+
2. **Puerto 80/443** accesible desde internet
|
|
763
|
+
3. **Reglas de firewall** permitiendo tráfico entrante
|
|
764
|
+
|
|
765
|
+
Ejemplo de configuración con ngrok:
|
|
766
|
+
|
|
767
|
+
```bash
|
|
768
|
+
# Ejecutar ngrok
|
|
769
|
+
ngrok http 3000
|
|
770
|
+
|
|
771
|
+
# Configurar env
|
|
772
|
+
TG_WEBHOOK_URL=https://tu-url-ngrok.ngrok-free.app/webhook
|
|
773
|
+
TG_MODE=webhook
|
|
774
|
+
|
|
775
|
+
# Iniciar bot
|
|
776
|
+
bun run dev:bot
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
## Streaming de Logs
|
|
780
|
+
|
|
781
|
+
Los logs se envían a Telegram cuando `TG_LOG_CHAT_ID` está configurado:
|
|
782
|
+
|
|
783
|
+
- **Buffering**: Los logs se bufferizan (máximo 10 mensajes, 5 segundos de
|
|
784
|
+
timeout)
|
|
785
|
+
- **Rate Limiting**: Limitación automática de tasa para prevenir spam
|
|
786
|
+
- **Niveles**: Solo los logs que coincidan con `LOG_LEVEL` se envían
|
|
787
|
+
|
|
788
|
+
Desactiva el streaming de logs removiendo `TG_LOG_CHAT_ID` de `.env`.
|
|
789
|
+
|
|
790
|
+
## Solución de Problemas
|
|
791
|
+
|
|
792
|
+
### El bot no responde a los comandos
|
|
793
|
+
|
|
794
|
+
**Problema**: El bot recibe comandos pero no responde
|
|
795
|
+
|
|
796
|
+
**Soluciones:**
|
|
797
|
+
|
|
798
|
+
- Verifica que `TG_BOT_TOKEN` es correcto
|
|
799
|
+
- Comprueba si el bot está ejecutándose con el comando `/health`
|
|
800
|
+
- Asegúrate de que estás enviando mensajes a la cuenta correcta del bot
|
|
801
|
+
- Verifica `TG_AUTHORIZED_USER_IDS` para comandos de control
|
|
802
|
+
|
|
803
|
+
### Webhook no recibe actualizaciones
|
|
804
|
+
|
|
805
|
+
**Problema**: Webhook configurado pero Telegram no envía actualizaciones
|
|
806
|
+
|
|
807
|
+
**Soluciones:**
|
|
808
|
+
|
|
809
|
+
- Verifica que `TG_WEBHOOK_URL` es públicamente accesible
|
|
810
|
+
```bash
|
|
811
|
+
curl https://tu-url-webhook.com/webhook
|
|
812
|
+
```
|
|
813
|
+
- Comprueba el firewall permite conexiones entrantes
|
|
814
|
+
- Verifica que la URL usa HTTPS (requerido por Telegram)
|
|
815
|
+
- Revisa los logs del bot para errores de configuración del webhook
|
|
816
|
+
- Usa un probador de la API de bots de Telegram para verificar la URL del
|
|
817
|
+
webhook
|
|
818
|
+
|
|
819
|
+
### El streaming de logs no funciona
|
|
820
|
+
|
|
821
|
+
**Problema**: Los logs no se están enviando a Telegram
|
|
822
|
+
|
|
823
|
+
**Soluciones:**
|
|
824
|
+
|
|
825
|
+
- Verifica que `TG_LOG_CHAT_ID` está configurado correctamente
|
|
826
|
+
- Comprueba que el bot tiene permiso para enviar mensajes en el chat
|
|
827
|
+
- Verifica que `TG_LOG_TOPIC_ID` coincide con el ID del topic (obtener de
|
|
828
|
+
Telegram)
|
|
829
|
+
- Verifica que `LOG_LEVEL` es apropiado para los logs que esperas
|
|
830
|
+
|
|
831
|
+
### Errores de typecheck
|
|
832
|
+
|
|
833
|
+
```bash
|
|
834
|
+
# Instalar dependencias
|
|
835
|
+
bun install
|
|
836
|
+
|
|
837
|
+
# Verificar tipos
|
|
838
|
+
bun run typecheck:bot
|
|
839
|
+
|
|
840
|
+
# Formatear código
|
|
841
|
+
bun run format
|
|
842
|
+
```
|
|
843
|
+
|
|
844
|
+
### Errores de permiso denegado
|
|
845
|
+
|
|
846
|
+
**Problema**: El bot devuelve "no tiene suficientes derechos" o errores
|
|
847
|
+
similares
|
|
848
|
+
|
|
849
|
+
**Soluciones:**
|
|
850
|
+
|
|
851
|
+
- Verifica que el bot es admin del grupo/canal
|
|
852
|
+
- Comprueba que el bot tiene permiso para enviar mensajes
|
|
853
|
+
- Verifica que los IDs de topic son correctos (los topics requieren derechos de
|
|
854
|
+
admin del bot)
|
|
855
|
+
- Elimina y vuelve a añadir el bot al chat para refrescar permisos
|
|
856
|
+
|
|
857
|
+
## Desarrollo
|
|
858
|
+
|
|
859
|
+
```bash
|
|
860
|
+
# Instalar dependencias
|
|
861
|
+
bun install
|
|
862
|
+
|
|
863
|
+
# Ejecutar en modo watch
|
|
864
|
+
bun run dev:bot
|
|
865
|
+
|
|
866
|
+
# Solo verificar tipos
|
|
867
|
+
bun run typecheck:bot
|
|
868
|
+
|
|
869
|
+
# Ejecutar linter
|
|
870
|
+
bun run lint
|
|
871
|
+
|
|
872
|
+
# Formatear código
|
|
873
|
+
bun run format
|
|
874
|
+
|
|
875
|
+
# Verificar formateo
|
|
876
|
+
bun run format:check
|
|
877
|
+
```
|
|
878
|
+
|
|
879
|
+
## Estructura del Proyecto
|
|
880
|
+
|
|
881
|
+
```
|
|
882
|
+
apps/telegram-bot/
|
|
883
|
+
├── src/
|
|
884
|
+
│ ├── index.ts # Punto de entrada del bot
|
|
885
|
+
│ ├── config/
|
|
886
|
+
│ │ ├── env.ts # Validación de entorno
|
|
887
|
+
│ │ └── index.ts # Gestión de configuración
|
|
888
|
+
│ ├── middleware/
|
|
889
|
+
│ │ ├── auth.ts # Middleware de autorización
|
|
890
|
+
│ │ ├── error-handler.ts # Manejo global de errores
|
|
891
|
+
│ │ ├── logging.ts # Integración con Better Logger
|
|
892
|
+
│ │ └── topics.ts # Validación de topics
|
|
893
|
+
│ ├── handlers/
|
|
894
|
+
│ │ ├── health.ts # Comandos de salud y estadísticas
|
|
895
|
+
│ │ ├── control.ts # Comandos de control
|
|
896
|
+
│ │ └── logs.ts # Streaming de logs
|
|
897
|
+
│ ├── utils/
|
|
898
|
+
│ │ ├── bot-manager.ts # Gestión del ciclo de vida del bot
|
|
899
|
+
│ │ └── formatters.ts # Formateadores de mensajes
|
|
900
|
+
│ └── types/
|
|
901
|
+
│ ├── bot.ts # Interfaces TypeScript
|
|
902
|
+
│ ├── result.ts # Monad de Result
|
|
903
|
+
│ └── constants.ts # Constantes
|
|
904
|
+
├── package.json
|
|
905
|
+
├── tsconfig.json
|
|
906
|
+
├── .env.example
|
|
907
|
+
└── README.md
|
|
908
|
+
```
|
|
909
|
+
|
|
910
|
+
## Personalización
|
|
911
|
+
|
|
912
|
+
### Añadir Nuevos Comandos
|
|
913
|
+
|
|
914
|
+
1. Crear función handler en `src/handlers/`:
|
|
915
|
+
|
|
916
|
+
```typescript
|
|
917
|
+
// src/handlers/custom.ts
|
|
918
|
+
import type { Context } from 'telegraf'
|
|
919
|
+
|
|
920
|
+
export async function handleCustom(ctx: Context): Promise<void> {
|
|
921
|
+
await ctx.reply('Respuesta de comando personalizado')
|
|
922
|
+
}
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
2. Registrar en `src/index.ts`:
|
|
926
|
+
|
|
927
|
+
```typescript
|
|
928
|
+
import { handleCustom } from './handlers/custom.js'
|
|
929
|
+
|
|
930
|
+
bot.command('custom', handleCustom)
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
### Añadir Middleware Personalizado
|
|
934
|
+
|
|
935
|
+
```typescript
|
|
936
|
+
// src/middleware/custom.ts
|
|
937
|
+
import type { Context, Middleware } from 'telegraf'
|
|
938
|
+
|
|
939
|
+
export function customMiddleware(): Middleware<Context> {
|
|
940
|
+
return async (ctx, next) => {
|
|
941
|
+
// Tu lógica aquí
|
|
942
|
+
return next()
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// Registrar en src/index.ts
|
|
947
|
+
import { customMiddleware } from './middleware/custom.js'
|
|
948
|
+
bot.use(customMiddleware())
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
### Personalizar Niveles de Log
|
|
952
|
+
|
|
953
|
+
```typescript
|
|
954
|
+
// src/middleware/logging.ts
|
|
955
|
+
import { getConfig } from '../config/index.js'
|
|
956
|
+
import logger from '@mks2508/better-logger'
|
|
957
|
+
|
|
958
|
+
const config = getConfig()
|
|
959
|
+
|
|
960
|
+
if (config.logLevel === 'debug') {
|
|
961
|
+
logger.preset('debug')
|
|
962
|
+
logger.showLocation()
|
|
963
|
+
} else {
|
|
964
|
+
logger.preset('cyberpunk')
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
logger.showTimestamp()
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
## API Pública: BotManager
|
|
971
|
+
|
|
972
|
+
```typescript
|
|
973
|
+
import { botManager } from './utils/bot-manager.js'
|
|
974
|
+
|
|
975
|
+
// Iniciar bot
|
|
976
|
+
await botManager.start(bot, 'polling')
|
|
977
|
+
|
|
978
|
+
// Obtener estado actual
|
|
979
|
+
const statusResult = botManager.getStatus()
|
|
980
|
+
if (statusResult.ok) {
|
|
981
|
+
console.log(`Estado del bot: ${statusResult.value.status}`)
|
|
982
|
+
console.log(`Modo: ${statusResult.value.mode}`)
|
|
983
|
+
console.log(`Uptime: ${statusResult.value.uptime}ms`)
|
|
984
|
+
console.log(`Memoria:`, statusResult.value.memoryUsage)
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// Obtener estadísticas
|
|
988
|
+
const statsResult = botManager.getStats()
|
|
989
|
+
if (statsResult.ok) {
|
|
990
|
+
console.log(`Mensajes: ${statsResult.value.messagesProcessed}`)
|
|
991
|
+
console.log(`Comandos: ${statsResult.value.commandsExecuted}`)
|
|
992
|
+
console.log(`Errores: ${statsResult.value.errorsEncountered}`)
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
// Reiniciar bot
|
|
996
|
+
await botManager.restart()
|
|
997
|
+
|
|
998
|
+
// Apagar bot
|
|
999
|
+
await botManager.stop('razón')
|
|
1000
|
+
|
|
1001
|
+
// Resetear estadísticas
|
|
1002
|
+
await botManager.resetStats()
|
|
1003
|
+
|
|
1004
|
+
// Verificar autorización
|
|
1005
|
+
const isAuth = botManager.authorize(userId)
|
|
1006
|
+
if (isAuth.ok) {
|
|
1007
|
+
console.log('Usuario autorizado')
|
|
1008
|
+
} else {
|
|
1009
|
+
console.log('Usuario no autorizado')
|
|
1010
|
+
}
|
|
1011
|
+
```
|
|
1012
|
+
|
|
1013
|
+
## Recursos
|
|
1014
|
+
|
|
1015
|
+
- [Documentación de Telegraf](https://telegraf.js.org/)
|
|
1016
|
+
- [API de Bots de Telegram](https://core.telegram.org/bots/api)
|
|
1017
|
+
- [Better Logger](https://github.com/mks2508/better-logger)
|
|
1018
|
+
- [Documentación de Bun](https://bun.sh/docs)
|
|
1019
|
+
|
|
1020
|
+
## Licencia
|
|
1021
|
+
|
|
1022
|
+
MIT
|
|
1023
|
+
|
|
1024
|
+
## Autor
|
|
1025
|
+
|
|
1026
|
+
MKS2508
|
|
1027
|
+
|
|
1028
|
+
## Contribuyendo
|
|
1029
|
+
|
|
1030
|
+
Esta es una plantilla. Siéntete libre de fork y personalizar para tu caso de
|
|
1031
|
+
uso.
|
|
1032
|
+
|
|
1033
|
+
### Mejores Prácticas
|
|
1034
|
+
|
|
1035
|
+
- Usa modo estricto de TypeScript
|
|
1036
|
+
- Añade JSDoc a funciones públicas
|
|
1037
|
+
- Sigue los patrones de código existentes
|
|
1038
|
+
- Prueba antes de hacer commit
|
|
1039
|
+
- Mantén commits atómicos y descriptivos
|
|
1040
|
+
|
|
1041
|
+
## Actualizaciones
|
|
1042
|
+
|
|
1043
|
+
Para actualizar dependencias:
|
|
1044
|
+
|
|
1045
|
+
```bash
|
|
1046
|
+
bun install
|
|
1047
|
+
```
|
|
1048
|
+
|
|
1049
|
+
Para añadir nuevas dependencias:
|
|
1050
|
+
|
|
1051
|
+
```bash
|
|
1052
|
+
cd apps/telegram-bot
|
|
1053
|
+
bun add package-name
|
|
1054
|
+
```
|
|
1055
|
+
|
|
1056
|
+
## Reportando Problemas
|
|
1057
|
+
|
|
1058
|
+
Para problemas específicos de esta plantilla, abre un issue en el repositorio.
|
|
1059
|
+
|
|
1060
|
+
Para problemas de Telegraf: https://github.com/telegraf/telegraf/issues Para
|
|
1061
|
+
problemas de Better Logger: https://github.com/mks2508/better-logger/issues
|
|
1062
|
+
|
|
1063
|
+
---
|
|
1064
|
+
|
|
1065
|
+
<div align="center">
|
|
1066
|
+
|
|
1067
|
+
Made with ❤️ by [MKS2508](https://github.com/mks2508)
|