Skip to content

Commit e5f16a8

Browse files
authored
Multiple bots support (BoShurik#49)
1 parent d9daff6 commit e5f16a8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1522
-311
lines changed

.gitattributes

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Path-based git attributes
2+
# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
3+
4+
# Ignore all test and documentation with "export-ignore".
5+
/.gitattributes export-ignore
6+
/.gitignore export-ignore
7+
/.github export-ignore
8+
/phpunit.xml.dist export-ignore
9+
/.php-cs-fixer.dist.php export-ignore
10+
/psalm.xml export-ignore
11+
/tests export-ignore

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
CHANGELOG
22
=========
33

4-
5.1.0 (2023-xx-xx)
4+
6.0.0 (2023-xx-xx)
55
------------------
6+
7+
* Allow multiple bots
68
* Improve the webhook:set command so that it accepts the hostname. The webhook URL will be generated automatically.
79
* Moved config yaml files to php.
810

README.md

+71-7
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,14 @@ public function registerBundles()
3737
``` yaml
3838
BoShurikTelegramBotBundle:
3939
resource: "@BoShurikTelegramBotBundle/Resources/config/routing.php"
40-
prefix: /_telegram/<some-secret>
40+
prefix: /_telegram/%telegram_bot_route_secret%
41+
```
42+
43+
or for multiple bots:
44+
``` yaml
45+
BoShurikTelegramBotBundle:
46+
resource: "@BoShurikTelegramBotBundle/Resources/config/routing.php"
47+
prefix: /_telegram/{bot}/%telegram_bot_route_secret%
4148
```
4249
4350
#### Configuration
@@ -49,12 +56,39 @@ boshurik_telegram_bot:
4956
proxy: "socks5://127.0.0.1:8888"
5057
```
5158
59+
or for multiple bots:
60+
``` yaml
61+
boshurik_telegram_bot:
62+
api:
63+
default_bot: first
64+
bots:
65+
first: "%first_telegram_bot_api_token%"
66+
second: "%second_telegram_bot_api_token%"
67+
proxy: "socks5://127.0.0.1:8888"
68+
```
69+
5270
## Usage
5371
5472
#### API
5573
74+
To get default bot api:
75+
```php
76+
use TelegramBot\Api\BotApi;
77+
public function __construct(private BotApi $api)
78+
```
79+
80+
For multiple bots:
81+
5682
```php
57-
$api = $this->container->get(TelegramBot\Api\BotApi::class);
83+
84+
use BoShurik\TelegramBotBundle\Telegram\BotLocator;
85+
use TelegramBot\Api\BotApi;
86+
87+
public function foo(BotLocator $botLocator)
88+
{
89+
/** @var BotApi $api */
90+
$api = $botLocator->get('first');
91+
}
5892
```
5993

6094
For more info see [Usage][2] section in [`telegram-bot/api`][1] library
@@ -63,6 +97,7 @@ For more info see [Usage][2] section in [`telegram-bot/api`][1] library
6397

6498
``` bash
6599
bin/console telegram:updates
100+
bin/console telegram:updates first
66101
```
67102

68103
For more information see [official documentation][3]
@@ -72,13 +107,15 @@ For more information see [official documentation][3]
72107
##### Set
73108

74109
``` bash
75-
bin/console telegram:webhook:set <url> [<path-to-certificate>]
110+
bin/console telegram:webhook:set <url-or-hostname> [<path-to-certificate>]
111+
bin/console telegram:webhook:set <url-or-hostname> [<path-to-certificate>] --bot first
76112
```
77113

78114
##### Unset
79115

80116
``` bash
81117
bin/console telegram:webhook:unset
118+
bin/console telegram:webhook:unset first
82119
```
83120

84121
For more information see [official documentation][4]
@@ -118,16 +155,43 @@ app.telegram.command:
118155

119156
If you use `autoconfigure` tag will be added automatically
120157

121-
There is predefined `\BoShurik\TelegramBotBundle\Telegram\Command\HelpCommand`. You need to register it:
158+
For application with multiple bots you need to pass bot id:
159+
``` yaml
160+
app.telegram.command:
161+
class: AppBundle\Telegram\Command\SomeCommand
162+
tags:
163+
- { name: boshurik_telegram_bot.command, bot: first }
164+
```
165+
If you need to use same command for multiple bots you must add multiple tags for each bot:
166+
``` yaml
167+
app.telegram.command:
168+
class: AppBundle\Telegram\Command\SomeCommand
169+
tags:
170+
- { name: boshurik_telegram_bot.command, bot: first }
171+
- { name: boshurik_telegram_bot.command, bot: second }
172+
```
173+
174+
There is predefined `\BoShurik\TelegramBotBundle\Telegram\Command\HelpCommand`.
175+
It displays commands which additionally implement `\BoShurik\TelegramBotBundle\Telegram\Command\PublicCommandInterface`
176+
177+
You need to register it:
122178
``` yaml
123179
app.telegram.command.help:
124180
class: BoShurik\TelegramBotBundle\Telegram\Command\HelpCommand
125181
arguments:
126-
- '@BoShurik\TelegramBotBundle\Telegram\Command\CommandRegistry'
182+
- '@boshurik_telegram_bot.command.registry.default'
127183
tags:
128184
- { name: boshurik_telegram_bot.command }
129185
```
130-
It displays commands which additionally implement `\BoShurik\TelegramBotBundle\Telegram\Command\PublicCommandInterface`
186+
or for multiple bots:
187+
``` yaml
188+
app.telegram.command.help:
189+
class: BoShurik\TelegramBotBundle\Telegram\Command\HelpCommand
190+
arguments:
191+
- '@boshurik_telegram_bot.command.registry.first'
192+
tags:
193+
- { name: boshurik_telegram_bot.command, bot: first }
194+
```
131195

132196
#### Events
133197

@@ -147,7 +211,7 @@ public function onUpdate(UpdateEvent $event)
147211

148212
This bundle supports login through Telegram Api
149213

150-
If you want allow your Bot's users to login without requiring them to register again
214+
If you want to allow your Bot's users to login without requiring them to register again
151215
follow these [instructions](LOGIN_WITH_TELEGRAM.md).
152216

153217
[1]: https://github.com/TelegramBot/Api

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
},
6565
"extra": {
6666
"branch-alias": {
67-
"dev-master": "5.0.x-dev"
67+
"dev-master": "6.0.x-dev"
6868
}
6969
}
7070
}

phpunit.xml.dist

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
<php>
2020
<ini name="error_reporting" value="-1" />
21-
<server name="KERNEL_CLASS" value="BoShurik\TelegramBotBundle\Tests\Kernel\TestKernel" />
21+
<server name="KERNEL_CLASS" value="BoShurik\TelegramBotBundle\Tests\Kernel\Single\SingleTestKernel" />
2222
<server name="SYMFONY_DEPRECATIONS_HELPER" value="weak" />
2323
</php>
2424

src/Authenticator/TelegramAuthenticator.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
2525
use Symfony\Component\Security\Http\Util\TargetPathTrait;
2626

27-
class TelegramAuthenticator extends AbstractAuthenticator
27+
final class TelegramAuthenticator extends AbstractAuthenticator
2828
{
2929
use TargetPathTrait;
3030

src/Authenticator/TelegramLoginValidator.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313

1414
use BoShurik\TelegramBotBundle\Exception\AuthenticationException;
1515

16-
class TelegramLoginValidator
16+
/**
17+
* @final
18+
*/
19+
/* final */ class TelegramLoginValidator
1720
{
1821
private const EXPIRING_TIMEOUT = 3600;
1922

src/BoShurikTelegramBotBundle.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
1818
use Symfony\Component\HttpKernel\Bundle\Bundle;
1919

20-
class BoShurikTelegramBotBundle extends Bundle
20+
final class BoShurikTelegramBotBundle extends Bundle
2121
{
22-
public function build(ContainerBuilder $container)
22+
public function build(ContainerBuilder $container): void
2323
{
2424
parent::build($container);
2525

src/Command/UpdatesCommand.php

+10-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313

1414
use BoShurik\TelegramBotBundle\Telegram\Telegram;
1515
use Symfony\Component\Console\Command\Command;
16+
use Symfony\Component\Console\Input\InputArgument;
1617
use Symfony\Component\Console\Input\InputInterface;
1718
use Symfony\Component\Console\Output\OutputInterface;
1819

19-
class UpdatesCommand extends Command
20+
final class UpdatesCommand extends Command
2021
{
2122
public function __construct(private Telegram $telegram)
2223
{
@@ -27,13 +28,20 @@ protected function configure(): void
2728
{
2829
$this
2930
->setName('telegram:updates')
31+
->addArgument('bot', InputArgument::OPTIONAL, 'Bot')
3032
->setDescription('Get updates')
3133
;
3234
}
3335

3436
protected function execute(InputInterface $input, OutputInterface $output): int
3537
{
36-
$this->telegram->processUpdates();
38+
/** @var string|null $bot */
39+
$bot = $input->getArgument('bot');
40+
if ($bot) {
41+
$this->telegram->processUpdates($bot);
42+
} else {
43+
$this->telegram->processAllUpdates();
44+
}
3745

3846
return Command::SUCCESS;
3947
}

src/Command/Webhook/InfoCommand.php

+33-13
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,17 @@
1111

1212
namespace BoShurik\TelegramBotBundle\Command\Webhook;
1313

14+
use BoShurik\TelegramBotBundle\Telegram\BotLocator;
1415
use Symfony\Component\Console\Command\Command;
16+
use Symfony\Component\Console\Input\InputArgument;
1517
use Symfony\Component\Console\Input\InputInterface;
1618
use Symfony\Component\Console\Output\OutputInterface;
1719
use Symfony\Component\Console\Style\SymfonyStyle;
1820
use TelegramBot\Api\BotApi;
1921

20-
class InfoCommand extends Command
22+
final class InfoCommand extends Command
2123
{
22-
public function __construct(private BotApi $api)
24+
public function __construct(private BotLocator $botLocator)
2325
{
2426
parent::__construct();
2527
}
@@ -28,6 +30,7 @@ protected function configure(): void
2830
{
2931
$this
3032
->setName('telegram:webhook:info')
33+
->addArgument('bot', InputArgument::OPTIONAL, 'Bot')
3134
->setDescription('Webhook info')
3235
;
3336
}
@@ -36,43 +39,60 @@ protected function execute(InputInterface $input, OutputInterface $output): int
3639
{
3740
$io = new SymfonyStyle($input, $output);
3841

39-
$info = $this->api->getWebhookInfo();
42+
/** @var string|null $bot */
43+
$bot = $input->getArgument('bot');
44+
if ($bot) {
45+
$api = $this->botLocator->get($bot);
46+
47+
$this->printWebhookInfo($io, $bot, $api);
48+
} else {
49+
foreach ($this->botLocator->all() as $name => $api) {
50+
$this->printWebhookInfo($io, $name, $api);
51+
}
52+
}
53+
54+
return Command::SUCCESS;
55+
}
56+
57+
private function printWebhookInfo(SymfonyStyle $io, string $name, BotApi $api): void
58+
{
59+
$io->block(sprintf('Bot "%s"', $name));
60+
61+
$info = $api->getWebhookInfo();
4062

4163
$values = [];
4264
$values[] = [
4365
'Webhook URL',
4466
$info->getUrl(),
4567
];
4668
$values[] = [
47-
'custom certificate',
69+
'Custom Certificate',
4870
$info->hasCustomCertificate() ? 'yes' : 'no',
4971
];
5072
$values[] = [
51-
'pending update count',
73+
'Pending Update Count',
5274
$info->getPendingUpdateCount(),
5375
];
5476
$values[] = [
55-
'last error date',
77+
'Last Error Date',
5678
$info->getLastErrorDate() ? date('Y-m-d H:i:s', $info->getLastErrorDate()) : '-',
5779
];
5880
$values[] = [
59-
'last error message',
81+
'Last Error Message',
6082
$info->getLastErrorMessage() ?? '-',
6183
];
6284
$values[] = [
63-
'max connections',
85+
'Max Connections',
6486
$info->getMaxConnections(),
6587
];
6688
$values[] = [
67-
'allowed updates',
89+
'Allowed Updates',
6890
\is_array($info->getAllowedUpdates()) ? implode(', ', $info->getAllowedUpdates()) : '-',
6991
];
7092

7193
$io->table([
72-
'name',
73-
'value',
94+
'Name',
95+
'Value',
7496
], $values);
75-
76-
return Command::SUCCESS;
7797
}
7898
}

0 commit comments

Comments
 (0)