@4via6/relay 1.0.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/.env.example +50 -0
- package/README.md +253 -0
- package/dist/auth.d.ts +3 -0
- package/dist/auth.js +32 -0
- package/dist/auth.js.map +1 -0
- package/dist/bot.d.ts +2 -0
- package/dist/bot.js +14 -0
- package/dist/bot.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/admin.d.ts +2 -0
- package/dist/commands/admin.js +420 -0
- package/dist/commands/admin.js.map +1 -0
- package/dist/commands/chat.d.ts +2 -0
- package/dist/commands/chat.js +80 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/files.d.ts +2 -0
- package/dist/commands/files.js +162 -0
- package/dist/commands/files.js.map +1 -0
- package/dist/commands/history.d.ts +2 -0
- package/dist/commands/history.js +152 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.js +21 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/mcp.d.ts +2 -0
- package/dist/commands/mcp.js +105 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/media.d.ts +2 -0
- package/dist/commands/media.js +248 -0
- package/dist/commands/media.js.map +1 -0
- package/dist/commands/monitor.d.ts +2 -0
- package/dist/commands/monitor.js +136 -0
- package/dist/commands/monitor.js.map +1 -0
- package/dist/commands/session.d.ts +2 -0
- package/dist/commands/session.js +114 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/shell.d.ts +2 -0
- package/dist/commands/shell.js +90 -0
- package/dist/commands/shell.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/claude.d.ts +52 -0
- package/dist/providers/claude.js +449 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/codex.d.ts +45 -0
- package/dist/providers/codex.js +400 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/providers/index.d.ts +6 -0
- package/dist/providers/index.js +40 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/opencode.d.ts +40 -0
- package/dist/providers/opencode.js +498 -0
- package/dist/providers/opencode.js.map +1 -0
- package/dist/providers/types.d.ts +173 -0
- package/dist/providers/types.js +6 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/session.d.ts +10 -0
- package/dist/session.js +65 -0
- package/dist/session.js.map +1 -0
- package/dist/utils/chunker.d.ts +1 -0
- package/dist/utils/chunker.js +24 -0
- package/dist/utils/chunker.js.map +1 -0
- package/dist/utils/errors.d.ts +12 -0
- package/dist/utils/errors.js +85 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/files.d.ts +15 -0
- package/dist/utils/files.js +81 -0
- package/dist/utils/files.js.map +1 -0
- package/dist/utils/html.d.ts +4 -0
- package/dist/utils/html.js +10 -0
- package/dist/utils/html.js.map +1 -0
- package/dist/utils/media.d.ts +15 -0
- package/dist/utils/media.js +103 -0
- package/dist/utils/media.js.map +1 -0
- package/dist/utils/store.d.ts +15 -0
- package/dist/utils/store.js +44 -0
- package/dist/utils/store.js.map +1 -0
- package/dist/utils/stream.d.ts +21 -0
- package/dist/utils/stream.js +149 -0
- package/dist/utils/stream.js.map +1 -0
- package/dist/utils/stt.d.ts +7 -0
- package/dist/utils/stt.js +118 -0
- package/dist/utils/stt.js.map +1 -0
- package/dist/utils/system-prompt.d.ts +5 -0
- package/dist/utils/system-prompt.js +64 -0
- package/dist/utils/system-prompt.js.map +1 -0
- package/dist/utils/timeout.d.ts +2 -0
- package/dist/utils/timeout.js +18 -0
- package/dist/utils/timeout.js.map +1 -0
- package/docs/commands.md +351 -0
- package/docs/configuration.md +160 -0
- package/docs/features.md +443 -0
- package/docs/getting-started.md +102 -0
- package/docs/providers.md +236 -0
- package/docs/troubleshooting.md +287 -0
- package/package.json +54 -0
package/.env.example
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Telegram
|
|
2
|
+
BOT_TOKEN=your-telegram-bot-token
|
|
3
|
+
ALLOWED_USER_ID=your-telegram-user-id
|
|
4
|
+
|
|
5
|
+
# Provider selection: "opencode" | "claude" | "codex"
|
|
6
|
+
PROVIDER=opencode
|
|
7
|
+
|
|
8
|
+
# --- OpenCode provider ---
|
|
9
|
+
OPENCODE_MODE=start # "start" (spawn server) or "connect" (remote URL)
|
|
10
|
+
OPENCODE_URL=http://localhost:4096 # used when MODE=connect
|
|
11
|
+
OPENCODE_HOSTNAME=127.0.0.1 # used when MODE=start
|
|
12
|
+
OPENCODE_PORT=4096 # used when MODE=start
|
|
13
|
+
OPENCODE_MODEL= # e.g. "anthropic/claude-sonnet-4-20250514"
|
|
14
|
+
|
|
15
|
+
# --- Claude Code provider ---
|
|
16
|
+
# ANTHROPIC_API_KEY=sk-ant-... # required for PROVIDER=claude
|
|
17
|
+
# CLAUDE_MODEL=sonnet # "sonnet" | "opus" | "haiku"
|
|
18
|
+
# CLAUDE_PERMISSION_MODE=acceptEdits # Claude permission mode
|
|
19
|
+
# CLAUDE_CWD= # working directory (default: process.cwd())
|
|
20
|
+
|
|
21
|
+
# --- Codex provider ---
|
|
22
|
+
# CODEX_API_KEY=sk-... # required for PROVIDER=codex (or use OPENAI_API_KEY)
|
|
23
|
+
# CODEX_MODEL=o3 # "o3" | "o4-mini" etc.
|
|
24
|
+
# CODEX_CWD= # working directory (default: process.cwd())
|
|
25
|
+
|
|
26
|
+
# Bot mode: "polling" (default) or "webhook"
|
|
27
|
+
BOT_MODE=polling
|
|
28
|
+
# WEBHOOK_URL=https://example.com/bot # required when BOT_MODE=webhook
|
|
29
|
+
# WEBHOOK_PORT=3000 # HTTP server port (default: 3000)
|
|
30
|
+
# WEBHOOK_SECRET=your-secret-token # optional secret for webhook verification
|
|
31
|
+
|
|
32
|
+
# Data directory for persisted state (default: .relay/ in project root)
|
|
33
|
+
# RELAY_DATA_DIR=.relay
|
|
34
|
+
|
|
35
|
+
# Streaming (progressive message editing — supported by all providers)
|
|
36
|
+
STREAMING_ENABLED=false
|
|
37
|
+
STREAM_EDIT_INTERVAL_MS=2000
|
|
38
|
+
|
|
39
|
+
# Prompt timeout (milliseconds) — max time to wait for a provider response
|
|
40
|
+
PROMPT_TIMEOUT_MS=300000 # 5 minutes
|
|
41
|
+
|
|
42
|
+
# System prompt — loaded from file and prepended to every message
|
|
43
|
+
# Default built-in prompt is used if no file exists
|
|
44
|
+
# SYSTEM_PROMPT_FILE=skill.md # default: looks for skill.md in project root
|
|
45
|
+
|
|
46
|
+
# Voice STT — set one or more; cheapest available is auto-selected
|
|
47
|
+
# STT_PROVIDER=auto # "openai" | "groq" | "assemblyai" | "auto" (default)
|
|
48
|
+
GROQ_API_KEY=
|
|
49
|
+
OPENAI_API_KEY=
|
|
50
|
+
ASSEMBLYAI_API_KEY=
|
package/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# Relay
|
|
2
|
+
|
|
3
|
+
Telegram bot for managing AI coding agents remotely. Supports [OpenCode](https://github.com/opencode-ai/opencode), [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview), and [OpenAI Codex](https://github.com/openai/codex).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Multi-provider** -- switch between OpenCode, Claude Code, and Codex with a single env var
|
|
8
|
+
- **Text, voice, photo, and file input** -- send messages in any format
|
|
9
|
+
- **File output** -- receive screenshots, generated files, and artifacts as Telegram attachments (OpenCode)
|
|
10
|
+
- **Streaming responses** -- progressive message editing for real-time output
|
|
11
|
+
- **Session management** -- create, switch, fork, delete, and list sessions
|
|
12
|
+
- **Dynamic model selection** -- models fetched from provider APIs, always up to date
|
|
13
|
+
- **MCP servers** -- add, remove, and monitor MCP servers at runtime (OpenCode, Claude)
|
|
14
|
+
- **Shell access** -- run commands on the coding agent's machine
|
|
15
|
+
- **Voice transcription** -- Groq, OpenAI, or AssemblyAI speech-to-text
|
|
16
|
+
- **Custom system prompts** -- load from file, hot-reload on change
|
|
17
|
+
- **File operations** -- read, find, search, and browse project files (all providers)
|
|
18
|
+
- **Code diffs** -- view git diffs from sessions (all providers)
|
|
19
|
+
- **State persistence** -- sessions, model selection, and MCP configs survive restarts
|
|
20
|
+
- **Webhook mode** -- deploy with webhooks for lower latency in production
|
|
21
|
+
- **Large file support** -- text files up to 500KB fully included, larger files chunked
|
|
22
|
+
|
|
23
|
+
## Documentation
|
|
24
|
+
|
|
25
|
+
| Guide | Description |
|
|
26
|
+
|-------|-------------|
|
|
27
|
+
| [Getting Started](docs/getting-started.md) | Installation, prerequisites, first steps |
|
|
28
|
+
| [Configuration](docs/configuration.md) | All environment variables and options |
|
|
29
|
+
| [Providers](docs/providers.md) | Detailed setup for each provider |
|
|
30
|
+
| [Commands](docs/commands.md) | Full command reference with examples |
|
|
31
|
+
| [Features](docs/features.md) | Streaming, file attachments, voice, MCP, models |
|
|
32
|
+
| [Troubleshooting](docs/troubleshooting.md) | Common issues and solutions |
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
### From npm
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install -g relay
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Then create a `.env` file in your working directory (see [Configuration](docs/configuration.md)):
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
curl -O https://raw.githubusercontent.com/Harsh-2002/relay/main/.env.example
|
|
46
|
+
# Edit .env with your BOT_TOKEN, ALLOWED_USER_ID, and provider config
|
|
47
|
+
relay
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### From source
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
git clone https://github.com/Harsh-2002/relay.git
|
|
54
|
+
cd relay
|
|
55
|
+
npm install
|
|
56
|
+
npm run build
|
|
57
|
+
cp .env.example .env
|
|
58
|
+
# Edit .env with your BOT_TOKEN, ALLOWED_USER_ID, and provider config
|
|
59
|
+
npm start
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### With npx (no install)
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx relay
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Prerequisites
|
|
69
|
+
|
|
70
|
+
- [Node.js](https://nodejs.org/) >= 18 (or [Bun](https://bun.sh/))
|
|
71
|
+
- A Telegram bot token (from [@BotFather](https://t.me/BotFather))
|
|
72
|
+
- Provider credentials (see below)
|
|
73
|
+
|
|
74
|
+
## Providers
|
|
75
|
+
|
|
76
|
+
Set `PROVIDER` in `.env` to select your coding agent backend.
|
|
77
|
+
|
|
78
|
+
| Provider | `PROVIDER=` | Required env vars | Install |
|
|
79
|
+
|----------|-------------|-------------------|---------|
|
|
80
|
+
| OpenCode | `opencode` | `OPENCODE_MODE` | included |
|
|
81
|
+
| Claude Code | `claude` | `ANTHROPIC_API_KEY` | `npm install @anthropic-ai/claude-code` |
|
|
82
|
+
| OpenAI Codex | `codex` | `CODEX_API_KEY` or `OPENAI_API_KEY` | `npm install @openai/codex` |
|
|
83
|
+
|
|
84
|
+
### OpenCode
|
|
85
|
+
|
|
86
|
+
```env
|
|
87
|
+
PROVIDER=opencode
|
|
88
|
+
OPENCODE_MODE=start # "start" (spawn server) or "connect" (remote URL)
|
|
89
|
+
OPENCODE_URL=http://localhost:4096
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Claude Code
|
|
93
|
+
|
|
94
|
+
```env
|
|
95
|
+
PROVIDER=claude
|
|
96
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
97
|
+
CLAUDE_MODEL=sonnet # use /models to see all available
|
|
98
|
+
CLAUDE_PERMISSION_MODE=acceptEdits
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### OpenAI Codex
|
|
102
|
+
|
|
103
|
+
```env
|
|
104
|
+
PROVIDER=codex
|
|
105
|
+
CODEX_API_KEY=sk-...
|
|
106
|
+
CODEX_MODEL=o3 # use /models to see all available
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Commands
|
|
110
|
+
|
|
111
|
+
### Chat
|
|
112
|
+
Send any text message, voice note, photo, or file to chat with the AI. File attachments from the AI (screenshots, generated files) are automatically sent back as Telegram documents or photos.
|
|
113
|
+
|
|
114
|
+
### Sessions
|
|
115
|
+
| Command | Description |
|
|
116
|
+
|---------|-------------|
|
|
117
|
+
| `/new` | Create a new session |
|
|
118
|
+
| `/sessions` | List all sessions |
|
|
119
|
+
| `/switch <id>` | Switch to a session |
|
|
120
|
+
| `/delete <id>` | Delete a session |
|
|
121
|
+
| `/current` | Show active session |
|
|
122
|
+
| `/fork [messageId]` | Fork the current session |
|
|
123
|
+
|
|
124
|
+
### Monitor
|
|
125
|
+
| Command | Description |
|
|
126
|
+
|---------|-------------|
|
|
127
|
+
| `/todo` | View AI task checklist (OpenCode) |
|
|
128
|
+
| `/diff` | Session code changes summary |
|
|
129
|
+
| `/diff full` | Download full diff |
|
|
130
|
+
|
|
131
|
+
### Files
|
|
132
|
+
| Command | Description |
|
|
133
|
+
|---------|-------------|
|
|
134
|
+
| `/read <path>` | Read a file |
|
|
135
|
+
| `/find <query>` | Find files by name |
|
|
136
|
+
| `/search <pattern>` | Search file contents |
|
|
137
|
+
| `/symbols <query>` | Find code symbols (OpenCode) |
|
|
138
|
+
| `/status` | Git file status |
|
|
139
|
+
|
|
140
|
+
### History
|
|
141
|
+
| Command | Description |
|
|
142
|
+
|---------|-------------|
|
|
143
|
+
| `/history` | View conversation history |
|
|
144
|
+
| `/summarize` | Summarize the session |
|
|
145
|
+
| `/revert` | Undo last AI change |
|
|
146
|
+
| `/abort` | Cancel running operation |
|
|
147
|
+
| `/share` | Share session (OpenCode) |
|
|
148
|
+
|
|
149
|
+
### Shell
|
|
150
|
+
| Command | Description |
|
|
151
|
+
|---------|-------------|
|
|
152
|
+
| `/shell <cmd>` | Run a shell command |
|
|
153
|
+
| `/cmd <command>` | Run an OpenCode command |
|
|
154
|
+
| `/commands` | List available commands |
|
|
155
|
+
|
|
156
|
+
### Models
|
|
157
|
+
| Command | Description |
|
|
158
|
+
|---------|-------------|
|
|
159
|
+
| `/models` | List available models with capabilities |
|
|
160
|
+
| `/model <provider/model>` | Set the AI model |
|
|
161
|
+
| `/model <name>` | Set model by partial match |
|
|
162
|
+
|
|
163
|
+
Models show capability badges: `[reasoning]` for thinking/reasoning support, `[vision]` for image input, and `[active]` for the currently selected model.
|
|
164
|
+
|
|
165
|
+
### MCP (OpenCode, Claude)
|
|
166
|
+
| Command | Description |
|
|
167
|
+
|---------|-------------|
|
|
168
|
+
| `/mcp` | Show MCP server status |
|
|
169
|
+
| `/mcp add <name> local <command...>` | Add a local MCP server |
|
|
170
|
+
| `/mcp add <name> remote <url>` | Add a remote MCP server |
|
|
171
|
+
| `/mcp remove <name>` | Remove an MCP server |
|
|
172
|
+
|
|
173
|
+
MCP servers extend the AI's capabilities with additional tools (browsers, databases, APIs). OpenCode supports full runtime management; Claude persists MCP config to disk and restores it on restart.
|
|
174
|
+
|
|
175
|
+
### Settings
|
|
176
|
+
| Command | Description |
|
|
177
|
+
|---------|-------------|
|
|
178
|
+
| `/system` | View system prompt |
|
|
179
|
+
| `/system reload` | Reload system prompt |
|
|
180
|
+
| `/health` | Server status (with reasoning badge) |
|
|
181
|
+
| `/config` | Show configuration |
|
|
182
|
+
| `/providers` | List available providers |
|
|
183
|
+
| `/agents` | List available agents |
|
|
184
|
+
| `/tools` | Available tools |
|
|
185
|
+
| `/project` | Project info |
|
|
186
|
+
| `/git` | Git branch and status |
|
|
187
|
+
| `/help` | Show all commands |
|
|
188
|
+
|
|
189
|
+
## Voice / STT
|
|
190
|
+
|
|
191
|
+
Configure one or more speech-to-text providers for voice message support. The cheapest available provider is auto-selected.
|
|
192
|
+
|
|
193
|
+
```env
|
|
194
|
+
GROQ_API_KEY=... # Groq Whisper (fastest, free tier)
|
|
195
|
+
OPENAI_API_KEY=... # OpenAI Whisper
|
|
196
|
+
ASSEMBLYAI_API_KEY=... # AssemblyAI
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## System Prompt
|
|
200
|
+
|
|
201
|
+
The bot loads a system prompt from `skill.md` in the project root (or the path set in `SYSTEM_PROMPT_FILE`). If the file doesn't exist, a default prompt is used. The file is watched for changes and reloaded automatically. Use `/system reload` to force a reload.
|
|
202
|
+
|
|
203
|
+
## Architecture
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
src/
|
|
207
|
+
providers/
|
|
208
|
+
types.ts -- Provider interface, capabilities, MCP/model types
|
|
209
|
+
index.ts -- Provider factory (selects based on PROVIDER env var)
|
|
210
|
+
opencode.ts -- OpenCode SDK provider
|
|
211
|
+
claude.ts -- Claude Code / Agent SDK provider
|
|
212
|
+
codex.ts -- OpenAI Codex SDK provider
|
|
213
|
+
commands/
|
|
214
|
+
chat.ts -- Text message handler
|
|
215
|
+
session.ts -- Session management commands
|
|
216
|
+
media.ts -- Photo, voice, audio, file handlers
|
|
217
|
+
admin.ts -- Health, config, model, models, help commands
|
|
218
|
+
monitor.ts -- Todo, diff, fork commands
|
|
219
|
+
files.ts -- File read, find, search commands
|
|
220
|
+
history.ts -- History, revert, share commands
|
|
221
|
+
shell.ts -- Shell and command execution
|
|
222
|
+
mcp.ts -- MCP server management
|
|
223
|
+
utils/
|
|
224
|
+
store.ts -- JSON file-backed persistence (.relay/)
|
|
225
|
+
stream.ts -- Streaming response handler
|
|
226
|
+
files.ts -- Outbound file attachment handling
|
|
227
|
+
chunker.ts -- Telegram message chunking
|
|
228
|
+
errors.ts -- Error formatting
|
|
229
|
+
html.ts -- HTML escaping for Telegram
|
|
230
|
+
media.ts -- File upload/download
|
|
231
|
+
stt.ts -- Speech-to-text
|
|
232
|
+
system-prompt.ts -- System prompt loading
|
|
233
|
+
timeout.ts -- Prompt timeout utility
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Each provider implements the `Provider` interface with a `capabilities` object declaring which features it supports. Commands check capabilities and show appropriate messages when a feature isn't available.
|
|
237
|
+
|
|
238
|
+
### Provider Capabilities
|
|
239
|
+
|
|
240
|
+
| Capability | OpenCode | Claude | Codex |
|
|
241
|
+
|-----------|----------|--------|-------|
|
|
242
|
+
| Streaming | yes | yes | yes |
|
|
243
|
+
| File output | yes | no | no |
|
|
244
|
+
| MCP management | yes | yes | no |
|
|
245
|
+
| Model listing | dynamic | dynamic | dynamic |
|
|
246
|
+
| Session management | full | limited | limited |
|
|
247
|
+
| File operations | yes | yes | yes |
|
|
248
|
+
| Code diffs | yes | yes | yes |
|
|
249
|
+
| State persistence | yes | yes | yes |
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
MIT
|
package/dist/auth.d.ts
ADDED
package/dist/auth.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Parse ALLOWED_USER_ID — fail-secure: NaN means "block all"
|
|
2
|
+
const raw = process.env.ALLOWED_USER_ID;
|
|
3
|
+
const allowedUserId = raw ? Number(raw) : NaN;
|
|
4
|
+
// Simple in-memory rate limiter: max requests per minute per user
|
|
5
|
+
const RATE_LIMIT = 30;
|
|
6
|
+
const rateBuckets = new Map();
|
|
7
|
+
export function isAuthConfigured() {
|
|
8
|
+
return !isNaN(allowedUserId) && allowedUserId > 0;
|
|
9
|
+
}
|
|
10
|
+
export async function authMiddleware(ctx, next) {
|
|
11
|
+
// Fail-secure: if ALLOWED_USER_ID is not set or invalid, block everyone
|
|
12
|
+
if (!isAuthConfigured()) {
|
|
13
|
+
await ctx.reply("Bot is misconfigured — ALLOWED_USER_ID is not set.");
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const userId = ctx.from?.id;
|
|
17
|
+
if (userId !== allowedUserId) {
|
|
18
|
+
await ctx.reply("Unauthorized.");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// Rate limiting
|
|
22
|
+
const now = Date.now();
|
|
23
|
+
const bucket = (rateBuckets.get(userId) ?? []).filter((t) => now - t < 60_000);
|
|
24
|
+
if (bucket.length >= RATE_LIMIT) {
|
|
25
|
+
await ctx.reply("Too many requests — wait a moment.");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
bucket.push(now);
|
|
29
|
+
rateBuckets.set(userId, bucket);
|
|
30
|
+
await next();
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAEA,6DAA6D;AAC7D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;AACxC,MAAM,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAE9C,kEAAkE;AAClE,MAAM,UAAU,GAAG,EAAE,CAAC;AACtB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAC;AAEhD,MAAM,UAAU,gBAAgB;IAC9B,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,aAAa,GAAG,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAY,EAAE,IAAkB;IACnE,wEAAwE;IACxE,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;QACxB,MAAM,GAAG,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;IAC5B,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;QAC7B,MAAM,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QACjC,OAAO;IACT,CAAC;IAED,gBAAgB;IAChB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IAC/E,IAAI,MAAM,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,GAAG,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACtD,OAAO;IACT,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhC,MAAM,IAAI,EAAE,CAAC;AACf,CAAC"}
|
package/dist/bot.d.ts
ADDED
package/dist/bot.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Bot } from "grammy";
|
|
2
|
+
import { authMiddleware } from "./auth.js";
|
|
3
|
+
import { registerCommands } from "./commands/index.js";
|
|
4
|
+
export function createBot(token) {
|
|
5
|
+
const bot = new Bot(token);
|
|
6
|
+
bot.use(authMiddleware);
|
|
7
|
+
registerCommands(bot);
|
|
8
|
+
bot.catch((err) => {
|
|
9
|
+
const e = err.error;
|
|
10
|
+
console.error("Bot error:", e instanceof Error ? e.message : String(e));
|
|
11
|
+
});
|
|
12
|
+
return bot;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=bot.js.map
|
package/dist/bot.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot.js","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAE3B,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACxB,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAEtB,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QAChB,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,CAAC"}
|