Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,659 changes: 4,659 additions & 0 deletions docs/swagger.json

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions src/Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public function __construct(
}

$this->client = $client;
$this->modelFactory = $modelFactory ?? new ModelFactory();
$this->modelFactory = $modelFactory ?? new ModelFactory($this->logger);
$this->updateDispatcher = new UpdateDispatcher($this);
}

Expand Down Expand Up @@ -685,7 +685,6 @@ public function getPinnedMessage(int $chatId): ?Message
return null;
}


return $this->modelFactory->createMessage($response['message']);
}

Expand Down
5 changes: 5 additions & 0 deletions src/Enums/UpdateType.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@ enum UpdateType: string
case MessageRemoved = 'message_removed';
case BotAdded = 'bot_added';
case BotRemoved = 'bot_removed';
case DialogMuted = 'dialog_muted';
case DialogUnmuted = 'dialog_unmuted';
case DialogCleared = 'dialog_cleared';
case DialogRemoved = 'dialog_removed';
case UserAdded = 'user_added';
case UserRemoved = 'user_removed';
case BotStarted = 'bot_started';
case BotStopped = 'bot_stopped';
case ChatTitleChanged = 'chat_title_changed';
case MessageChatCreated = 'message_chat_created';
}
73 changes: 69 additions & 4 deletions src/Laravel/MaxBotManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@
* Provides convenient methods for integrating Max Bot with Laravel applications.
* Handles webhook processing, long polling, and event dispatching within Laravel context.
*/
class MaxBotManager
readonly class MaxBotManager
{
/**
* @param Container $container
* @param Api $api
* @param UpdateDispatcher $dispatcher
*/
public function __construct(
private readonly Container $container,
private readonly Api $api,
private readonly UpdateDispatcher $dispatcher,
private Container $container,
private Api $api,
private UpdateDispatcher $dispatcher,
) {
}

Expand Down Expand Up @@ -229,6 +229,58 @@ public function onBotRemoved(callable|string $handler): void
$this->dispatcher->onBotRemoved($this->resolveHandler($handler));
}

/**
* Register a dialog mute handler.
*
* @param callable|string $handler Can be a closure, callable, or Laravel container binding.
*
* @throws BindingResolutionException
* @codeCoverageIgnore
*/
public function onDialogMuted(callable|string $handler): void
{
$this->dispatcher->onDialogMuted($this->resolveHandler($handler));
}

/**
* Register a dialog unmute handler.
*
* @param callable|string $handler Can be a closure, callable, or Laravel container binding.
*
* @throws BindingResolutionException
* @codeCoverageIgnore
*/
public function onDialogUnmuted(callable|string $handler): void
{
$this->dispatcher->onDialogUnmuted($this->resolveHandler($handler));
}

/**
* Register a dialog cleared handler.
*
* @param callable|string $handler Can be a closure, callable, or Laravel container binding.
*
* @throws BindingResolutionException
* @codeCoverageIgnore
*/
public function onDialogCleared(callable|string $handler): void
{
$this->dispatcher->onDialogCleared($this->resolveHandler($handler));
}

/**
* Register a dialog removed handler.
*
* @param callable|string $handler Can be a closure, callable, or Laravel container binding.
*
* @throws BindingResolutionException
* @codeCoverageIgnore
*/
public function onDialogRemoved(callable|string $handler): void
{
$this->dispatcher->onDialogRemoved($this->resolveHandler($handler));
}

/**
* Register a user added handler.
*
Expand Down Expand Up @@ -268,6 +320,19 @@ public function onBotStarted(callable|string $handler): void
$this->dispatcher->onBotStarted($this->resolveHandler($handler));
}

/**
* Register a bot stopped handler.
*
* @param callable|string $handler Can be a closure, callable, or Laravel container binding.
*
* @throws BindingResolutionException
* @codeCoverageIgnore
*/
public function onBotStopped(callable|string $handler): void
{
$this->dispatcher->onBotStopped($this->resolveHandler($handler));
}

/**
* Register a chat title changed handler.
*
Expand Down
31 changes: 26 additions & 5 deletions src/Laravel/MaxBotServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,14 @@ public function register(): void
);
});

$this->app->singleton(ModelFactory::class, function () {
return new ModelFactory();
$this->app->singleton(ModelFactory::class, function (Application $app) {
/** @var Config $config */
$config = $app->make(Config::class);
$logger = $config->get('maxbot.logging.enabled', false)
? $app->make(LoggerInterface::class)
: new NullLogger();

