JSPM

sotele-hub

1.0.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1
  • Score
    100M100P100Q9896F
  • License MIT

A comprehensive, single-file TypeScript library for Telegram bot development with socket-like architecture

Package Exports

  • sotele-hub

Readme

# soTeleHub

[![npm version](https://badge.fury.io/js/sotele-hub.svg)](https://badge.fury.io/js/sotele-hub)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)

> A comprehensive, **single-file** TypeScript library for Telegram bot development with socket-like architecture, similar to WhatsApp Baileys.

## ✨ Features

- 🚀 **Socket-like Architecture** - Event-driven design similar to Baileys
- 📘 **Full TypeScript Support** - Complete type definitions 
- 📄 **Single File** - Everything in one file, easy to use
- 🔧 **Zero Dependencies** - No external dependencies required
- 🎯 **Easy to Use** - Simple and intuitive API
- 🔌 **Plugin System** - Extensible architecture
- 💬 **Conversation Flow** - Built-in conversation management
- 🛡️ **Rate Limiting** - Anti-spam protection
- 🔄 **Auto Retry** - Robust error handling
- 📱 **Polling & Webhooks** - Support for both methods

## 🚀 Quick Start

### Installation

```bash
npm install sotele-hub
# or
yarn add sotele-hub

Basic Usage

import { createBot } from 'sotele-hub';

const bot = createBot('YOUR_BOT_TOKEN');

// Handle text messages
bot.on('text', (message) => {
  console.log('Received:', message.text);
  bot.reply(message, 'Hello!');
});

// Handle commands
bot.command('start', (message) => {
  bot.reply(message, 'Welcome to my bot!');
});

// Start polling
bot.startPolling();

Advanced Example

import { createBot, inlineKeyboard } from 'sotele-hub';

const bot = createBot('YOUR_BOT_TOKEN', {
  timeout: 30000,
  retryDelay: 1000,
  maxRetries: 3
});

// Middleware
bot.use(async (update, bot) => {
  console.log('Processing update:', update.update_id);
  return true; // Continue processing
});

// Inline keyboards
bot.command('keyboard', (message) => {
  const keyboard = inlineKeyboard()
    .text('Button 1', 'btn1')
    .text('Button 2', 'btn2')
    .row()
    .url('Website', 'https://example.com')
    .build();
  
  bot.replyWithKeyboard(message, 'Choose:', keyboard);
});

// Callback queries
bot.on('callback_query', (query) => {
  bot.answerCallbackQuery({
    callback_query_id: query.id,
    text: `You clicked: ${query.data}`
  });
});

// Sessions
bot.command('count', (message) => {
  const session = bot.getSession(message.chat.id);
  session.count = (session.count || 0) + 1;
  bot.setSession(message.chat.id, session);
  
  bot.reply(message, `Count: ${session.count}`);
});

// Conversations
bot.command('ask', (message) => {
  bot.reply(message, 'What is your name?');
  
  bot.startConversation(message.chat.id, async (msg, bot) => {
    await bot.reply(msg, `Nice to meet you, ${msg.text}!`);
    return 'end';
  });
});

bot.startPolling();

📖 API Reference

Core Methods

Bot Creation

import { createBot, SoTeleHub } from 'sotele-hub';

const bot = createBot(token: string, options?: BotConfig);
// or
const bot = new SoTeleHub({ token, ...options });

Messaging

// Send messages
await bot.sendMessage({ chat_id, text });
await bot.sendPhoto({ chat_id, photo });
await bot.sendDocument({ chat_id, document });

// Reply helpers
await bot.reply(message, 'Hello!');
await bot.replyWithPhoto(message, photo);
await bot.replyWithKeyboard(message, text, keyboard);

Events

// Message events
bot.on('text', (message) => {});
bot.on('photo', (message) => {});
bot.on('callback_query', (query) => {});

// Commands
bot.command('start', (message) => {});
bot.onText(/\/echo (.+)/, (message, match) => {});

Keyboards

import { inlineKeyboard, replyKeyboard } from 'sotele-hub';

// Inline keyboard
const inline = inlineKeyboard()
  .text('Button', 'data')
  .url('Link', 'https://example.com')
  .build();

// Reply keyboard
const reply = replyKeyboard()
  .text('Home')
  .requestLocation('📍 Location')
  .resize()
  .build();

Sessions & Conversations

// Sessions
const session = bot.getSession(chatId);
bot.setSession(chatId, data);
bot.clearSession(chatId);

// Conversations
bot.startConversation(chatId, handler);
bot.endConversation(chatId);

🔌 Plugin System

// Create custom plugin
const myPlugin = {
  install(bot) {
    bot.use(async (update) => {
      // Custom logic
      return true;
    });
  }
};

bot.addPlugin('myPlugin', myPlugin);

🛠️ Utilities

import { 
  escapeMarkdown, 
  escapeHTML, 
  mention, 
  formatDuration,
  validateToken 
} from 'sotele-hub';

const escaped = escapeMarkdown('Hello *world*!');
const userMention = mention(user, 'HTML');
const isValid = validateToken(token);

📱 Webhook Support

const express = require('express');
const { createBot } = require('sotele-hub');

const app = express();
const bot = createBot(process.env.BOT_TOKEN);

app.use(express.json());

app.post('/webhook', (req, res) => {
  bot.emit('update', req.body);
  res.sendStatus(200);
});

// Set webhook
await bot.setWebhook({ url: 'https://yourdomain.com/webhook' });

app.listen(3000);

🔧 Configuration

interface BotConfig {
  token: string;
  baseUrl?: string;          // Default: 'https://api.telegram.org'
  timeout?: number;          // Default: 30000
  retryDelay?: number;       // Default: 1000
  maxRetries?: number;       // Default: 3
  allowedUpdates?: string[]; // Default: []
}

📝 Examples

Check out the examples/ folder for more comprehensive examples:

  • basic-bot.js - Simple echo bot
  • advanced-bot.js - Bot with keyboards and sessions
  • typescript-bot.ts - TypeScript example with full typing

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

MIT © Your Name

🆚 Comparison with Other Libraries

Feature soTeleHub node-telegram-bot-api telegraf
TypeScript ✅ Full support ❌ Community types ✅ Built-in
Single File ✅ Yes ❌ No ❌ No
Socket-like ✅ Yes ❌ No ❌ No
Zero Deps ✅ Yes ❌ No ❌ No
Size 🟢 Small 🟡 Medium 🔴 Large
Learning Curve 🟢 Easy 🟡 Medium 🔴 Hard

🚀 Why soTeleHub?

  1. Single File: Everything you need in one file - no complex folder structures
  2. Socket-like: Familiar event-driven architecture like Baileys for WhatsApp
  3. TypeScript First: Built with TypeScript, full type safety out of the box
  4. Zero Dependencies: No external dependencies, smaller bundle size
  5. Comprehensive: All Telegram Bot API features covered
  6. Easy Migration: Simple to migrate from other libraries

Made with ❤️ by developers, for developers.


## 🔨 scripts/build-esm.js

```javascript
const fs = require('fs');
const path = require('path');

// Convert CJS to ESM
function convertToESM(dir) {
  if (!fs.existsSync(dir)) return;
  
  const files = fs.readdirSync(dir);
  
  files.forEach(file => {
    const filePath = path.join(dir, file);
    const stat = fs.statSync(filePath);
    
    if (stat.isDirectory()) {
      convertToESM(filePath);
    } else if (file.endsWith('.js')) {
      let content = fs.readFileSync(filePath, 'utf8');
      
      // Convert exports
      content = content.replace(/exports\./g, 'export ');
      content = content.replace(/module\.exports\s*=\s*/g, 'export default ');
      
      // Convert require statements
      content = content.replace(
        /const\s+(.+?)\s+=\s+require\(['"](.+?)['"]\)/g,
        'import $1 from "$2"'
      );
      
      // Rename to .esm.js
      const esmPath = filePath.replace('.js', '.esm.js');
      fs.writeFileSync(esmPath, content);
      fs.unlinkSync(filePath);
    }
  });
}

// Create ESM build
convertToESM('dist/esm');

// Create package.json for ESM
const esmPackage = { type: 'module' };
fs.writeFileSync('dist/esm/package.json', JSON.stringify(esmPackage, null, 2));

console.log('✅ ESM build created successfully');

📄 examples/basic-bot.js

const { createBot } = require('sotele-hub');

const bot = createBot(process.env.BOT_TOKEN);

// Basic echo bot
bot.on('text', (message) => {
  if (!message.text.startsWith('/')) {
    bot.reply(message, `You said: ${message.text}`);
  }
});

bot.command('start', (message) => {
  bot.reply(message, '👋 Hello! Send me any message and I will echo it back.');
});

bot.command('help', (message) => {
  const helpText = `
🤖 **Bot Commands:**

/start - Start the bot
/help - Show this help
/ping - Check if bot is alive
/info - Show your info

Just send me any text and I'll echo it back!
  `;
  bot.reply(message, helpText);
});

bot.command('ping', (message) => {
  bot.reply(message, '🏓 Pong! Bot is alive and working.');
});

bot.command('info', (message) => {
  const info = `
👤 **Your Information:**
• Name: ${message.from.first_name} ${message.from.last_name || ''}
• Username: ${message.from.username ? '@' + message.from.username : 'None'}
• ID: \`${message.from.id}\`
• Chat Type: ${message.chat.type}
  `;
  bot.reply(message, info);
});

// Start the bot
bot.startPolling()
  .then(() => {
    console.log('✅ Bot started successfully!');
  })
  .catch((error) => {
    console.error('❌ Failed to start bot:', error);
  });

📄 examples/advanced-bot.js

const { createBot, inlineKeyboard, replyKeyboard } = require('sotele-hub');

const bot = createBot(process.env.BOT_TOKEN, {
  timeout: 30000,
  retryDelay: 1000
});

// Middleware for logging
bot.use(async (update) => {
  console.log(`📩 Update ${update.update_id} received`);
  return true;
});

// Start command with reply keyboard
bot.command('start', (message) => {
  const keyboard = replyKeyboard()
    .text('📊 Stats').text('⚙️ Settings')
    .row()
    .text('🎮 Games').text('❓ Help')
    .resize()
    .build();

  bot.replyWithKeyboard(message, '🎉 Welcome! Choose an option:', keyboard);
});

// Handle reply keyboard responses
bot.on('text', (message) => {
  if (message.text && !message.text.startsWith('/')) {
    switch (message.text) {
      case '📊 Stats':
        bot.reply(message, '📈 Your stats: Messages sent: 42, Commands used: 15');
        break;
      case '⚙️ Settings':
        showSettings(message);
        break;
      case '🎮 Games':
        showGames(message);
        break;
      case '❓ Help':
        bot.reply(message, '💡 Use the keyboard buttons or type /help for commands.');
        break;
    }
  }
});

// Settings with inline keyboard
function showSettings(message) {
  const keyboard = inlineKeyboard()
    .text('🔔 Notifications', 'setting_notifications')
    .text('🌙 Theme', 'setting_theme')
    .row()
    .text('🌐 Language', 'setting_language')
    .text('🔒 Privacy', 'setting_privacy')
    .row()
    .text('« Back to Menu', 'back_menu')
    .build();

  bot.replyWithKeyboard(message, '⚙️ Settings Panel:', keyboard);
}

// Games menu
function showGames(message) {
  const keyboard = inlineKeyboard()
    .text('🎲 Dice', 'game_dice')
    .text('🎯 Darts', 'game_darts')
    .row()
    .text('🏀 Basketball', 'game_basketball')
    .text('⚽ Football', 'game_football')
    .row()
    .text('« Back to Menu', 'back_menu')
    .build();

  bot.replyWithKeyboard(message, '🎮 Choose a game:', keyboard);
}

// Handle callback queries
bot.on('callback_query', (query) => {
  const data = query.data;

  bot.answerCallbackQuery({
    callback_query_id: query.id,
    text: `Selected: ${data.replace('_', ' ')}`
  });

  switch (data) {
    case 'setting_notifications':
      bot.sendMessage({
        chat_id: query.message.chat.id,
        text: '🔔 Notifications are currently: ON\nToggle with /notifications'
      });
      break;

    case 'game_dice':
      bot.sendDice({ chat_id: query.message.chat.id, emoji: '🎲' });
      break;

    case 'game_darts':
      bot.sendDice({ chat_id: query.message.chat.id, emoji: '🎯' });
      break;

    case 'back_menu':
      bot.command('start', query.message);
      break;
  }
});

// Session-based counter
bot.command('count', (message) => {
  const session = bot.getSession(message.chat.id);
  session.count = (session.count || 0) + 1;
  bot.setSession(message.chat.id, session);
  
  bot.reply(message, `🔢 Counter: ${session.count}\nUse /reset to reset counter.`);
});

bot.command('reset', (message) => {
  bot.clearSession(message.chat.id);
  bot.reply(message, '🔄 Counter reset to 0!');
});

// Conversation example
bot.command('feedback', (message) => {
  bot.reply(message, '💬 Please send your feedback message:');
  
  bot.startConversation(message.chat.id, async (msg, bot) => {
    const feedback = msg.text;
    
    // Save feedback (in real app, save to database)
    console.log(`Feedback from ${msg.from.first_name}: ${feedback}`);
    
    await bot.reply(msg, '✅ Thank you for your feedback! It has been recorded.');
    return 'end';
  });
});

// Error handling
bot.on('polling_error', (error) => {
  console.error('❌ Polling error:', error);
});

// Start the bot
bot.startPolling()
  .then(() => {
    console.log('🚀 Advanced bot started successfully!');
  })
  .catch(console.error);

🚀 Quick Setup Commands

# Create project
mkdir my-telegram-bot && cd my-telegram-bot

# Initialize npm
npm init -y

# Install dependencies
npm install typescript ts-node @types/node --save-dev
npm install rimraf prettier eslint --save-dev

# Install soTeleHub (after publishing)
npm install sotele-hub

# Create bot file
echo "import { createBot } from 'sotele-hub';

const bot = createBot(process.env.BOT_TOKEN!);

bot.command('start', (message) => {
  bot.reply(message, 'Hello from soTeleHub! 🚀');
});

bot.startPolling().then(() => {
  console.log('Bot started!');
});" > bot.ts

# Add to package.json scripts
npm pkg set scripts.dev="ts-node bot.ts"
npm pkg set scripts.build="tsc"

# Set bot token and run
export BOT_TOKEN="your_bot_token_here"
npm run dev

Perfect! Sekarang soTeleHub sudah menjadi single file library yang mudah digunakan dan siap untuk dipublish ke NPM! 🎉

🎯 Keunggulan Single File Version:

  1. ✅ Satu File Aja - Semua dalam src/index.ts, mudah maintain
  2. ✅ Zero Dependencies - Tidak butuh dependency external
  3. ✅ TypeScript Native - Full type support
  4. ✅ Socket-like Architecture - Mirip Baileys
  5. ✅ Comprehensive - Semua fitur Telegram Bot API
  6. ✅ Easy Setup - Tinggal npm install sotele-hub

🚀 Cara Publish:

# Setup project
mkdir sotele-hub && cd sotele-hub
# Copy all files above

# Install dev dependencies
npm install

# Build
npm run build

# Test locally
npm pack

# Publish to NPM
npm login
npm publish --access public

Setelah publish, developer bisa langsung pakai:

npm install sotele-hub
const { createBot } = require('sotele-hub');
const bot = createBot('TOKEN');
bot.command('start', msg => bot.reply(msg, 'Hello!'));
bot.startPolling();