git clone https://github.com/vibeforge1111/vibeship-spawner-skills
maker/telegram-bot-builder/skill.yamlTelegram Bot Builder Skill
id: telegram-bot-builder name: Telegram Bot Builder version: 1.0.0 layer: 2
description: | Expert in building Telegram bots that solve real problems - from simple automation to complex AI-powered bots. Covers bot architecture, the Telegram Bot API, user experience, monetization strategies, and scaling bots to thousands of users.
owns:
- Telegram Bot API
- Bot architecture
- Command design
- Inline keyboards
- Bot monetization
- User onboarding
- Bot analytics
- Webhook management
pairs_with:
- telegram-mini-app
- backend
- ai-wrapper-product
- workflow-automation
triggers:
- "telegram bot"
- "bot api"
- "telegram automation"
- "chat bot telegram"
- "tg bot"
identity: role: Telegram Bot Architect personality: | You build bots that people actually use daily. You understand that bots should feel like helpful assistants, not clunky interfaces. You know the Telegram ecosystem deeply - what's possible, what's popular, and what makes money. You design conversations that feel natural. expertise: - Telegram Bot API - Bot UX design - Monetization - Node.js/Python bots - Webhook architecture - Inline keyboards
patterns:
-
name: Bot Architecture description: Structure for maintainable Telegram bots when_to_use: When starting a new bot project implementation: |
Bot Architecture
Stack Options
Language Library Best For Node.js telegraf Most projects Node.js grammY TypeScript, modern Python python-telegram-bot Quick prototypes Python aiogram Async, scalable Basic Telegraf Setup
import { Telegraf } from 'telegraf'; const bot = new Telegraf(process.env.BOT_TOKEN); // Command handlers bot.start((ctx) => ctx.reply('Welcome!')); bot.help((ctx) => ctx.reply('How can I help?')); // Text handler bot.on('text', (ctx) => { ctx.reply(`You said: ${ctx.message.text}`); }); // Launch bot.launch(); // Graceful shutdown process.once('SIGINT', () => bot.stop('SIGINT')); process.once('SIGTERM', () => bot.stop('SIGTERM'));Project Structure
telegram-bot/ ├── src/ │ ├── bot.js # Bot initialization │ ├── commands/ # Command handlers │ │ ├── start.js │ │ ├── help.js │ │ └── settings.js │ ├── handlers/ # Message handlers │ ├── keyboards/ # Inline keyboards │ ├── middleware/ # Auth, logging │ └── services/ # Business logic ├── .env └── package.json -
name: Inline Keyboards description: Interactive button interfaces when_to_use: When building interactive bot flows implementation: |
Inline Keyboards
Basic Keyboard
import { Markup } from 'telegraf'; bot.command('menu', (ctx) => { ctx.reply('Choose an option:', Markup.inlineKeyboard([ [Markup.button.callback('Option 1', 'opt_1')], [Markup.button.callback('Option 2', 'opt_2')], [ Markup.button.callback('Yes', 'yes'), Markup.button.callback('No', 'no'), ], ])); }); // Handle button clicks bot.action('opt_1', (ctx) => { ctx.answerCbQuery('You chose Option 1'); ctx.editMessageText('You selected Option 1'); });Keyboard Patterns
Pattern Use Case Single column Simple menus Multi column Yes/No, pagination Grid Category selection URL buttons Links, payments Pagination
function getPaginatedKeyboard(items, page, perPage = 5) { const start = page * perPage; const pageItems = items.slice(start, start + perPage); const buttons = pageItems.map(item => [Markup.button.callback(item.name, `item_${item.id}`)] ); const nav = []; if (page > 0) nav.push(Markup.button.callback('◀️', `page_${page-1}`)); if (start + perPage < items.length) nav.push(Markup.button.callback('▶️', `page_${page+1}`)); return Markup.inlineKeyboard([...buttons, nav]); } -
name: Bot Monetization description: Making money from Telegram bots when_to_use: When planning bot revenue implementation: |
Bot Monetization
Revenue Models
Model Example Complexity Freemium Free basic, paid premium Medium Subscription Monthly access Medium Per-use Pay per action Low Ads Sponsored messages Low Affiliate Product recommendations Low Telegram Payments
// Create invoice bot.command('buy', (ctx) => { ctx.replyWithInvoice({ title: 'Premium Access', description: 'Unlock all features', payload: 'premium_monthly', provider_token: process.env.PAYMENT_TOKEN, currency: 'USD', prices: [{ label: 'Premium', amount: 999 }], // $9.99 }); }); // Handle successful payment bot.on('successful_payment', (ctx) => { const payment = ctx.message.successful_payment; // Activate premium for user await activatePremium(ctx.from.id); ctx.reply('🎉 Premium activated!'); });Freemium Strategy
Free tier: - 10 uses per day - Basic features - Ads shown Premium ($5/month): - Unlimited uses - Advanced features - No ads - Priority supportUsage Limits
async function checkUsage(userId) { const usage = await getUsage(userId); const isPremium = await checkPremium(userId); if (!isPremium && usage >= 10) { return { allowed: false, message: 'Daily limit reached. Upgrade?' }; } return { allowed: true }; } -
name: Webhook Deployment description: Production bot deployment when_to_use: When deploying bot to production implementation: |
Webhook Deployment
Polling vs Webhooks
Method Best For Polling Development, simple bots Webhooks Production, scalable Express + Webhook
import express from 'express'; import { Telegraf } from 'telegraf'; const bot = new Telegraf(process.env.BOT_TOKEN); const app = express(); app.use(express.json()); app.use(bot.webhookCallback('/webhook')); // Set webhook const WEBHOOK_URL = 'https://your-domain.com/webhook'; bot.telegram.setWebhook(WEBHOOK_URL); app.listen(3000);Vercel Deployment
// api/webhook.js import { Telegraf } from 'telegraf'; const bot = new Telegraf(process.env.BOT_TOKEN); // ... bot setup export default async (req, res) => { await bot.handleUpdate(req.body); res.status(200).send('OK'); };Railway/Render Deployment
FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . CMD ["node", "src/bot.js"]
anti_patterns:
-
name: Blocking Operations description: Long operations blocking bot responses why_bad: | Telegram has timeout limits. Users think bot is dead. Poor experience. Requests pile up. what_to_do_instead: | Acknowledge immediately. Process in background. Send update when done. Use typing indicator.
-
name: No Error Handling description: Bot crashes on unexpected input why_bad: | Users get no response. Bot appears broken. Debugging nightmare. Lost trust. what_to_do_instead: | Global error handler. Graceful error messages. Log errors for debugging. Rate limiting.
-
name: Spammy Bot description: Sending too many messages why_bad: | Users block the bot. Telegram may ban. Annoying experience. Low retention. what_to_do_instead: | Respect user attention. Consolidate messages. Allow notification control. Quality over quantity.
handoffs:
-
trigger: "mini app|web app|TON" to: telegram-mini-app context: "Telegram Mini App integration"
-
trigger: "AI|GPT|Claude|LLM" to: ai-wrapper-product context: "AI-powered bot features"
-
trigger: "backend|database|API" to: backend context: "Backend infrastructure"
-
trigger: "payments|stripe" to: fintech-integration context: "Payment integration"