return new ModelFactory($logger);
});

$this->app->singleton(Api::class, function (Application $app) {
Expand All @@ -97,11 +103,15 @@ public function register(): void
);
}

$logger = $config->get('maxbot.logging.enabled', false)
? $app->make(LoggerInterface::class)
: new NullLogger();

return new Api(
$accessToken,
$app->make(ClientApiInterface::class),
$app->make(ModelFactory::class),
$app->make(LoggerInterface::class),
$logger,
);
});

Expand All @@ -114,19 +124,30 @@ public function register(): void
$config = $app->make(Config::class);
$secret = $config->get('maxbot.webhook_secret');

$logger = $config->get('maxbot.logging.enabled', false)
? $app->make(LoggerInterface::class)
: new NullLogger();

return new WebhookHandler(
$app->make(UpdateDispatcher::class),
$app->make(ModelFactory::class),
$app->make(LoggerInterface::class),
$logger,
$secret,
);
});

$this->app->bind(LongPollingHandler::class, function (Application $app) {
/** @var Config $config */
$config = $app->make(Config::class);

$logger = $config->get('maxbot.logging.enabled', false)
? $app->make(LoggerInterface::class)
: new NullLogger();

return new LongPollingHandler(
$app->make(Api::class),
$app->make(UpdateDispatcher::class),
$app->make(LoggerInterface::class),
$logger,
);
});

Expand Down
30 changes: 28 additions & 2 deletions src/ModelFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,12 @@
use BushlanovDev\MaxMessengerBot\Models\Updates\BotAddedToChatUpdate;
use BushlanovDev\MaxMessengerBot\Models\Updates\BotRemovedFromChatUpdate;
use BushlanovDev\MaxMessengerBot\Models\Updates\BotStartedUpdate;
use BushlanovDev\MaxMessengerBot\Models\Updates\BotStoppedUpdate;
use BushlanovDev\MaxMessengerBot\Models\Updates\ChatTitleChangedUpdate;
use BushlanovDev\MaxMessengerBot\Models\Updates\DialogClearedUpdate;
use BushlanovDev\MaxMessengerBot\Models\Updates\DialogMutedUpdate;
use BushlanovDev\MaxMessengerBot\Models\Updates\DialogRemovedUpdate;
use BushlanovDev\MaxMessengerBot\Models\Updates\DialogUnmutedUpdate;
use BushlanovDev\MaxMessengerBot\Models\Updates\MessageCallbackUpdate;
use BushlanovDev\MaxMessengerBot\Models\Updates\MessageChatCreatedUpdate;
use BushlanovDev\MaxMessengerBot\Models\Updates\MessageCreatedUpdate;
Expand All @@ -67,13 +72,25 @@
use BushlanovDev\MaxMessengerBot\Models\UploadEndpoint;
use BushlanovDev\MaxMessengerBot\Models\VideoAttachmentDetails;
use LogicException;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use ReflectionException;

