PHPackages                             reymon/tg-keyboard - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. reymon/tg-keyboard

ActiveLibrary[API Development](/categories/api)

reymon/tg-keyboard
==================

An easy keyboard builder for Telegram Api &amp; Mtproto syntax

5.0.0(2mo ago)359[1 PRs](https://github.com/reymontg/tg-keyboard/pulls)GPL-3.0-onlyPHPCI passing

Since Jul 25Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/reymontg/tg-keyboard)[ Packagist](https://packagist.org/packages/reymon/tg-keyboard)[ RSS](/packages/reymon-tg-keyboard/feed)WikiDiscussions main Synced today

READMEChangelog (8)Dependencies (8)Versions (10)Used By (0)

tg-keyboard
===========

[](#tg-keyboard)

A keyboard builder for Telegram Api &amp; Mtproto syntax

 Table of Contents1. [Installation](#installation)
2. [Usage](#usage)
    1. [Defining a Keyboard](#defining-a-keyboard)
    2. [Defining Buttons](#defining-buttons)
    3. [Bind Buttons to a Keyboard](#bind-buttons-to-a-keyboard)
        1. [By Row](#by-row)
        2. [By Button](#by-button)
        3. [By Coordinates](#by-coordinates)
        4. [As Stack](#as-stack)
    4. [KeyboardForceReply and KeyboardHide](#keyboardforcereply-and-keyboardhide)
    5. [Keyboard Peer Type](#keyboard-peer-type)
    6. [Convert To Api &amp; Mtproto Keyboard (and the opposite)](#convert-keyboards)
        1. [Telegram API](#telegram-api)
        2. [Mtproto](#mtproto)

Installation
------------

[](#installation)

Install the package using composer:

```
composer require reymon/tg-keyboard
```

([back to top](#top))

Usage
-----

[](#usage)

If you need to create a keyboard you can use the classes provided by this package as a drop-in replacement.

This is best explained with an example:

```
KeyboardMarkup::new()
        ->singleUse()
        ->addButton(KeyboardButton::Text('Cancel'))
        ->addButton(KeyboardButton::Text('OK'));
```

A ReplyKeyboardMarkup is created by calling the static `new()` method on `KeyboardMarkup`. After that every field, like `singleUse`, ... add some extras. Buttons can be added by calling the `addButton()` method. We have a detailed look on that later.

([back to top](#top))

### Defining a Keyboard

[](#defining-a-keyboard)

You can create a keyboard by calling the static `new()` method on its class.

After that you can chain methods to set additional fields that are available in the Bot API. This is done by calling the `placeholder()` method.

```
KeyboardMarkup::new()
    ->placeholder('Placeholder');
```

([back to top](#top))

### Defining Buttons

[](#defining-buttons)

The Buttons are created in the different way:

```
$button = KeyboardButton::Phone('Send my Contact');
$button->getText();
$button->setText('Give me contact');
```

This is done the same way for `InlineButton`:

```
$button = InlineButton::Url('hello','https://example.com');
$button->getUrl();
$button->setUrl('github.com');
```

([back to top](#top))

### Bind Buttons to a Keyboard

[](#bind-buttons-to-a-keyboard)

The keyboard does not work without any buttons, so you need to pass the buttons to the keyboard. There are a few ways to do this.

#### By Row

[](#by-row)

```
KeyboardMarkup::new()
    ->row(
        KeyboardButton::Text('Cancel'),
        KeyboardButton::Text('OK')
    );
```

If you need more than one row, call `row()` multiple times:

```
KeyboardInline::new()
    ->row(
        InlineButton::Callback('1', 'page-1'),
        InlineButton::Callback('2', 'page-2'),
        InlineButton::Callback('3', 'page-3')
    )
    ->row(
        InlineButton::Callback('prev', 'page-prev'),
        InlineButton::Callback('next', 'page-next')
    );
```

You can add array of callbacks or texts keyboard in another way!

```
KeyboardInline::new()
    ->addCallbacks([
        '1' => 'page-1',
        '2' => 'page-2',
        '3' => 'page-3',
    ],[
        'prev' => 'page-prev',
        'next' => 'page-next'
    ]);
```

```
KeyboardMarkup::new()
    ->addTexts([
       'Cancel',
       'Ok'
    ]);
```

You can even use these methods

for InlineKeyboard:

- [addCallback](src/Keyboard/KeyboardInline.php#L37)
- [addCallbacks](src/Keyboard/KeyboardInline.php#L47)
- [addCopyText](src/Keyboard/KeyboardInline.php#L62)
- [addUrl](src/Keyboard/KeyboardInline.php#L73)
- [addWebApp](src/Keyboard/KeyboardInline.php#L84)
- [addLoginUrl](src/Keyboard/KeyboardInline.php#L98)
- [addGame](src/Keyboard/KeyboardInline.php#L108)
- [addBuy](src/Keyboard/KeyboardInline.php#L118)
- [addSwitchInline](src/Keyboard/KeyboardInline.php#L129)
- [addSwitchInlineCurrent](src/Keyboard/KeyboardInline.php#L140)
- [addSwitchInlineFilter](src/Keyboard/KeyboardInline.php#L155)

and for ReplyKeyboard:

- [addText](src/Keyboard/KeyboardMarkup.php#L74)
- [addTexts](src/Keyboard/KeyboardMarkup.php#L84)
- [addWebApp](src/Keyboard/KeyboardMarkup.php#L99)
- [requestPoll](src/Keyboard/KeyboardMarkup.php#L109)
- [requestPollQuiz](src/Keyboard/KeyboardMarkup.php#L119)
- [requestPollRegular](src/Keyboard/KeyboardMarkup.php#L129)
- [requestLocation](src/Keyboard/KeyboardMarkup.php#L139)
- [requestPhone](src/Keyboard/KeyboardMarkup.php#L149)
- [requestUsers](src/Keyboard/KeyboardMarkup.php#L166)
- [requestGroup](src/Keyboard/KeyboardMarkup.php#L186)
- [requestChannel](src/Keyboard/KeyboardMarkup.php#L205)

#### By Button

[](#by-button)

```
KeyboardMarkup::new()
    ->addButton(KeyboardButton::Text('First Button'))
    ->addButton(KeyboardButton::Text('Second Button'));
```

If you need more than one row, just call the row method without arguments, and continue calling `addButton()`:

```
KeyboardInline::new()
    ->addButton(
        InlineButton::Callback('A','answer-a'),
        InlineButton::Callback('B','answer-b')
    )
    ->row()
    ->addButton(
        InlineButton::Callback('C', 'answer-c'),
        InlineButton::Callback('D', 'answer-d')
    );
```

It's up to you if you define your buttons inline like in these examples or if you'd like to generate a whole row beforehand and pass the variable to the `row()` method.

You can remove the last button by calling `remove` method here is an example :

```
KeyboardInline::new()
    ->addButton(InlineButton::Callback('A', 'answer-a'))
    ->addButton(InlineButton::Callback('B', 'answer-b'))
    ->row()
    ->addButton(InlineButton::Callback('C', 'answer-c'))
    ->addButton(InlineButton::Callback('D', 'answer-d'))
    ->remove();
```

In this example button D will remove from buttons.

#### By Coordinates

[](#by-coordinates)

You can add button to each coordinates you want! (Note that coordinates start from 0 just like array indexes.) for example imagine we have this keyboard :

```
$keyboard = KeyboardInline::new()
    ->addButton(InlineButton::Callback('Numbers', 'Numbers'))
    ->addButton(InlineButton::Callback('Status', 'Status'))
    ->row()
    ->addButton(InlineButton::Callback('Add', 'Add'))
    ->addButton(InlineButton::Callback('Remove', 'Remove'));
```

we can add new button with it coordinates(raw and column) by calling `addToCoordinates` method. This methods will add new button in the coordinate that you passed and shift next buttons of the coordinates. This picture show you the position of new button :

[![addToCoordinates](./assets/add-to-coordinates.png)](./assets/add-to-coordinates.png)

```
$keyboard->addToCoordinates(0, 1, InlineButton::Callback('Middle','Middle'));
```

The results should like this image :

[![addToCoordinatesResult](./assets/add-to-coordinates-result.png)](./assets/add-to-coordinates-result.png)

You can also replace into specific coordinates unlike `addToCoordinates` the `replaceIntoCoordinates` method will replace your new button into passed coordinate for example if we want to replace Add in this example like this picture :

[![replaceIntoCoordinates](./assets/replace-Into-coordinates.png)](./assets/replace-Into-coordinates.png)

we should use this code :

```
$keyboard->replaceIntoCoordinates(1, 0, InlineButton::Callback('Replaced Add','Add'));
```

The result should like this image :

[![replaceIntoCoordinatesResult](./assets/replace-Into-coordinates-result.png)](./assets/replace-Into-coordinates-result.png)

You can also remove the button by it's coordinates for example if we want remove Add button(in last example) we should run this code:

```
$keyboard->removeFromCoordinates(1,0);
```

#### As Stack

[](#as-stack)

If you want to add a bunch of buttons that have each a row for themselves you can use the `Stack()` method.

```
KeyboardInline::new()
    ->Stack(
        InlineButton::LoginUrl('Login','https://example.com/login'),
        InlineButton::Url('Visit Homepage','https://example.com')
    );
```

**You can mix and match the `row()`, `Stack()` and `addButton()` methods as it fits your needs.**

([back to top](#top))

### KeyboardForceReply and KeyboardHide

[](#keyboardforcereply-and-keyboardhide)

KeyboardForceReply and KeyboardHide can be used the same way as a normal keyboard, but they do not receive any buttons:

```
$keyboard = KeyboardHide::new();
```

```
KeyboardForceReply::new()
    ->addButton(KeyboardButton::Text('Hello please reply'))
    ->placeholder('must reply');
```

([back to top](#top))

### Keyboard Peer Type

[](#keyboard-peer-type)

We have 3 types of peer type can be requested by bots RequestUsers , RequestGroup and RequestChannel

```
KeyboardMarkup::new()
    ->addButton(KeyboardButton::PeerUsers('Request for user', 0, bot: false));
```

```
KeyboardMarkup::new()
    ->addButton(KeyboardButton::PeerGroup('Request for chat', 1));
```

```
KeyboardMarkup::new()
    ->addButton(KeyboardButton::PeerChannel('Request for channel', 2));
```

**You can also use easier syntax to create better one**

```
KeyboardMarkup::new()
    ->requestUsers('Request for user', 0);
```

```
KeyboardMarkup::new()
    ->requestGroup('Request for chat', 1);
```

```
KeyboardMarkup::new()
    ->requestChannel('Request for broadcast', 2);
```

([back to top](#top))

### Convert Keyboards

[](#convert-keyboards)

You can now easily convert telegram keyboards for modify and ... using `fromBotApi` or `fromMtproto` (for [MadelineProto](https://docs.madelineproto.xyz/)) methods!

Here is an example

(for now `fromBotApi` only accepts inline keyboards)

#### **Telegram API**

[](#telegram-api)

```
$keyboard = Keyboard::fromBotApi([
    "inline_keyboard": [
        [
            ["text" => "Callback data", "callback_data" => "Some data"]
        ],
        [
            [ "text" => "Hide keyboard", "callback_data" => "HIDE"]
        ]
    ]
]);
$keyboard->addButton(InlineButton::Callback('End','End'));
// Convert to mtproto syntax
$keyborad->toMtproto();
```

#### **Mtproto**

[](#mtproto)

```
$keyboard = Keyboard::fromMtproto([
    '_' => 'replyInlineMarkup',
    'rows' => [
        [
            '_' => 'keyboardButtonRow',
            'buttons' => [
                ['_' => 'keyboardButtonCallback', 'text' => '1', 'data' => '0'],
                ['_' => 'keyboardButtonCallback', 'text' => '2', 'data' => '1'],
                ['_' => 'keyboardButtonCallback', 'text' => '🟢', 'data' => 'stat'],
                ['_' => 'keyboardButtonCallback', 'text' => '3', 'data' => '2'],
                ['_' => 'keyboardButtonCallback', 'text' => '4', 'data' => '3']
            ]
        ],
        [
            '_' => 'keyboardButtonRow',
            'buttons' => [
                ['_' => 'keyboardButtonCallback', 'text' => '10', 'data' => '9'],
                ['_' => 'keyboardButtonCallback', 'text' => '11', 'data' => '10'],
                ['_' => 'keyboardButtonCallback', 'text' => '12', 'data' => '11'],

            ]
        ],
        [
            '_' => 'keyboardButtonRow',
            'buttons' => [
                ['_' => 'keyboardButtonCallback','text' => '13', 'data' => '12'],
                ['_' => 'keyboardButtonCallback','text' => '14', 'data' => '13']
            ]
        ]
    ],
]);
$keyboard->addButton(InlineButton::Callback('15','14'));
// Convert to telegram api syntax
$keyborad->toApi();
json_encode($keyborad);
```

As you know `$keyboard` is object here and you can modify and add more buttons to it. Or event iterate it!:

```
foreach ($keyboard as $row) {
    foreach ($row as $button) {
        printf("Text: %s Callback: %s", $button->getText(), $button->getCallback());
    }
}
```

([back to top](#top))

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance88

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 86% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~36 days

Recently: every ~59 days

Total

8

Last Release

88d ago

Major Versions

4.6.0 → 5.0.02026-04-06

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/107793906?v=4)[AhJ](/maintainers/ahjdev)[@ahjdev](https://github.com/ahjdev)

---

Top Contributors

[![ahjdev](https://avatars.githubusercontent.com/u/107793906?v=4)](https://github.com/ahjdev "ahjdev (154 commits)")[![mtalaeii](https://avatars.githubusercontent.com/u/73236713?v=4)](https://github.com/mtalaeii "mtalaeii (24 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

---

Tags

apibuilderbottelegrammtprototelegram apikeyboardmadelineproto

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/reymon-tg-keyboard/health.svg)

```
[![Health](https://phpackages.com/badges/reymon-tg-keyboard/health.svg)](https://phpackages.com/packages/reymon-tg-keyboard)
```

###  Alternatives

[phptg/bot-api

PHP library for working with Telegram API

12716.4k7](/packages/phptg-bot-api)[php-telegram-bot/fluent-keyboard

Fluent Keyboard builder for ReplyKeyboardMarkup and InlineKeyboardMarkup.

131.1k](/packages/php-telegram-bot-fluent-keyboard)[borsaco/telegram-bot-api-bundle

A simple wrapper for telegram-bot-api.

5633.6k](/packages/borsaco-telegram-bot-api-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
