Skip to content

Hrafngud/teleframer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Telegram Bot Framework Documentation

This documentation provides a clear and structured guide to building and managing bots using the custom Telegram bot framework. The framework focuses on flexibility, scalability, and adherence to best practices like the DRY (Don't Repeat Yourself) and SOLID principles.

The framework allows developers to easily create new features and integrate them seamlessly. To demonstrate its capabilities, an example feature, fruits, is included.

Key Features of the Framework

  1. Dynamic Command Registration: Features can be added to the framework by registering them in a single featureRegistry object.
  2. Agnostic Input and Output Handling: Handlers for messages, commands, and button presses are decoupled from feature logic.
  3. Dynamic Main Menu: The main menu buttons are generated automatically based on registered features.
  4. Error Handling: Built-in mechanisms to catch and handle errors gracefully in commands, messages, and button presses.
  5. Extensibility: Adding new features is simple and does not require modifications to the core framework logic.
  6. Encapsulation: Features manage their own state independently, ensuring modularity and ease of debugging.

Framework Architecture

Core Components

  1. Input Handler (``) Handles commands, button presses, and messages agnostically. It prevents duplicate processing and ensures that each input is routed correctly to the respective feature.

  2. Output Handler (``) Provides utilities for sending messages and buttons to users, abstracting Telegram Bot API specifics.

  3. Feature Registry Maps commands to their respective feature start functions, enabling dynamic command handling and menu generation.

  4. Main Bot File The central file (bot.js) initializes the bot, registers handlers, and manages the main menu generation and /start command.

Example Feature: Fruits

The fruits feature serves as an example to demonstrate how to implement a custom feature within the framework. It guides users through a flow of collecting five fruit names and then allows them to select their favorite from a dynamically generated menu.

Implementation Details

Input Handler (input.js)

let isStartHandled = false; // Tracks if /start has been handled

function handleCommand(bot, chatId, command) {
  try {
    console.log(`Command received: ${command}`);

    if (command === '/start' && isStartHandled) {
      console.log('Skipping /start as it has already been handled.');
      return;
    }

    if (command === '/start') {
      isStartHandled = true;
    }

    // Command-specific logic can go here
  } catch (error) {
    console.error('Error handling command:', error);
    bot.sendMessage(chatId, 'An error occurred while processing your command.');
  }
}

function handleButton(bot, chatId, data) {
  try {
    console.log(`Button pressed with data: ${data}`);
    // Button-specific logic can go here
  } catch (error) {
    console.error('Error handling button press:', error);
    bot.sendMessage(chatId, 'An error occurred while processing your choice.');
  }
}

function handleMessage(bot, chatId, text) {
  try {
    console.log(`Message received: ${text}`);
    // Message-specific logic can go here
  } catch (error) {
    console.error('Error handling message:', error);
    bot.sendMessage(chatId, 'An error occurred while processing your message.');
  }
}

module.exports = {
  handleCommand,
  handleButton,
  handleMessage,
};

Output Handler (output.js)

function sendMessage(bot, chatId, text) {
  try {
    bot.sendMessage(chatId, text);
  } catch (error) {
    console.error('Error sending message:', error);
    bot.sendMessage(chatId, 'An error occurred while sending a message.');
  }
}

function sendButtons(bot, chatId, text, buttons) {
  try {
    bot.sendMessage(chatId, text, {
      reply_markup: {
        inline_keyboard: buttons,
      },
    });
  } catch (error) {
    console.error('Error sending buttons:', error);
    bot.sendMessage(chatId, 'An error occurred while sending buttons.');
  }
}

module.exports = {
  sendMessage,
  sendButtons,
};

Example Feature: Fruits (fruits.js)

const input = require('../handlers/input');
const output = require('../handlers/output');

let fruits = [];
let activeFruitsFlow = {}; // Tracks active fruit collection flows by user

function start(bot, chatId) {
  fruits = []; // Reset fruits on start
  activeFruitsFlow[chatId] = true; // Mark this user as in the fruit collection flow
  output.sendMessage(bot, chatId, 'Please type the name of a fruit. I need 5 in total.');
}

function handleFruitInput(bot, chatId, text) {
  if (activeFruitsFlow[chatId] && fruits.length < 5) {
    fruits.push(text);
    const remaining = 5 - fruits.length;

    if (remaining > 0) {
      output.sendMessage(bot, chatId, `Got it! Please type another fruit (${remaining} more to go).`);
    } else {
      const buttons = fruits.map((fruit) => [
        { text: fruit, callback_data: fruit },
      ]);
      output.sendButtons(bot, chatId, 'Thanks! Choose one of your favorite fruits:', buttons);
    }
  } else if (fruits.length >= 5) {
    output.sendMessage(bot, chatId, 'You already provided 5 fruits. Please choose one from the buttons.');
  } else {
    output.sendMessage(bot, chatId, 'Something went wrong. Please try again.');
  }
}

function handleButtonPress(bot, chatId, data) {
  if (activeFruitsFlow[chatId]) {
    output.sendMessage(bot, chatId, `You chose: ${data}`);
    fruits = [];
    activeFruitsFlow[chatId] = false; // End the fruit collection process
  }
}

function isFruitCollectionActive(chatId) {
  return activeFruitsFlow[chatId] === true;
}

module.exports = {
  start,
  handleFruitInput,
  handleButtonPress,
  isFruitCollectionActive,
};

Adding a New Feature

To add a new feature:

  1. Create a new file in the features directory (e.g., myFeature.js).
  2. Implement the feature logic (e.g., handling messages, commands, or buttons).
  3. Register the feature in the featureRegistry in the main bot file (bot.js).
  4. Test the feature to ensure it integrates seamlessly with the framework.

Conclusion

This framework provides a robust and extensible foundation for building Telegram bots. The fruits feature demonstrates its capabilities, but you can easily extend it with custom features to suit your needs. By adhering to clean coding principles, this framework ensures maintainability and scalability for projects of any size.

About

A framework for creating telegram bots easily.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors