Added ChatButton & ReplyButtons

This commit is contained in:
Alex
2025-08-02 09:24:11 +03:00
parent f5acd0ee88
commit 51b105b847
35 changed files with 625 additions and 92 deletions
+22 -2
View File
@@ -48,9 +48,10 @@ use RuntimeException;
*/
class Api
{
private const string API_BASE_URL = 'https://botapi.max.ru';
public const string API_VERSION = '0.0.6';
private const string API_BASE_URL = 'https://botapi.max.ru';
private const string METHOD_GET = 'GET';
private const string METHOD_POST = 'POST';
private const string METHOD_DELETE = 'DELETE';
@@ -88,7 +89,7 @@ class Api
public function __construct(
string $accessToken,
?ClientApiInterface $client = null,
?ModelFactory $modelFactory = null
?ModelFactory $modelFactory = null,
) {
if ($client === null) {
if (!class_exists(\GuzzleHttp\Client::class) || !class_exists(\GuzzleHttp\Psr7\HttpFactory::class)) {
@@ -114,6 +115,25 @@ class Api
$this->modelFactory = $modelFactory ?? new ModelFactory();
}
/**
* Performs a request to the Max Bot API.
*
* @param string $method The HTTP method (GET, POST, PATCH, etc.).
* @param string $uri The API endpoint (e.g., '/me', '/messages').
* @param array<string, mixed> $queryParams Query parameters for the request.
* @param array<string, mixed> $body The request body.
*
* @return array<string, mixed> The decoded JSON response as an associative array.
* @throws ClientApiException for API-level errors (4xx, 5xx).
* @throws NetworkException for network-related issues.
* @throws SerializationException for JSON encoding/decoding failures.
* @codeCoverageIgnore
*/
public function request(string $method, string $uri, array $queryParams = [], array $body = []): array
{
return $this->client->request($method, $uri, $queryParams, $body);
}
/**
* Creates a WebhookHandler instance, pre-configured with the necessary dependencies.
*
+1
View File
@@ -13,6 +13,7 @@ enum AttachmentType: string
case Sticker = 'sticker';
case Contact = 'contact';
case InlineKeyboard = 'inline_keyboard';
case ReplyKeyboard = 'reply_keyboard';
case Location = 'location';
case Share = 'share';
}
@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Enums;
enum ButtonType: string
enum InlineButtonType: string
{
case Callback = 'callback';
case Link = 'link';
@@ -12,4 +12,5 @@ enum ButtonType: string
case RequestContact = 'request_contact';
case OpenApp = 'open_app';
case Message = 'message';
case Chat = 'chat';
}
+12
View File
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Enums;
enum ReplyButtonType: string
{
case Message = 'message';
case UserGeoLocation = 'user_geo_location';
case UserContact = 'user_contact';
}
@@ -1,17 +0,0 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons;
use BushlanovDev\MaxMessengerBot\Enums\ButtonType;
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
abstract readonly class AbstractButton extends AbstractModel
{
public function __construct(
public ButtonType $type,
public string $text,
) {
}
}
@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline;
use BushlanovDev\MaxMessengerBot\Enums\InlineButtonType;
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
abstract readonly class AbstractInlineButton extends AbstractModel
{
/**
* @param InlineButtonType $type The type of the inline button.
* @param string $text Visible text of the button.
*/
public function __construct(
public InlineButtonType $type,
public string $text,
) {
}
}
@@ -2,15 +2,15 @@
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons;
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline;
use BushlanovDev\MaxMessengerBot\Enums\ButtonType;
use BushlanovDev\MaxMessengerBot\Enums\InlineButtonType;
use BushlanovDev\MaxMessengerBot\Enums\Intent;
/**
* Sends a notification with payload to a bot (via WebHook or long polling).
*/
final readonly class CallbackButton extends AbstractButton
final readonly class CallbackButton extends AbstractInlineButton
{
public string $payload;
public ?Intent $intent;
@@ -22,7 +22,7 @@ final readonly class CallbackButton extends AbstractButton
*/
public function __construct(string $text, string $payload, ?Intent $intent = null)
{
parent::__construct(ButtonType::Callback, $text);
parent::__construct(InlineButtonType::Callback, $text);
$this->payload = $payload;
$this->intent = $intent;
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline;
use BushlanovDev\MaxMessengerBot\Enums\InlineButtonType;
/**
* Button that creates a new chat associated with the message.
* The bot will be added as an administrator by default.
*/
final readonly class ChatButton extends AbstractInlineButton
{
/**
* @param string $text Visible text of the button (1 to 128 characters).
* @param string $chatTitle Title of the chat to be created (max 200 characters).
* @param string|null $chatDescription Optional chat description (max 400 characters).
* @param string|null $startPayload Optional payload that will be sent to the bot in a `message_chat_created` update.
* @param int|null $uuid Optional unique identifier for the button. If not passed, it will be generated.
*/
public function __construct(
string $text,
public string $chatTitle,
public ?string $chatDescription = null,
public ?string $startPayload = null,
public ?int $uuid = null,
) {
parent::__construct(InlineButtonType::Chat, $text);
}
}
@@ -2,14 +2,14 @@
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons;
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline;
use BushlanovDev\MaxMessengerBot\Enums\ButtonType;
use BushlanovDev\MaxMessengerBot\Enums\InlineButtonType;
/**
* Makes a user to follow a link.
*/
final readonly class LinkButton extends AbstractButton
final readonly class LinkButton extends AbstractInlineButton
{
public string $url;
@@ -19,7 +19,7 @@ final readonly class LinkButton extends AbstractButton
*/
public function __construct(string $text, string $url)
{
parent::__construct(ButtonType::Link, $text);
parent::__construct(InlineButtonType::Link, $text);
$this->url = $url;
}
@@ -2,14 +2,14 @@
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons;
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline;
use BushlanovDev\MaxMessengerBot\Enums\ButtonType;
use BushlanovDev\MaxMessengerBot\Enums\InlineButtonType;
/**
* Opens the bot's mini-application.
*/
final readonly class OpenAppButton extends AbstractButton
final readonly class OpenAppButton extends AbstractInlineButton
{
public ?string $webApp;
public ?int $contactId;
@@ -21,7 +21,7 @@ final readonly class OpenAppButton extends AbstractButton
*/
public function __construct(string $text, ?string $webApp = null, ?int $contactId = null)
{
parent::__construct(ButtonType::OpenApp, $text);
parent::__construct(InlineButtonType::OpenApp, $text);
$this->webApp = $webApp;
$this->contactId = $contactId;
@@ -2,20 +2,20 @@
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons;
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline;
use BushlanovDev\MaxMessengerBot\Enums\ButtonType;
use BushlanovDev\MaxMessengerBot\Enums\InlineButtonType;
/**
* Requests the user permission to access contact information (phone number, short link, email).
*/
final readonly class RequestContactButton extends AbstractButton
final readonly class RequestContactButton extends AbstractInlineButton
{
/**
* @param string $text Visible button text (1 to 128 characters).
*/
public function __construct(string $text)
{
parent::__construct(ButtonType::RequestContact, $text);
parent::__construct(InlineButtonType::RequestContact, $text);
}
}
@@ -2,14 +2,14 @@
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons;
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline;
use BushlanovDev\MaxMessengerBot\Enums\ButtonType;
use BushlanovDev\MaxMessengerBot\Enums\InlineButtonType;
/**
* After pressing this type of button client sends new message with attachment of current user geo location.
*/
final readonly class RequestGeoLocationButton extends AbstractButton
final readonly class RequestGeoLocationButton extends AbstractInlineButton
{
public bool $quick;
@@ -19,7 +19,7 @@ final readonly class RequestGeoLocationButton extends AbstractButton
*/
public function __construct(string $text, bool $quick = false)
{
parent::__construct(ButtonType::RequestGeoLocation, $text);
parent::__construct(InlineButtonType::RequestGeoLocation, $text);
$this->quick = $quick;
}
@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply;
use BushlanovDev\MaxMessengerBot\Enums\ReplyButtonType;
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
abstract readonly class AbstractReplyButton extends AbstractModel
{
/**
* @param ReplyButtonType $type The type of the reply button.
* @param string $text Visible text of the button.
*/
public function __construct(
public ReplyButtonType $type,
public string $text,
) {
}
}
@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply;
use BushlanovDev\MaxMessengerBot\Enums\ReplyButtonType;
final readonly class SendContactButton extends AbstractReplyButton
{
/**
* @param string $text Visible text of the button.
*/
public function __construct(string $text)
{
parent::__construct(ReplyButtonType::UserContact, $text);
}
}
@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply;
use BushlanovDev\MaxMessengerBot\Enums\ReplyButtonType;
final readonly class SendGeoLocationButton extends AbstractReplyButton
{
/**
* @param string $text Visible text of the button.
* @param bool $quick If `true`, sends location without asking user's confirmation.
*/
public function __construct(
string $text,
public bool $quick = false,
) {
parent::__construct(ReplyButtonType::UserGeoLocation, $text);
}
}
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply;
use BushlanovDev\MaxMessengerBot\Enums\Intent;
use BushlanovDev\MaxMessengerBot\Enums\ReplyButtonType;
final readonly class SendMessageButton extends AbstractReplyButton
{
/**
* @param string $text Visible text of the button.
* @param string|null $payload Button payload.
* @param Intent $intent Intent of button.
*/
public function __construct(
string $text,
public ?string $payload = null,
public Intent $intent = Intent::Default,
) {
parent::__construct(ReplyButtonType::Message, $text);
}
}
@@ -4,12 +4,12 @@ declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads;
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\AbstractButton;
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\AbstractInlineButton;
final readonly class InlineKeyboardAttachmentRequestPayload extends AbstractAttachmentRequestPayload
{
/**
* @param AbstractButton[][] $buttons
* @param AbstractInlineButton[][] $buttons
*/
public function __construct(
public array $buttons,
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads;
use BushlanovDev\MaxMessengerBot\Attributes\ArrayOf;
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\AbstractReplyButton;
final readonly class ReplyKeyboardAttachmentRequestPayload extends AbstractAttachmentRequestPayload
{
/**
* @param AbstractReplyButton[][] $buttons Two-dimensional array of buttons.
* @param bool $direct Applicable only for chats.
* @param int|null $directUserId If set, reply keyboard will only be shown to this participant.
*/
public function __construct(
#[ArrayOf(AbstractReplyButton::class)]
public array $buttons,
public bool $direct = false,
public ?int $directUserId = null,
) {
}
}
@@ -5,13 +5,13 @@ declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Requests;
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\AbstractButton;
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\AbstractInlineButton;
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\InlineKeyboardAttachmentRequestPayload;
final readonly class InlineKeyboardAttachmentRequest extends AbstractAttachmentRequest
{
/**
* @param AbstractButton[][] $buttons
* @param AbstractInlineButton[][] $buttons
*/
public function __construct(array $buttons)
{
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Requests;
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\AbstractReplyButton;
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\ReplyKeyboardAttachmentRequestPayload;
final readonly class ReplyKeyboardAttachmentRequest extends AbstractAttachmentRequest
{
/**
* @param AbstractReplyButton[][] $buttons
* @param bool $direct
* @param int|null $directUserId
*/
public function __construct(
array $buttons,
bool $direct = false,
?int $directUserId = null
) {
parent::__construct(
AttachmentType::ReplyKeyboard,
new ReplyKeyboardAttachmentRequestPayload($buttons, $direct, $directUserId),
);
}
}