fn () => Bootstrap::envConfig(), Psr17Factory::class => fn () => new Psr17Factory(), Guzzle::class => fn () => new Guzzle(['timeout' => 30]), Options::class => function (ContainerInterface $c): Options { $cfg = $c->get('config'); $opts = Options::default()->withKeepRawUpdates(true); if (($cfg['debug.chat_id'] ?? 0) > 0) { $opts = $opts->withDebugChatId((int) $cfg['debug.chat_id']); } return $opts; }, Api::class => function (ContainerInterface $c): Api { $cfg = $c->get('config'); return Api::create( token: (string) $cfg['bot.token'], http: $c->get(Guzzle::class), requestFactory: $c->get(Psr17Factory::class), streamFactory: $c->get(Psr17Factory::class), options: $c->get(Options::class), ); }, LoggerInterface::class => fn (ContainerInterface $c) => LoggerFactory::create($c->get('config')), KeyboardFactory::class => function (ContainerInterface $c): KeyboardFactory { $cfg = $c->get('config'); $url = trim((string) ($cfg['webapp.url'] ?? '')); return new KeyboardFactory($url !== '' ? $url : null); }, CommandRouter::class => function (ContainerInterface $c): CommandRouter { $router = new CommandRouter(); $router->add('start', $c->get(HelpScenario::class)); $router->add('help', $c->get(HelpScenario::class)); $router->add('bot', $c->get(BotInfoScenario::class)); $router->add('bot_patch', $c->get(BotInfoScenario::class)); $router->add('chats', $c->get(ChatsScenario::class)); $router->add('chat', $c->get(ChatsScenario::class)); $router->add('chat_membership', $c->get(ChatsScenario::class)); $router->add('members', $c->get(ChatsScenario::class)); $router->add('admins', $c->get(ChatAdminScenario::class)); $router->add('pin', $c->get(ChatAdminScenario::class)); $router->add('action', $c->get(ChatAdminScenario::class)); $router->add('leave', $c->get(ChatAdminScenario::class)); $router->add('edit_chat', $c->get(ChatAdminScenario::class)); $router->add('add_member', $c->get(ChatAdminScenario::class)); $router->add('remove_member', $c->get(ChatAdminScenario::class)); $router->add('send_text', $c->get(MessagesScenario::class)); $router->add('send_markdown', $c->get(MessagesScenario::class)); $router->add('send_html', $c->get(MessagesScenario::class)); $router->add('reply', $c->get(MessagesScenario::class)); $router->add('forward', $c->get(MessagesScenario::class)); $router->add('edit', $c->get(MessagesScenario::class)); $router->add('delete', $c->get(MessagesScenario::class)); $router->add('messages', $c->get(MessagesScenario::class)); $router->add('message', $c->get(MessagesScenario::class)); $router->add('markup', $c->get(MessagesScenario::class)); $router->add('notify', $c->get(MessagesScenario::class)); $router->add('disable_preview', $c->get(MessagesScenario::class)); $router->add('keyboard', $c->get(KeyboardScenario::class)); $router->add('upload_photo_file', $c->get(UploadsScenario::class)); $router->add('upload_photo_url', $c->get(UploadsScenario::class)); $router->add('upload_photo_bytes', $c->get(UploadsScenario::class)); $router->add('upload_photo_base64', $c->get(UploadsScenario::class)); $router->add('upload_audio', $c->get(UploadsScenario::class)); $router->add('upload_video', $c->get(UploadsScenario::class)); $router->add('upload_file', $c->get(UploadsScenario::class)); $router->add('upload_url', $c->get(UploadsScenario::class)); $router->add('attach_location', $c->get(AttachmentScenario::class)); $router->add('attach_contact', $c->get(AttachmentScenario::class)); $router->add('attach_sticker', $c->get(AttachmentScenario::class)); $router->add('phone_check', $c->get(PhoneCheckScenario::class)); $router->add('phone_list', $c->get(PhoneCheckScenario::class)); $router->add('debug', $c->get(DebugScenario::class)); return $router; }, UpdateRouter::class => function (ContainerInterface $c): UpdateRouter { $router = new UpdateRouter($c->get(LoggerInterface::class)); $router->add($c->get(MessageCreatedHandler::class)); $router->add($c->get(MessageCallbackHandler::class)); $router->add($c->get(MessageEditedHandler::class)); $router->add($c->get(MessageRemovedHandler::class)); $router->add($c->get(BotStartedHandler::class)); $router->add($c->get(BotAddedToChatHandler::class)); $router->add($c->get(BotRemovedFromChatHandler::class)); $router->add($c->get(BotStopedFromChatHandler::class)); $router->add($c->get(UserAddedToChatHandler::class)); $router->add($c->get(UserRemovedFromChatHandler::class)); $router->add($c->get(ChatTitleChangedHandler::class)); $router->add($c->get(DialogClearedHandler::class)); $router->add($c->get(DialogRemovedHandler::class)); return $router; }, WebhookHandler::class => function (ContainerInterface $c): WebhookHandler { $cfg = $c->get('config'); $handler = new WebhookHandler( responseFactory: $c->get(Psr17Factory::class), secret: (string) $cfg['bot.secret'], keepRawUpdates: true, ); $router = $c->get(UpdateRouter::class); $logger = $c->get(LoggerInterface::class); $handler->setHandler(static function (object $update) use ($router, $logger): void { try { $router->dispatch($update); } catch (\Throwable $e) { $logger->error('Update failed: ' . $e->getMessage(), ['exception' => $e]); } }); return $handler; }, HelpScenario::class => \DI\autowire(), BotInfoScenario::class => \DI\autowire(), ChatsScenario::class => \DI\autowire(), ChatAdminScenario::class => \DI\autowire(), MessagesScenario::class => \DI\autowire(), UploadsScenario::class => \DI\autowire(), KeyboardScenario::class => \DI\autowire(), AttachmentScenario::class => \DI\autowire(), PhoneCheckScenario::class => \DI\autowire(), DebugScenario::class => \DI\autowire(), MessageCreatedHandler::class => \DI\autowire(), MessageCallbackHandler::class => \DI\autowire(), MessageEditedHandler::class => \DI\autowire(), MessageRemovedHandler::class => \DI\autowire(), BotStartedHandler::class => \DI\autowire(), BotAddedToChatHandler::class => \DI\autowire(), BotRemovedFromChatHandler::class => \DI\autowire(), BotStopedFromChatHandler::class => \DI\autowire(), UserAddedToChatHandler::class => \DI\autowire(), UserRemovedFromChatHandler::class => \DI\autowire(), ChatTitleChangedHandler::class => \DI\autowire(), DialogClearedHandler::class => \DI\autowire(), DialogRemovedHandler::class => \DI\autowire(), Application::class => function (ContainerInterface $c): Application { $app = new Application('max-bot-test', '1.0.0'); $app->addCommands([ $c->get(\App\Command\SubscribeWebhookCommand::class), $c->get(\App\Command\UnsubscribeWebhookCommand::class), $c->get(\App\Command\ListSubscriptionsCommand::class), $c->get(\App\Command\GetBotInfoCommand::class), $c->get(\App\Command\SelfTestCommand::class), ]); return $app; }, ];