Skip to content

Commit 825c8b3

Browse files
abbasudollabbasmkhll
andauthored
send logic moved to drivers (#146)
Co-authored-by: llabbasmkhll <[email protected]>
1 parent 76299fa commit 825c8b3

File tree

11 files changed

+171
-105
lines changed

11 files changed

+171
-105
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
},
2929
"require-dev": {
3030
"mockery/mockery": "^1.4",
31+
"orchestra/testbench": "6.0",
3132
"phpunit/phpunit": "^9.0"
3233
},
3334
"autoload": {

src/Contracts/TelegramSender.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace NotificationChannels\Telegram\Contracts;
4+
5+
use NotificationChannels\Telegram\Exceptions\CouldNotSendNotification;
6+
7+
interface TelegramSender
8+
{
9+
/**
10+
* Send the given message.
11+
*
12+
* @throws CouldNotSendNotification
13+
*
14+
* @return mixed
15+
*/
16+
public function send();
17+
}

src/TelegramBase.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace NotificationChannels\Telegram;
4+
5+
use JsonSerializable;
6+
use NotificationChannels\Telegram\Traits\HasSharedLogic;
7+
8+
/**
9+
* Class TelegramBase.
10+
*/
11+
class TelegramBase implements JsonSerializable
12+
{
13+
use HasSharedLogic;
14+
15+
public function __construct()
16+
{
17+
$this->telegram = app(Telegram::class);
18+
}
19+
}

src/TelegramChannel.php

Lines changed: 3 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@
1212
*/
1313
class TelegramChannel
1414
{
15-
/**
16-
* @var Telegram
17-
*/
18-
protected $telegram;
19-
2015
/**
2116
* @var Dispatcher
2217
*/
@@ -25,9 +20,8 @@ class TelegramChannel
2520
/**
2621
* Channel constructor.
2722
*/
28-
public function __construct(Telegram $telegram, Dispatcher $dispatcher)
23+
public function __construct(Dispatcher $dispatcher)
2924
{
30-
$this->telegram = $telegram;
3125
$this->dispatcher = $dispatcher;
3226
}
3327

@@ -58,56 +52,11 @@ public function send($notifiable, Notification $notification): ?array
5852
}
5953

6054
if ($message->hasToken()) {
61-
$this->telegram->setToken($message->token);
55+
$message->telegram->setToken($message->token);
6256
}
6357

64-
$params = $message->toArray();
65-
66-
$sendMethod = str_replace('Telegram', 'send', array_reverse(explode('\\', get_class($message)))[0]);
67-
6858
try {
69-
if ($message instanceof TelegramMessage) {
70-
if ($message->shouldChunk()) {
71-
$replyMarkup = $message->getPayloadValue('reply_markup');
72-
73-
if ($replyMarkup) {
74-
unset($params['reply_markup']);
75-
}
76-
77-
$messages = $this->chunk($message->getPayloadValue('text'), $message->chunkSize);
78-
79-
$payloads = collect($messages)->filter()->map(function ($text) use ($params) {
80-
return array_merge($params, ['text' => $text]);
81-
});
82-
83-
if ($replyMarkup) {
84-
$lastMessage = $payloads->pop();
85-
$lastMessage['reply_markup'] = $replyMarkup;
86-
$payloads->push($lastMessage);
87-
}
88-
89-
return $payloads->map(function ($payload) {
90-
$response = $this->telegram->sendMessage($payload);
91-
92-
// To avoid rate limit of one message per second.
93-
sleep(1);
94-
95-
if ($response) {
96-
return json_decode($response->getBody()->getContents(), true);
97-
}
98-
99-
return $response;
100-
})->toArray();
101-
}
102-
103-
$response = $this->telegram->sendMessage($params);
104-
} elseif ($message instanceof TelegramFile) {
105-
$response = $this->telegram->sendFile($params, $message->type, $message->hasFile());
106-
} elseif (method_exists($this->telegram, $sendMethod)) {
107-
$response = $this->telegram->{$sendMethod}($params);
108-
} else {
109-
return null;
110-
}
59+
$response = $message->send();
11160
} catch (CouldNotSendNotification $exception) {
11261
$this->dispatcher->dispatch(new NotificationFailed(
11362
$notifiable,
@@ -121,27 +70,4 @@ public function send($notifiable, Notification $notification): ?array
12170

12271
return json_decode($response->getBody()->getContents(), true);
12372
}
124-
125-
/**
126-
* Chunk the given string into an array of strings.
127-
*/
128-
public function chunk(string $value, int $limit = 4096): array
129-
{
130-
if (mb_strwidth($value, 'UTF-8') <= $limit) {
131-
return [$value];
132-
}
133-
134-
if ($limit >= 4097) {
135-
$limit = 4096;
136-
}
137-
138-
$output = explode('%#TGMSG#%', wordwrap($value, $limit, '%#TGMSG#%'));
139-
140-
// Fallback for when the string is too long and wordwrap doesn't cut it.
141-
if (count($output) <= 1) {
142-
$output = mb_str_split($value, $limit, 'UTF-8');
143-
}
144-
145-
return $output;
146-
}
14773
}

src/TelegramContact.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,17 @@
22

33
namespace NotificationChannels\Telegram;
44

5-
use JsonSerializable;
6-
use NotificationChannels\Telegram\Traits\HasSharedLogic;
5+
use NotificationChannels\Telegram\Contracts\TelegramSender;
6+
use NotificationChannels\Telegram\Exceptions\CouldNotSendNotification;
77

88
/**
99
* Class TelegramContact.
1010
*/
11-
class TelegramContact implements JsonSerializable
11+
class TelegramContact extends TelegramBase implements TelegramSender
1212
{
13-
use HasSharedLogic;
14-
1513
public function __construct(string $phoneNumber = '')
1614
{
15+
parent::__construct();
1716
$this->phoneNumber($phoneNumber);
1817
}
1918

@@ -69,4 +68,12 @@ public function vCard(string $vCard): self
6968

7069
return $this;
7170
}
71+
72+
/**
73+
* @throws CouldNotSendNotification
74+
*/
75+
public function send()
76+
{
77+
return $this->telegram->sendContact($this->toArray());
78+
}
7279
}

src/TelegramFile.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,21 @@
33
namespace NotificationChannels\Telegram;
44

55
use Illuminate\Support\Facades\View;
6-
use JsonSerializable;
7-
use NotificationChannels\Telegram\Traits\HasSharedLogic;
6+
use NotificationChannels\Telegram\Contracts\TelegramSender;
7+
use NotificationChannels\Telegram\Exceptions\CouldNotSendNotification;
88
use Psr\Http\Message\StreamInterface;
99

1010
/**
1111
* Class TelegramFile.
1212
*/
13-
class TelegramFile implements JsonSerializable
13+
class TelegramFile extends TelegramBase implements TelegramSender
1414
{
15-
use HasSharedLogic;
16-
1715
/** @var string content type. */
1816
public $type = 'document';
1917

2018
public function __construct(string $content = '')
2119
{
20+
parent::__construct();
2221
$this->content($content);
2322
$this->payload['parse_mode'] = 'Markdown';
2423
}
@@ -198,6 +197,14 @@ public function toMultipart(): array
198197
return $data;
199198
}
200199

200+
/**
201+
* @throws CouldNotSendNotification
202+
*/
203+
public function send()
204+
{
205+
return $this->telegram->sendFile($this->toArray(), $this->type, $this->hasFile());
206+
}
207+
201208
/**
202209
* Determine if it's a regular and readable file.
203210
*/

src/TelegramLocation.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@
22

33
namespace NotificationChannels\Telegram;
44

5-
use JsonSerializable;
6-
use NotificationChannels\Telegram\Traits\HasSharedLogic;
5+
use NotificationChannels\Telegram\Contracts\TelegramSender;
6+
use NotificationChannels\Telegram\Exceptions\CouldNotSendNotification;
77

88
/**
99
* Class TelegramLocation.
1010
*/
11-
class TelegramLocation implements JsonSerializable
11+
class TelegramLocation extends TelegramBase implements TelegramSender
1212
{
13-
use HasSharedLogic;
14-
1513
/**
1614
* Telegram Location constructor.
1715
*
@@ -20,6 +18,7 @@ class TelegramLocation implements JsonSerializable
2018
*/
2119
public function __construct($latitude = null, $longitude = null)
2220
{
21+
parent::__construct();
2322
$this->latitude($latitude);
2423
$this->longitude($longitude);
2524
}
@@ -62,4 +61,12 @@ public function longitude($longitude): self
6261

6362
return $this;
6463
}
64+
65+
/**
66+
* @throws CouldNotSendNotification
67+
*/
68+
public function send()
69+
{
70+
return $this->telegram->sendLocation($this->toArray());
71+
}
6572
}