/**
* Creates DTOs from raw associative arrays returned by the API client.
*/
class ModelFactory
readonly class ModelFactory
{
private LoggerInterface $logger;

/**
* @param LoggerInterface|null $logger PSR LoggerInterface.
*/
public function __construct(?LoggerInterface $logger = null)
{
$this->logger = $logger ?? new NullLogger();
}

/**
* Simple response to request.
*
Expand Down Expand Up @@ -341,7 +358,11 @@ public function createUpdateList(array $data): UpdateList
if (isset($data['updates']) && is_array($data['updates'])) {
foreach ($data['updates'] as $updateData) {
// Here we delegate the creation of a specific update to another factory method
$updateObjects[] = $this->createUpdate($updateData);
try {
$updateObjects[] = $this->createUpdate($updateData);
} catch (LogicException $e) {
$this->logger->debug($e->getMessage(), ['payload' => $updateData, 'exception' => $e]);
}
}
}

Expand Down Expand Up @@ -369,9 +390,14 @@ public function createUpdate(array $data): AbstractUpdate
UpdateType::MessageRemoved => MessageRemovedUpdate::fromArray($data),
UpdateType::BotAdded => BotAddedToChatUpdate::fromArray($data),
UpdateType::BotRemoved => BotRemovedFromChatUpdate::fromArray($data),
UpdateType::DialogMuted => DialogMutedUpdate::fromArray($data),
UpdateType::DialogUnmuted => DialogUnmutedUpdate::fromArray($data),
UpdateType::DialogCleared => DialogClearedUpdate::fromArray($data),
UpdateType::DialogRemoved => DialogRemovedUpdate::fromArray($data),
UpdateType::UserAdded => UserAddedToChatUpdate::fromArray($data),
UpdateType::UserRemoved => UserRemovedFromChatUpdate::fromArray($data),
UpdateType::BotStarted => BotStartedUpdate::fromArray($data),
UpdateType::BotStopped => BotStoppedUpdate::fromArray($data),
UpdateType::ChatTitleChanged => ChatTitleChangedUpdate::fromArray($data),
UpdateType::MessageChatCreated => MessageChatCreatedUpdate::fromArray($data),
default => throw new LogicException(
Expand Down
29 changes: 29 additions & 0 deletions src/Models/Updates/BotStoppedUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace BushlanovDev\MaxMessengerBot\Models\Updates;

use BushlanovDev\MaxMessengerBot\Enums\UpdateType;
use BushlanovDev\MaxMessengerBot\Models\User;

/**
* The bot receives this type of update as soon as the user stops the bot.
*/
final readonly class BotStoppedUpdate extends AbstractUpdate
{
/**
* @param int $timestamp Unix-time when event has occurred.
* @param int $chatId Dialog identifier where event has occurred.
* @param User $user User pressed the 'Start' button.
* @param string|null $userLocale Current user locale in IETF BCP 47 format.
*/
public function __construct(
int $timestamp,
public int $chatId,
public User $user,
public ?string $userLocale,
) {
parent::__construct(UpdateType::BotStopped, $timestamp);
}
}
29 changes: 29 additions & 0 deletions src/Models/Updates/DialogClearedUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace BushlanovDev\MaxMessengerBot\Models\Updates;

use BushlanovDev\MaxMessengerBot\Enums\UpdateType;
use BushlanovDev\MaxMessengerBot\Models\User;

/**
* Event clearing dialog history.
*/
final readonly class DialogClearedUpdate extends AbstractUpdate
{
/**
* @param int $timestamp Unix-time when event has occurred.
* @param int $chatId Dialog identifier where event has occurred.
* @param User $user User pressed the 'Start' button.
* @param string|null $userLocale Current user locale in IETF BCP 47 format.
*/
public function __construct(
int $timestamp,
public int $chatId,
public User $user,
public ?string $userLocale,
) {
parent::__construct(UpdateType::DialogCleared, $timestamp);
}
}
31 changes: 31 additions & 0 deletions src/Models/Updates/DialogMutedUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace BushlanovDev\MaxMessengerBot\Models\Updates;

use BushlanovDev\MaxMessengerBot\Enums\UpdateType;
use BushlanovDev\MaxMessengerBot\Models\User;

/**
* Event when a user mutes a conversation with a bot.
*/
final readonly class DialogMutedUpdate extends AbstractUpdate
{
/**
* @param int $timestamp Unix-time when event has occurred.
* @param int $chatId Dialog identifier where event has occurred.
* @param User $user User pressed the 'Start' button.
* @param int|null $mutedUntil The time in Unix format before which the dialog was disabled.
* @param string|null $userLocale Current user locale in IETF BCP 47 format.
*/
public function __construct(
int $timestamp,
public int $chatId,
public User $user,
public ?int $mutedUntil,
public ?string $userLocale,
) {
parent::__construct(UpdateType::DialogMuted, $timestamp);
}
}
29 changes: 29 additions & 0 deletions src/Models/Updates/DialogRemovedUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace BushlanovDev\MaxMessengerBot\Models\Updates;

use BushlanovDev\MaxMessengerBot\Enums\UpdateType;
use BushlanovDev\MaxMessengerBot\Models\User;

/**
* Event deleting a chat.
*/
final readonly class DialogRemovedUpdate extends AbstractUpdate
{
/**
* @param int $timestamp Unix-time when event has occurred.
* @param int $chatId Dialog identifier where event has occurred.
* @param User $user User pressed the 'Start' button.
* @param string|null $userLocale Current user locale in IETF BCP 47 format.
*/
public function __construct(
int $timestamp,
public int $chatId,
public User $user,
public ?string $userLocale,
) {
parent::__construct(UpdateType::DialogRemoved, $timestamp);
}
}
Loading