Skip to content

Commit a33f44b

Browse files
committed
Easier chat id migrations with callback
1 parent 17f9bf0 commit a33f44b

2 files changed

Lines changed: 92 additions & 9 deletions

File tree

src/Bot.php

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Telepath\Handlers\ConversationHandler;
2525
use Telepath\Handlers\Handler;
2626
use Telepath\Layers\Generated;
27+
use Telepath\Telegram\ResponseParameters;
2728
use Telepath\Telegram\Update;
2829

2930
class Bot extends Generated
@@ -125,11 +126,8 @@ protected function discoverPsr4(string $path): static
125126

126127
$this->handlers[] = $attribute->newInstance()
127128
->assign($class, $method->getName());
128-
129129
}
130-
131130
}
132-
133131
}
134132

135133
if (count($this->handlers) === 0) {
@@ -202,9 +200,7 @@ public function handlePolling(?array $allowedUpdates = null, int $timeout = 60):
202200

203201
$offset = max($offset, $update->update_id + 1);
204202
$this->processUpdate($update);
205-
206203
}
207-
208204
}
209205
}
210206

@@ -231,7 +227,7 @@ public function username(): string
231227
}
232228

233229
// Check cache
234-
$cacheKey = 'telepath.username.'. sha1($this->token);
230+
$cacheKey = 'telepath.username.'.sha1($this->token);
235231
$username = $this->cache()?->get($cacheKey);
236232
if ($username !== null) {
237233
$this->username = $username;
@@ -289,6 +285,16 @@ protected function processUpdate(Update $update): mixed
289285
{
290286
$this->container->extend(Update::class)->setConcrete($update);
291287

288+
// Check for chat_id_migration
289+
if ($update->message?->migrate_to_chat_id || $update->message?->migrate_from_chat_id) {
290+
$message = $update->message;
291+
292+
$fromChatId = $message->migrate_from_chat_id ?? $message->chat->id;
293+
$toChatId = $message->migrate_to_chat_id ?? $message->chat->id;
294+
295+
$this->callChatIdMigrationCallbacks($fromChatId, $toChatId);
296+
}
297+
292298
$responsibleHandlers = [];
293299

294300
$conversationHandler = $this->getAvailableConversationHandler($update);
@@ -340,4 +346,61 @@ private function getNamespace(string $file): ?string
340346

341347
return $namespace ?: null;
342348
}
349+
350+
/**
351+
* @var array<callable(int, int): void>
352+
*/
353+
protected array $chatIdMigrationCallbacks = [];
354+
355+
protected function callChatIdMigrationCallbacks(int $fromChatId, int $toChatId): void
356+
{
357+
foreach ($this->chatIdMigrationCallbacks as $callback) {
358+
$callback($fromChatId, $toChatId);
359+
}
360+
}
361+
362+
/**
363+
* @param callable(int $fromChatId, int $toChatId): void $callback
364+
*/
365+
public function chatIdMigrationCallback(callable $callback): static
366+
{
367+
$this->chatIdMigrationCallbacks[] = $callback;
368+
369+
return $this;
370+
}
371+
372+
/**
373+
* @param array{
374+
* ok: bool,
375+
* description?: string,
376+
* result?: array,
377+
* error_code?: int,
378+
* parameters?: array,
379+
* } $response
380+
*/
381+
public function rescueError(string $method, array $data, array $response): mixed
382+
{
383+
if (! isset($response['parameters'])) {
384+
return null;
385+
}
386+
387+
$responseParameters = new ResponseParameters($response['parameters']);
388+
389+
if ($responseParameters->migrate_to_chat_id) {
390+
if (! isset($data['chat_id'])) {
391+
return null;
392+
}
393+
394+
$fromChatId = $data['chat_id'];
395+
$toChatId = $responseParameters->migrate_to_chat_id;
396+
397+
$this->callChatIdMigrationCallbacks($fromChatId, $toChatId);
398+
399+
$data['chat_id'] = $toChatId;
400+
401+
return $this->$method($data);
402+
}
403+
404+
return null;
405+
}
343406
}

src/Layers/Base.php

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,28 @@ public function raw(string $method, $data = []): mixed
5858
default => $this->sendAsJson($method, $data)
5959
};
6060

61+
/**
62+
* @var array{
63+
* ok: bool,
64+
* description?: string,
65+
* result?: array,
66+
* error_code?: int,
67+
* parameters?: array,
68+
* } $json
69+
*/
6170
$json = json_decode($response->getBody()->getContents(), true);
6271

6372
if ($json['ok'] !== true) {
64-
throw new TelegramException($json['description'], $json['error_code'] ?? 0);
73+
$result = $this->rescueError($method, $data, $json);
74+
75+
if ($result !== null) {
76+
return $result;
77+
}
78+
79+
throw new TelegramException(
80+
$json['description'] ?? 'An unknown error occured',
81+
$json['error_code'] ?? 0
82+
);
6583
}
6684

6785
$this->lastApiResult = $json['description'] ?? null;
@@ -70,7 +88,11 @@ public function raw(string $method, $data = []): mixed
7088
preg_match('/@return (.+)\[]\n/u', $method->getDocComment(), $matches);
7189

7290
return $this->objectify($json['result'], $method->getReturnType(), $matches[1] ?? null, $this);
91+
}
7392

93+
protected function rescueError(string $method, array $data, array $response): mixed
94+
{
95+
return null;
7496
}
7597

7698
protected function extractFiles(array|object &$input, int $depth = 1): array
@@ -120,7 +142,6 @@ protected function sendAsMultipart(string $method, array $data): \Psr\Http\Messa
120142
'name' => $key,
121143
'contents' => $value,
122144
];
123-
124145
}
125146

126147
return $this->httpClient()->post($method, [
@@ -166,7 +187,6 @@ protected function hasInputFiles(array $data): bool
166187
if ($value instanceof InputMedia) {
167188
return true;
168189
}
169-
170190
}
171191

172192
return false;

0 commit comments

Comments
 (0)