src/TelegramMessage.php

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,20 @@
33
namespace NotificationChannels\Telegram;
44

55
use Illuminate\Support\Facades\View;
6-
use JsonSerializable;
7-
use NotificationChannels\Telegram\Traits\HasSharedLogic;
6+
use NotificationChannels\Telegram\Contracts\TelegramSender;
7+
use NotificationChannels\Telegram\Exceptions\CouldNotSendNotification;
88

99
/**
1010
* Class TelegramMessage.
1111
*/
12-
class TelegramMessage implements JsonSerializable
12+
class TelegramMessage extends TelegramBase implements TelegramSender
1313
{
14-
use HasSharedLogic;
15-
1614
/** @var int Message Chunk Size */
1715
public $chunkSize;
1816

1917
public function __construct(string $content = '')
2018
{
19+
parent::__construct();
2120
$this->content($content);
2221
$this->payload['parse_mode'] = 'Markdown';
2322
}
@@ -73,4 +72,70 @@ public function shouldChunk(): bool
7372
{
7473
return null !== $this->chunkSize;
7574
}
75+
76+
/**
77+
* @throws CouldNotSendNotification
78+
*/
79+
public function send()
80+
{
81+
$params = $this->toArray();
82+
83+
if ($this->shouldChunk()) {
84+
$replyMarkup = $this->getPayloadValue('reply_markup');
85+
86+
if ($replyMarkup) {
87+
unset($params['reply_markup']);
88+
}
89+
90+
$messages = $this->chunkStrings($this->getPayloadValue('text'), $this->chunkSize);
91+
92+
$payloads = collect($messages)->filter()->map(function ($text) use ($params) {
93+
return array_merge($params, ['text' => $text]);
94+
});
95+
96+
if ($replyMarkup) {
97+
$lastMessage = $payloads->pop();
98+
$lastMessage['reply_markup'] = $replyMarkup;
99+
$payloads->push($lastMessage);
100+
}
101+
102+
return $payloads->map(function ($payload) {
103+
$response = $this->telegram->sendMessage($payload);
104+
105+
// To avoid rate limit of one message per second.
106+
sleep(1);
107+
108+
if ($response) {
109+
return json_decode($response->getBody()->getContents(), true);
110+
}
111+
112+
return $response;
113+
})->toArray();
114+
}
115+
116+
return $this->telegram->sendMessage($params);
117+
}
118+
119+
/**
120+
* Chunk the given string into an array of strings.
121+
*/
122+
private function chunkStrings(string $value, int $limit = 4096): array
123+
{
124+
if (mb_strwidth($value, 'UTF-8') <= $limit) {
125+
return [$value];
126+
}
127+
128+
if ($limit >= 4097) {
129+
$limit = 4096;
130+
}
131+
132+
$output = explode('%#TGMSG#%', wordwrap($value, $limit, '%#TGMSG#%'));
133+
134+
// Fallback for when the string is too long and wordwrap doesn't cut it.
135+
if (count($output) <= 1) {
136+
$output = mb_str_split($value, $limit, 'UTF-8');
137+
}
138+
139+
return $output;
140+
}
76141
}

0 commit comments

Comments
 (0)