{"id":29420279,"url":"https://github.com/byteholic/teleplate","last_synced_at":"2026-03-12T10:38:05.981Z","repository":{"id":197440483,"uuid":"686742665","full_name":"ByteHolic/TelePlate","owner":"ByteHolic","description":"Telegram Bot Template with Grammy \u0026 Hono","archived":false,"fork":false,"pushed_at":"2025-07-08T10:35:48.000Z","size":30,"stargazers_count":14,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-12T01:31:51.378Z","etag":null,"topics":["bot-template","grammy","grammyjs","hono","honojs","telegram","telegram-bot-template"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ByteHolic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-09-03T19:43:43.000Z","updated_at":"2025-07-08T10:35:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"1ff1b755-cc46-451a-b4dc-fe5bb8cec371","html_url":"https://github.com/ByteHolic/TelePlate","commit_stats":null,"previous_names":["yamlengineer/teleplate"],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/ByteHolic/TelePlate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ByteHolic%2FTelePlate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ByteHolic%2FTelePlate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ByteHolic%2FTelePlate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ByteHolic%2FTelePlate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ByteHolic","download_url":"https://codeload.github.com/ByteHolic/TelePlate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ByteHolic%2FTelePlate/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264923074,"owners_count":23683717,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bot-template","grammy","grammyjs","hono","honojs","telegram","telegram-bot-template"],"created_at":"2025-07-12T01:31:11.267Z","updated_at":"2026-03-12T10:38:05.974Z","avatar_url":"https://github.com/ByteHolic.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🤖 MTCute Modular Bot Template\n\nTelegram bot template built with **mtcute**, **Bun**, **TypeScript**, and **Drizzle ORM**. Features a NestJS-inspired modular architecture with dependency injection, decorators, and type safety.\n\n\u003e 💡 Also check out [TelePlate](https://github.com/ByteHolic/TelePlate/tree/grammy-version) - Our grammY-based bot template!\n\n***\n\n## ✨ Features\n\n- 🏗️ **Modular Architecture** - NestJS-style modules, services, and decorators\n- 💉 **Dependency Injection** - Custom DI container with automatic resolution\n- 🎨 **Decorator-Based Handlers** - Clean and intuitive update handling\n- 🗃️ **Drizzle ORM** - Type-safe database operations with SQLite\n- 📁 **Path Aliases** - Clean imports (`@core`, `@common`, `@database`, `@modules`)\n- ⚡ **Bun Runtime** - Lightning-fast performance\n- 🔧 **Full TypeScript** - End-to-end type safety\n- 📊 **Built-in Logger** - Configurable logging system\n- ⚙️ **Environment Validation** - Zod-based configuration validation\n- 🎭 **30+ Event Types** - Complete mtcute API coverage\n- 🔄 **Hot Reload** - Auto-restart in development mode\n\n***\n\n## 📦 Usage\n\nFollow these steps to set up and run your bot:\n\n### 1. Create a New Repository\n\nStart by creating a new repository using this template. [Click here to create](https://github.com/ByteHolic/TelePlate/generate).\n\n### 2. Environment Variables Setup\n\nCreate an environment variables file:\n\n```bash\ncp .env.example .env\n```\n\nEdit `.env` and set the required variables:\n\n```env\nAPI_ID=12345678\nAPI_HASH=your_api_hash\nBOT_TOKEN=your_bot_token\nNODE_ENV=development\nLOG_LEVEL=debug\nSESSION_NAME=bot_session\nDATABASE_URL=./bot-data/bot.db\n```\n\n### 3. Database Setup\n\nInitialize the database:\n\n```bash\nbun run db:push\n```\n\n### 4. Launching the Bot\n\n**Development Mode:**\n\n```bash\n# Install dependencies\nbun install\n\n# Start bot with hot reload\nbun run dev\n```\n\n**Production Mode:**\n\n```bash\n# Install production dependencies only\nbun install --production\n\n# Set NODE_ENV to production in .env\n# Then start the bot\nbun run start\n```\n\n***\n\n## 📝 List of Available Commands\n\n- `bun run dev` — Start in development mode with hot reload\n- `bun run start` — Start in production mode\n- `bun run db:push` — Push database schema\n- `bun run db:studio` — Open Drizzle Studio (database GUI)\n- `bun run db:generate` — Generate migrations\n\n***\n\n## 🗂️ Directory Structure\n\n```\nproject-root/\n├── src/\n│   ├── core/                      # Core framework\n│   │   ├── di/                    # Dependency injection\n│   │   │   ├── container.ts       # DI container\n│   │   │   └── metadata.ts        # Metadata keys\n│   │   ├── decorators/            # All decorators\n│   │   │   ├── injectable.decorator.ts\n│   │   │   ├── inject.decorator.ts\n│   │   │   ├── module.decorator.ts\n│   │   │   ├── update.decorators.ts     # 30+ event decorators\n│   │   │   ├── message.decorators.ts    # Message filters\n│   │   │   ├── callback.decorators.ts   # Callback queries\n│   │   │   ├── inline.decorators.ts     # Inline mode\n│   │   │   └── chat.decorators.ts       # Chat events\n│   │   ├── interfaces/\n│   │   │   └── module.interface.ts\n│   │   └── module-loader.ts       # Module loader\n│   ├── common/                    # Common utilities\n│   │   ├── config/                # Configuration\n│   │   │   ├── env.schema.ts      # Zod validation\n│   │   │   ├── env.validator.ts\n│   │   │   ├── env.service.ts\n│   │   │   └── config.module.ts\n│   │   └── logger/                # Logging system\n│   │       ├── logger.service.ts\n│   │       ├── logger.interface.ts\n│   │       └── logger.module.ts\n│   ├── database/                  # Database layer\n│   │   ├── schema/                # Drizzle schemas\n│   │   │   ├── users.schema.ts\n│   │   │   └── chats.schema.ts\n│   │   ├── db.service.ts\n│   │   └── database.module.ts\n│   ├── modules/                   # Bot modules\n│   │   ├── user/                  # User module\n│   │   │   ├── user.service.ts    # Business logic\n│   │   │   ├── user.updates.ts    # Update handlers\n│   │   │   └── user.module.ts     # Module definition\n│   │   └── chat/                  # Chat module\n│   │       ├── chat.service.ts\n│   │       ├── chat.updates.ts\n│   │       └── chat.module.ts\n│   ├── bot.module.ts              # Root module\n│   └── index.ts                   # Entry point\n├── drizzle/                       # Database migrations\n├── drizzle.config.ts              # Drizzle configuration\n├── tsconfig.json                  # TypeScript config with paths\n├── package.json\n└── .env                           # Environment variables\n```\n\n***\n\n## 🚀 Quick Start Example\n\n### Create a New Module\n\n```typescript\n// src/modules/hello/hello.service.ts\nimport { Injectable, Inject } from '@core/decorators';\nimport { LOGGER } from '@common/logger/constants';\nimport type { ILogger } from '@common/logger/logger.interface';\n\n@Injectable()\nexport class HelloService {\n  constructor(@Inject(LOGGER) private readonly logger: ILogger) {}\n\n  getGreeting(name: string): string {\n    this.logger.log(`Generating greeting for ${name}`);\n    return `Hello, ${name}! 👋`;\n  }\n}\n```\n\n```typescript\n// src/modules/hello/hello.updates.ts\nimport { Inject } from '@core/decorators';\nimport { OnCommand, OnText } from '@core/decorators';\nimport { TELEGRAM_CLIENT } from '@core/module-loader';\nimport { HelloService } from './hello.service';\nimport type { TelegramClient, Message } from '@mtcute/bun';\n\nexport class HelloUpdates {\n  constructor(\n    @Inject(HelloService) private readonly helloService: HelloService,\n    @Inject(TELEGRAM_CLIENT) private readonly client: TelegramClient\n  ) {}\n\n  @OnCommand('hello')\n  async handleHello(msg: Message) {\n    const greeting = this.helloService.getGreeting(msg.sender.firstName);\n    await this.client.sendText(msg.chat.id, greeting);\n  }\n\n  @OnText(/hi|hey/i)\n  async handleGreeting(msg: Message) {\n    await this.client.sendText(msg.chat.id, '👋 Hi there!');\n  }\n}\n```\n\n```typescript\n// src/modules/hello/hello.module.ts\nimport { Module } from '@core/decorators';\nimport { HelloService } from './hello.service';\nimport { HelloUpdates } from './hello.updates';\nimport { LoggerModule } from '@common/logger/logger.module';\n\n@Module({\n  imports: [LoggerModule],\n  providers: [HelloService],\n  updates: [HelloUpdates],\n  exports: [HelloService]\n})\nexport class HelloModule {}\n```\n\nRegister in `bot.module.ts`:\n\n```typescript\nimport { HelloModule } from '@modules/hello/hello.module';\n\n@Module({\n  imports: [\n    ConfigModule,\n    LoggerModule,\n    DatabaseModule,\n    HelloModule, // Add here\n  ]\n})\nexport class BotModule {}\n```\n\n***\n\n## 🎨 Available Decorators\n\n### Message Handlers\n\n```typescript\n@OnCommand('start')                  // Single command\n@OnCommand(['help', 'about'])        // Multiple commands\n@OnText()                            // Any text message\n@OnText('hello')                     // Text contains \"hello\"\n@OnText(/pattern/i)                  // Regex pattern\n@OnPhoto()                           // Photo messages\n@OnVideo()                           // Video messages\n@OnAudio()                           // Audio messages\n@OnVoice()                           // Voice messages\n@OnDocument()                        // Document messages\n@OnSticker()                         // Stickers\n@OnAnimation()                       // GIFs\n@OnContact()                         // Contacts\n@OnLocation()                        // Location\n@OnPoll()                            // Polls\n@OnDice()                            // Dice\n```\n\n### Update Handlers\n\n```typescript\n@OnNewMessage()                      // New message\n@OnEditMessage()                     // Message edited\n@OnDeleteMessage()                   // Message deleted\n@OnMessageGroup()                    // Album/media group\n@OnChatMemberUpdate()                // Member status changed\n@OnUserStatusUpdate()                // User online/offline\n@OnUserTyping()                      // User typing\n@OnHistoryRead()                     // Messages read\n@OnBotStopped()                      // Bot blocked by user\n@OnPollUpdate()                      // Poll updated\n@OnPollVote()                        // Poll vote\n@OnStoryUpdate()                     // Story posted\n@OnBotReactionUpdate()               // Reaction added\n```\n\n### Callback \u0026 Inline\n\n```typescript\n@OnCallback()                        // Any callback query\n@OnCallback('button_id')             // Specific callback data\n@OnCallback(/^action_/)              // Regex pattern\n@OnInline()                          // Any inline query\n@OnInline('search')                  // Contains text\n@OnChosenInline()                    // Inline result chosen\n```\n\n### Chat Events\n\n```typescript\n@OnNewChatMembers()                  // New members\n@OnLeftChatMember()                  // Member left\n@OnPinnedMessage()                   // Message pinned\n@OnNewChatTitle()                    // Title changed\n@OnNewChatPhoto()                    // Photo changed\n```\n\n***\n\n## 🗃️ Database Operations\n\n### Define Schema\n\n```typescript\n// src/database/schema/posts.schema.ts\nimport { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';\n\nexport const posts = sqliteTable('posts', {\n  id: integer('id').primaryKey({ autoIncrement: true }),\n  title: text('title').notNull(),\n  content: text('content').notNull(),\n  userId: integer('user_id').notNull(),\n  createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),\n});\n\nexport type Post = typeof posts.$inferSelect;\nexport type NewPost = typeof posts.$inferInsert;\n```\n\n### Use in Service\n\n```typescript\nimport { eq } from 'drizzle-orm';\n\n@Injectable()\nexport class PostService {\n  constructor(@Inject(DbService) private readonly db: DbService) {}\n\n  async createPost(data: NewPost) {\n    return await this.db.db.insert(posts).values(data).returning();\n  }\n\n  async getPost(id: number) {\n    return await this.db.db.query.posts.findFirst({\n      where: eq(posts.id, id),\n    });\n  }\n}\n```\n\n***\n\n## 🔧 Configuration\n\nAll configuration is done via environment variables validated with Zod:\n\n```typescript\n// src/common/config/env.schema.ts\nexport const envSchema = z.object({\n  API_ID: z.coerce.number().positive(),\n  API_HASH: z.string().min(1),\n  BOT_TOKEN: z.string().min(1),\n  // Add your custom variables\n  MY_VAR: z.string().default('default_value'),\n});\n```\n\nAccess in services:\n\n```typescript\nconstructor(@Inject(ENV_SERVICE) private readonly env: EnvService) {\n  const apiId = this.env.apiId;\n  const custom = this.env.get('MY_VAR');\n}\n```\n\n***\n\n## 🚢 Deployment\n\n### Using Docker\n\n```dockerfile\nFROM oven/bun:latest\n\nWORKDIR /app\n\nCOPY package.json bun.lockb ./\nRUN bun install --frozen-lockfile --production\n\nCOPY . .\n\nRUN bun run db:push\n\nCMD [\"bun\", \"run\", \"start\"]\n```\n\nBuild and run:\n\n```bash\ndocker build -t telegram-bot .\ndocker run -d --env-file .env telegram-bot\n```\n\n### Using PM2\n\n```bash\n# Install PM2\nbun add -g pm2\n\n# Start\npm2 start bun --name \"telegram-bot\" -- run start\n\n# Monitor\npm2 logs telegram-bot\npm2 monit\n```\n\n***\n\n## 💡 Best Practices\n\n1. **Keep modules focused** - One responsibility per module\n2. **Use dependency injection** - Better testability and maintainability\n3. **Leverage path aliases** - Keep imports clean (`@core`, `@common`, etc.)\n4. **Log important events** - Use the logger service\n5. **Validate all inputs** - Use Zod schemas\n6. **Handle errors gracefully** - Wrap handlers in try-catch\n7. **Type everything** - Take advantage of TypeScript\n\n***\n\n## 📚 Learn More\n\n- [mtcute Documentation](https://mtcute.dev) - Telegram client library\n- [Drizzle ORM](https://orm.drizzle.team) - TypeScript ORM\n- [Bun](https://bun.sh) - JavaScript runtime\n- [TelePlate](https://github.com/ByteHolic/TelePlate) - grammY-based alternative\n\n***\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing`)\n5. Open a Pull Request\n\n***\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n***\n\n## 🙏 Acknowledgments\n\n- [mtcute](https://github.com/mtcute/mtcute) - Telegram client library\n- [NestJS](https://nestjs.com) - Architecture inspiration\n- [Drizzle ORM](https://orm.drizzle.team) - Database toolkit\n- [Bun](https://bun.sh) - Fast all-in-one runtime\n\n***\n\n## 📞 Support\n\nIf you like this project, please consider giving it a ⭐️ on [GitHub](https://github.com/ByteHolic/TelePlate)!\n\n**Made with ❤️ by [ByteHolic](https://github.com/ByteHolic)**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyteholic%2Fteleplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbyteholic%2Fteleplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyteholic%2Fteleplate/lists"}