Centralize Telegram Bot API URL/token construction in a TelegramApi helper
This commit is contained in:
parent
e907ad087f
commit
b6a3cb886c
7 changed files with 85 additions and 23 deletions
|
|
@ -10,6 +10,7 @@
|
|||
use App\Features\SocialAccountLimit;
|
||||
use App\Models\SocialAccount;
|
||||
use App\Models\Workspace;
|
||||
use App\Services\Social\TelegramApi;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Laravel\Pennant\Feature;
|
||||
|
|
@ -79,27 +80,24 @@ public static function execute(Workspace $workspace, array $chat, string $nonce)
|
|||
*/
|
||||
private static function fetchChannelAvatar(string $chatId): ?string
|
||||
{
|
||||
$token = (string) config('trypost.platforms.telegram.bot_token');
|
||||
$api = rtrim((string) config('trypost.platforms.telegram.api'), '/');
|
||||
|
||||
if ($token === '') {
|
||||
if (TelegramApi::token() === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$fileId = data_get(Http::get("{$api}/bot{$token}/getChat", ['chat_id' => $chatId])->json(), 'result.photo.big_file_id');
|
||||
$fileId = data_get(Http::get(TelegramApi::endpoint('getChat'), ['chat_id' => $chatId])->json(), 'result.photo.big_file_id');
|
||||
|
||||
if (! is_string($fileId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$filePath = data_get(Http::get("{$api}/bot{$token}/getFile", ['file_id' => $fileId])->json(), 'result.file_path');
|
||||
$filePath = data_get(Http::get(TelegramApi::endpoint('getFile'), ['file_id' => $fileId])->json(), 'result.file_path');
|
||||
|
||||
if (! is_string($filePath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return uploadFromUrl("{$api}/file/bot{$token}/{$filePath}");
|
||||
return uploadFromUrl(TelegramApi::fileUrl($filePath));
|
||||
} catch (Throwable) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace App\Actions\SocialAccount;
|
||||
|
||||
use App\Services\Social\TelegramApi;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
|
|
@ -20,17 +21,15 @@ class RegisterTelegramWebhook
|
|||
*/
|
||||
public static function execute(): string
|
||||
{
|
||||
$token = (string) config('trypost.platforms.telegram.bot_token');
|
||||
$api = rtrim((string) config('trypost.platforms.telegram.api'), '/');
|
||||
$secret = (string) config('trypost.platforms.telegram.webhook_secret');
|
||||
|
||||
if ($token === '' || $secret === '') {
|
||||
if (TelegramApi::token() === '' || $secret === '') {
|
||||
throw new InvalidArgumentException('TELEGRAM_BOT_TOKEN and TELEGRAM_WEBHOOK_SECRET must both be set.');
|
||||
}
|
||||
|
||||
$url = route('telegram.webhook');
|
||||
|
||||
$response = Http::post("{$api}/bot{$token}/setWebhook", [
|
||||
$response = Http::post(TelegramApi::endpoint('setWebhook'), [
|
||||
'url' => $url,
|
||||
'secret_token' => $secret,
|
||||
'allowed_updates' => ['message', 'channel_post', 'message_reaction_count'],
|
||||
|
|
|
|||
|
|
@ -507,11 +507,8 @@ private function verifyBluesky(SocialAccount $account): bool
|
|||
|
||||
private function verifyTelegram(SocialAccount $account): bool
|
||||
{
|
||||
$token = (string) config('trypost.platforms.telegram.bot_token');
|
||||
$api = rtrim((string) config('trypost.platforms.telegram.api'), '/');
|
||||
|
||||
// getChat succeeds only while the bot can still reach the chat.
|
||||
$response = Http::get("{$api}/bot{$token}/getChat", [
|
||||
$response = Http::get(TelegramApi::endpoint('getChat'), [
|
||||
'chat_id' => data_get($account->meta, 'chat_id'),
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,17 +18,15 @@ class TelegramAnalytics
|
|||
*/
|
||||
public function getMetrics(SocialAccount $account): array
|
||||
{
|
||||
$token = (string) config('trypost.platforms.telegram.bot_token');
|
||||
$api = rtrim((string) config('trypost.platforms.telegram.api'), '/');
|
||||
$chatId = data_get($account->meta, 'chat_id');
|
||||
|
||||
if ($token === '' || $chatId === null) {
|
||||
if (TelegramApi::token() === '' || $chatId === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
$count = data_get(
|
||||
Http::get("{$api}/bot{$token}/getChatMemberCount", ['chat_id' => $chatId])->json(),
|
||||
Http::get(TelegramApi::endpoint('getChatMemberCount'), ['chat_id' => $chatId])->json(),
|
||||
'result',
|
||||
);
|
||||
} catch (Throwable) {
|
||||
|
|
|
|||
44
app/Services/Social/TelegramApi.php
Normal file
44
app/Services/Social/TelegramApi.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Services\Social;
|
||||
|
||||
/**
|
||||
* Builds Telegram Bot API URLs from the configured token + host, so the
|
||||
* `bot<token>/<method>` shape and config keys live in one place.
|
||||
*/
|
||||
class TelegramApi
|
||||
{
|
||||
public static function token(): string
|
||||
{
|
||||
return (string) config('trypost.platforms.telegram.bot_token');
|
||||
}
|
||||
|
||||
/**
|
||||
* Endpoint for a Bot API method, e.g. `https://api.telegram.org/bot<token>/sendMessage`.
|
||||
*/
|
||||
public static function endpoint(string $method): string
|
||||
{
|
||||
$base = self::baseUrl();
|
||||
$token = self::token();
|
||||
|
||||
return "{$base}/bot{$token}/{$method}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Download URL for a file path returned by `getFile`.
|
||||
*/
|
||||
public static function fileUrl(string $path): string
|
||||
{
|
||||
$base = self::baseUrl();
|
||||
$token = self::token();
|
||||
|
||||
return "{$base}/file/bot{$token}/{$path}";
|
||||
}
|
||||
|
||||
private static function baseUrl(): string
|
||||
{
|
||||
return rtrim((string) config('trypost.platforms.telegram.api'), '/');
|
||||
}
|
||||
}
|
||||
|
|
@ -141,10 +141,7 @@ private function telegramMedia(MediaItem $media): array
|
|||
|
||||
private function call(string $method, array $payload): Response
|
||||
{
|
||||
$token = (string) config('trypost.platforms.telegram.bot_token');
|
||||
$api = rtrim((string) config('trypost.platforms.telegram.api'), '/');
|
||||
|
||||
$response = $this->socialHttp()->post("{$api}/bot{$token}/{$method}", $payload);
|
||||
$response = $this->socialHttp()->post(TelegramApi::endpoint($method), $payload);
|
||||
|
||||
if ($response->failed() || data_get($response->json(), 'ok') !== true) {
|
||||
$this->handleApiError($response);
|
||||
|
|
|
|||
29
tests/Unit/Services/Social/TelegramApiTest.php
Normal file
29
tests/Unit/Services/Social/TelegramApiTest.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Services\Social\TelegramApi;
|
||||
|
||||
beforeEach(function () {
|
||||
config([
|
||||
'trypost.platforms.telegram.bot_token' => 'TESTTOKEN',
|
||||
'trypost.platforms.telegram.api' => 'https://api.telegram.org',
|
||||
]);
|
||||
});
|
||||
|
||||
it('builds a method endpoint from the token and host', function () {
|
||||
expect(TelegramApi::endpoint('sendMessage'))
|
||||
->toBe('https://api.telegram.org/botTESTTOKEN/sendMessage');
|
||||
});
|
||||
|
||||
it('builds a file download url', function () {
|
||||
expect(TelegramApi::fileUrl('photos/file_1.jpg'))
|
||||
->toBe('https://api.telegram.org/file/botTESTTOKEN/photos/file_1.jpg');
|
||||
});
|
||||
|
||||
it('trims a trailing slash from the configured host', function () {
|
||||
config(['trypost.platforms.telegram.api' => 'https://api.telegram.org/']);
|
||||
|
||||
expect(TelegramApi::endpoint('getChat'))
|
||||
->toBe('https://api.telegram.org/botTESTTOKEN/getChat');
|
||||
});
|
||||
Loading…
Reference in a new issue