Skip to content

junioraww/keygram

Repository files navigation

Keygram

Telegram bot library for interactive panels

TypeScript Telegram Node.js

Language: [EN] [RU]

Introduction

Keygram provides wrappers for Telegram’s callback queries, making it easier to create interactive panels.
In the near future, I plan to add media caching, a plugin system, and enhanced inline_query support.

Tested in Bun and Node ecosystems, JavaScript and TypeScript

✨ Features

  • Functions “embedded” into buttons
    When creating a keyboard with callbacks, they are stored in a global store and executed whenever the callback_query is processed.
  • Built-in security
    By default, callback buttons have signatures that make it harder to forge arguments.
    This feature can be disabled: new TelegramBot({ token, signCallbacks: false })
  • Text editing
    • Use a single method ctx.edit() to edit both text and file captions. No more separate bot.editMessageText or bot.editMessageCaption calls!
    • The adaptive method ctx.respond() will either send a new message or edit the existing one (if triggered by a callback button)

There are more features and they will be documented soon. For now, you can look at examples!

🚀 Installation

Install using your preferred package manager:

# With Bun
bun add keygram

# With npm
npm install keygram

# With yarn
yarn add keygram

💡 Keyboard Example

import { TelegramBot, Panel } from "keygram"

const bot = new TelegramBot("YOUR_TOKEN")

/* Example: function is pre-defined */
const clicked = (ctx, amount = 0) => {
    const btnText = "✨ Button clicked " + amount + " times"
    const keyboard = Panel().Callback(btnText, clicked, amount + 1)

    // Use ctx.edit() to edit the message, or ctx.reply() to send a new one
    ctx.edit(`You clicked <b>the button!</b>`, keyboard)
}

const mainMenu = Panel().Callback("✨ Click me!", clicked)
                        .Row()
                        .Button("Dummy button") // No callback_data needed

bot.on('/start', ctx => ctx.reply(`Welcome, <b>${ctx.from.first_name}</b>!`, mainMenu))

bot.setParser('HTML')
bot.startPolling()

📖 Pagination Example

Pagination functions can be asynchronous, but in this example it's not using that.

import { TelegramBot, Panel, Text, Pagination } from "keygram";

const bot = new TelegramBot("YOUR_TOKEN");

const data = [1, 2, 3, 4, 5, 6, 7].map(x => ({ number: Math.random() }))

const exampleText = (ctx, data, page) =>
`Your personal numbers PikiWedia\nYou're on page ${page+1}/${ctx.maxPage}!`

// If you want to display a slice (for example, 5 elements out of 100) then
// return an array like: [ data_slice_array, total_entries_amount ]
// If you return e.g 7 out of 7 elements, then just return an array of data:
const exampleData = (ctx, page) => data

const exampleKeys = (_, data, page) => 
    Panel().Add(data.map(({ number }) => [ Text("Float " + number.toFixed(4)) ]))

const close = ctx => ctx.delete()
const closeKeys = ctx => Panel().Callback("Close panel", close)

const pages = new Pagination("numbers").Text(exampleText)
                                       .Data(exampleData)
                                       .Keys(exampleKeys)
                                       .AfterKeys(closeKeys)
                                       .PageSize(3)

bot.on('/start', ctx => ctx.open(pages));

bot.startPolling()

📚 More examples

🗺️ Roadmap & Milestones

Milestones (v0.3.0)

  • Pagination: Add a ready-to-use class for an interactive panel with pages
  • Scenes: Add a scene system for multi-step interactions
  • Optimisations: Refactor the core with best practices in mind! XP

Future Plans

  • Persistent Callbacks: Add PersistentCallback to restore functions on startup
  • Cached Assets: Add classes like CachedImage for better media handling
  • More helpers: Simplify common Telegram Bot API tasks

About

Experimental bot library for interactive panels

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published