PHPackages                             easy-keyboard/fluent-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. easy-keyboard/fluent-keyboard

ActiveLibrary

easy-keyboard/fluent-keyboard
=============================

A fluent keyboard created for MTProto syntax

2.1.1(1y ago)299MITPHP

Since Jul 18Pushed 1y ago3 watchersCompare

[ Source](https://github.com/mtalaeii/fluent-keyboard)[ Packagist](https://packagist.org/packages/easy-keyboard/fluent-keyboard)[ RSS](/packages/easy-keyboard-fluent-keyboard/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (3)Versions (16)Used By (0)

fluent-keyboard
===============

[](#fluent-keyboard)

A fluent keyboard created for 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 Telegram Keyboard To Fluent Keyboard](#convert-telegram-keyboard-to-fluent-keyboard)

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

[](#installation)

Install the package using composer:

```
composer require easy-keyboard/fluent-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:

```
$this->messages->sendMessage(
    chat_id:       12345,
    text:          'Keyboard Example',
    reply_markup:  KeyboardMarkup::new()
        ->singleUse()
        ->addButton(KeyboardButton::Text('Cancel'))
        ->addButton(KeyboardButton::Text('OK'))
        ->build()
);
```

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.(note that this keyboard need to convert to array to readable by your robot so at the end you need to call `init()` method)

([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')
    ->build();
```

([back to top](#top))

### Defining Buttons

[](#defining-buttons)

The Buttons are created in the different way:

```
KeyboardButton::Phone('Send my Contact');
```

This is done the same way for `InlineButton`:

```
InlineButton::Url('hello', 'https://example.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')
    )
    ->build();
```

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')
    )
    ->build();
```

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'
    ])
    ->build();
```

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

#### By Button

[](#by-button)

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

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'))
    ->addButton(InlineButton::Callback('B', 'answer-b'))
    ->row()
    ->addButton(InlineButton::Callback('C', 'answer-c'))
    ->addButton(InlineButton::Callback('D', 'answer-d'))
    ->build();
```

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()
    ->build();
```

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 :

[![Screenshot_20230907_212829](https://private-user-images.githubusercontent.com/73236713/266403226-89c0427e-c1c1-4fa2-8a2b-6d13ecf92286.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzU2Mjk1OTgsIm5iZiI6MTc3NTYyOTI5OCwicGF0aCI6Ii83MzIzNjcxMy8yNjY0MDMyMjYtODljMDQyN2UtYzFjMS00ZmEyLThhMmItNmQxM2VjZjkyMjg2LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA0MDglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDA4VDA2MjEzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTY3OTQ3YzZhMDc2NDgxMjJhN2JkOTEyMjZkZTI1MzA5ZDg0ODAzMjU3YjIyNmU2NTAxNDZmODY2NDA2YmZjY2YmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.9M9_zBcAFp8mRxCf5NLBDmTmbEhE3LIB-jLgYSNY394)](https://private-user-images.githubusercontent.com/73236713/266403226-89c0427e-c1c1-4fa2-8a2b-6d13ecf92286.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzU2Mjk1OTgsIm5iZiI6MTc3NTYyOTI5OCwicGF0aCI6Ii83MzIzNjcxMy8yNjY0MDMyMjYtODljMDQyN2UtYzFjMS00ZmEyLThhMmItNmQxM2VjZjkyMjg2LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA0MDglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDA4VDA2MjEzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTY3OTQ3YzZhMDc2NDgxMjJhN2JkOTEyMjZkZTI1MzA5ZDg0ODAzMjU3YjIyNmU2NTAxNDZmODY2NDA2YmZjY2YmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.9M9_zBcAFp8mRxCf5NLBDmTmbEhE3LIB-jLgYSNY394)

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

The results should like this image :

[![Screenshot_20230907_213111](https://private-user-images.githubusercontent.com/73236713/266403748-ee148e4e-a990-402d-b99d-94065e77b3f5.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzU2Mjk1OTgsIm5iZiI6MTc3NTYyOTI5OCwicGF0aCI6Ii83MzIzNjcxMy8yNjY0MDM3NDgtZWUxNDhlNGUtYTk5MC00MDJkLWI5OWQtOTQwNjVlNzdiM2Y1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA0MDglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDA4VDA2MjEzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTk3NzI5YjEzMjZiYWRhZWMxOGQ4NzdjMDlhMzVlZDU0NDMxZjg2MDFiMGZmZmE3OWU0N2RiM2ZjZTZiMDc3YWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.8RT1N6WU7VaqwHmFWoqcJeHEeQ4oibCz5WVAXGo0-2Q)](https://private-user-images.githubusercontent.com/73236713/266403748-ee148e4e-a990-402d-b99d-94065e77b3f5.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzU2Mjk1OTgsIm5iZiI6MTc3NTYyOTI5OCwicGF0aCI6Ii83MzIzNjcxMy8yNjY0MDM3NDgtZWUxNDhlNGUtYTk5MC00MDJkLWI5OWQtOTQwNjVlNzdiM2Y1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA0MDglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDA4VDA2MjEzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTk3NzI5YjEzMjZiYWRhZWMxOGQ4NzdjMDlhMzVlZDU0NDMxZjg2MDFiMGZmZmE3OWU0N2RiM2ZjZTZiMDc3YWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.8RT1N6WU7VaqwHmFWoqcJeHEeQ4oibCz5WVAXGo0-2Q)

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 :

[![Screenshot_20230907_213957](https://private-user-images.githubusercontent.com/73236713/266405593-080e58b0-ed06-44b9-bcbb-27ef2719c0ef.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzU2Mjk1OTgsIm5iZiI6MTc3NTYyOTI5OCwicGF0aCI6Ii83MzIzNjcxMy8yNjY0MDU1OTMtMDgwZTU4YjAtZWQwNi00NGI5LWJjYmItMjdlZjI3MTljMGVmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA0MDglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDA4VDA2MjEzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWIzMDUzYzBhZDQ0ZDQ2ZGMzOTRjMDY1ZWVkNjE4ZWVlYmZkNTgxNmZkZjU0ODMwZGRmZWQwYTQzMjYzNmFkYWQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.peDaGRjqDHVTua1OMVt9DLiTwbM9zQEFynttr0D9AyY)](https://private-user-images.githubusercontent.com/73236713/266405593-080e58b0-ed06-44b9-bcbb-27ef2719c0ef.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzU2Mjk1OTgsIm5iZiI6MTc3NTYyOTI5OCwicGF0aCI6Ii83MzIzNjcxMy8yNjY0MDU1OTMtMDgwZTU4YjAtZWQwNi00NGI5LWJjYmItMjdlZjI3MTljMGVmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA0MDglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDA4VDA2MjEzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWIzMDUzYzBhZDQ0ZDQ2ZGMzOTRjMDY1ZWVkNjE4ZWVlYmZkNTgxNmZkZjU0ODMwZGRmZWQwYTQzMjYzNmFkYWQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.peDaGRjqDHVTua1OMVt9DLiTwbM9zQEFynttr0D9AyY)

we should use this code :

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

The result should like this image :

[![Screenshot_20230907_214232](https://private-user-images.githubusercontent.com/73236713/266406114-3dcd8604-9afd-4d99-93ba-ad18d260b48f.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzU2Mjk1OTgsIm5iZiI6MTc3NTYyOTI5OCwicGF0aCI6Ii83MzIzNjcxMy8yNjY0MDYxMTQtM2RjZDg2MDQtOWFmZC00ZDk5LTkzYmEtYWQxOGQyNjBiNDhmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA0MDglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDA4VDA2MjEzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWM5YTkwYTg3YzcxNDI1YjYxYmE3MmIxNmVlNDhkYmM2YmIxY2RmNmNlZDQyZWNmN2FkZDVkZjY4NjBmNGJkM2YmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.PrfEKRGQZgstTmrIVwXa4tnH61KT418huLemCuNBBWI)](https://private-user-images.githubusercontent.com/73236713/266406114-3dcd8604-9afd-4d99-93ba-ad18d260b48f.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzU2Mjk1OTgsIm5iZiI6MTc3NTYyOTI5OCwicGF0aCI6Ii83MzIzNjcxMy8yNjY0MDYxMTQtM2RjZDg2MDQtOWFmZC00ZDk5LTkzYmEtYWQxOGQyNjBiNDhmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA0MDglMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNDA4VDA2MjEzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWM5YTkwYTg3YzcxNDI1YjYxYmE3MmIxNmVlNDhkYmM2YmIxY2RmNmNlZDQyZWNmN2FkZDVkZjY4NjBmNGJkM2YmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.PrfEKRGQZgstTmrIVwXa4tnH61KT418huLemCuNBBWI)

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::Login('Login', 'https://example.com/login'),
        InlineButton::Url('Visit Homepage', 'https://example.com')
    )
    ->build();
```

**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:

```
#[FilterAnd(new FilterPrivate,new FilterIncoming)]
public function handleExit(Message $message){
    $message->reply('Thank you',
        reply_markup : KeyboardHide::new()->build()
    );
}
```

```
$data['reply_markup'] = KeyboardForceReply::new()
    ->addButton(KeyboardButton::Text('Hello please reply'))
    ->placeholder('must reply')
    ->build();
```

([back to top](#top))

### Keyboard Peer Type

[](#keyboard-peer-type)

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

```
KeyboardMarkup::new()
    ->addButton(KeyboardButton::Peer('Request for user', 0, RequestUser::new()));
```

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

```
KeyboardMarkup::new()
    ->addButton(KeyboardButton::Peer('Request for broadcast', 2, RequestChannel::new()));
```

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

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

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

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

([back to top](#top))

### Convert Telegram Keyboard To Fluent Keyboard

[](#convert-telegram-keyboard-to-fluent-keyboard)

You can now easily convert mtproto telegram keyboards to fluent keyboard for modify and ... using `fromRawReplyMarkup` methods! here is and example

```
$fluentKeyboard = Keyboard::fromRawReplyMarkup($replyMarkup);
```

As you know `$fluentKeyboard` is object here and you can modify and add more buttons to it. here is an example if `$flunentKeyboard` instance of `KeyboardInline`

```
$fluentKeyboard->addButton(InlineButton::Callback('End', 'End'));
```

At the end you can call `build` method on that and pass to some telegram method here is an example for [MadelineProto](https://github.com/danog/MadelineProto) :

```
#[FilterAnd(new FilterPrivate,new FilterIncoming)]
public function modify(Message $message){
    $message->reply('That is new keyboard',
        reply_markup : $fluentKeyboard->build()
    );
}
```

([back to top](#top))

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance42

Moderate activity, may be stable

Popularity12

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 58.1% 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 ~46 days

Recently: every ~88 days

Total

13

Last Release

467d ago

Major Versions

1.0.3-beta → 2.0.02024-09-17

### Community

Maintainers

![](https://www.gravatar.com/avatar/ab9d08066bf7c9fc3a54bb13fc1839dbeeceadd9be2bce0e9876d410f38f4fe1?d=identicon)[ahjdev](/maintainers/ahjdev)

![](https://www.gravatar.com/avatar/1ab11f83c077db98fb470ef73695dc0fbb3f451d326ef69d782a0718417c14fa?d=identicon)[mtalaeii](/maintainers/mtalaeii)

---

Top Contributors

[![ahjdev](https://avatars.githubusercontent.com/u/107793906?v=4)](https://github.com/ahjdev "ahjdev (50 commits)")[![mtalaeii](https://avatars.githubusercontent.com/u/73236713?v=4)](https://github.com/mtalaeii "mtalaeii (36 commits)")

---

Tags

builderfluentbottelegrammtprotokeyboardmadelineprotomt-proto

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/easy-keyboard-fluent-keyboard/health.svg)

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

###  Alternatives

[danog/madelineproto

Async PHP client API for the telegram MTProto protocol.

3.4k855.0k18](/packages/danog-madelineproto)[longman/telegram-bot

PHP Telegram bot

4.0k2.1M50](/packages/longman-telegram-bot)[telegram-bot/api

PHP Wrapper for Telegram Bot API

1.2k2.4M29](/packages/telegram-bot-api)[envms/fluentpdo

FluentPDO is a quick and light PHP library for rapid query building. It features a smart join builder, which automatically creates table joins.

925511.7k13](/packages/envms-fluentpdo)[nutgram/nutgram

The Telegram bot library that doesn't drive you nuts

714214.9k8](/packages/nutgram-nutgram)[php-telegram-bot/fluent-keyboard

Fluent Keyboard builder for ReplyKeyboardMarkup and InlineKeyboardMarkup.

131.0k](/packages/php-telegram-bot-fluent-keyboard)

PHPackages © 2026

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