phenogram/bindings

用于Telegram Bot API的低级别类型安全的PHP绑定

2.6.0 2024-09-22 13:28 UTC

This package is auto-updated.

Last update: 2024-09-22 13:28:57 UTC


README

🇬🇧 ENGLISH | 🇷🇺 РУССКИЙ

Telegram Bot API的PHP类型

基于官方文档的严格类型化PHP类,用于在Phenogram框架中使用

主要使用scraper生成

目前仍在开发中,并非每个类都经过测试或使用。如果您发现与文档不符之处,请创建问题。所有未在文档中描述的内容均超出本项目范围。

当前支持版本:Telegram bot API v7.10

安装

composer require phenogram/bindings

使用

序列化器

示例使用可以在Api类中查看。

以下是简单示例

use Phenogram\Bindings\Serializer;

$serializer = new Serializer();
$inlineKeyboardMarkup = new InlineKeyboardMarkup(
    inlineKeyboard: [[
        new InlineKeyboardButton(text: 'Кнопка 1', callbackData: 'data1')
    ]],
);

$json = $serializer->serialize([
    'reply_markup' => $inlineKeyboardMarkup,
]);

$arrayKeyboard = [
    'reply_markup' => [
        'inline_keyboard' => [[
            ['text' => 'Кнопка 1', 'callback_data' => 'data1']
        ]],
    ],
];

$jsonFromArray = json_encode($arrayKeyboard);

assert($jsonFromArray === $json);

它也可以用于将Telegram请求反序列化为类型化的PHP类。唯一需要注意的是,您需要传递来自Telegram请求的result字段的JSON编码字符串,而不是整个请求。

use Phenogram\Bindings\Serializer;
use Phenogram\Bindings\Types\Update;
use Phenogram\Bindings\Types\Message;
use Phenogram\Bindings\Types\Chat;

$updatesData = [[
    'update_id' => 1,
    'message' => [
        'message_id' => 54321,
        'chat' => [
            'id' => 11223344,
            'type' => 'private',
        ],
        'date' => 1600000000,
    ],
]];

$serializer = new Serializer();
$updates = $serializer->deserialize(
    data: json_encode($updatesData),
    type: Update::class,
    isArray: true,
);

assert($updates[0] instanceof Update::class);
assert($updates[0]->message instanceof Message::class);
assert($updates[0]->message->chat instanceof Chat::class);

使用API

客户端

要使用API,您首先需要实现ClientInterface接口,其中只有一个方法sendRequest。然后您可以使用Api类向Telegram API发送请求。

客户端实现超出本项目范围,但您可以在Phenogram框架中查看amphp/http-client的示例实现。

使用ext-curl的最基本实现可能如下

use Phenogram\Bindings\ClientInterface;
use Phenogram\Bindings\Types;

final readonly class TelegramBotApiClient implements ClientInterface
{
    public function __construct(
        private string $token,
        private string $apiUrl = 'https://api.telegram.org',
    ) {
    }
    
    public function sendRequest(string $method, string $json): Types\Response
    {
        $ch = curl_init("{$this->apiUrl}/bot{$this->token}/{$method}");
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);
    
        if (curl_errno($ch)) {
            throw new \RuntimeException('Ошибка запроса: ' . curl_error($ch));
        }
    
        curl_close($ch);
    
        $responseData = json_decode($response, true);
    
        if (!isset($responseData['ok']) || !isset($responseData['result'])) {
            return new Types\Response(
                ok: false,
                result: null,
                errorCode: $responseData['error_code'] ?? null,
                description: $responseData['description'] ?? null,
                parameters: isset($responseData['parameters']) ? new Types\ResponseParameters(
                    migrateToChatId: $responseData['parameters']['migrate_to_chat_id'] ?? null,
                    retryAfter: $responseData['parameters']['retry_after'] ?? null,
                ) : null,
            );
        }
    
        return new Types\Response(
            ok: $responseData['ok'],
            result: json_encode($responseData['result']),
            errorCode: $responseData['error_code'] ?? null,
            description: $responseData['description'] ?? null,
            parameters: isset($responseData['parameters']) ? new Types\ResponseParameters(
                migrateToChatId: $responseData['parameters']['migrate_to_chat_id'] ?? null,
                retryAfter: $responseData['parameters']['retry_after'] ?? null,
            ) : null,
        );
    }
}

但我当然推荐使用库,例如Guzzle或amphp/http-client。

执行请求

$api = new Api(
    client: new TelegramBotApiClient($token),
    serializer: new Serializer(),
);

$me = $api->getMe();

assert($me instanceof User::class);

仍在进行中

当前主要问题是多部分请求中文件的加载,但我正在考虑这个问题。

我还需要通过模板定义从Api::doRequest返回的类型,但我还没有确定如何操作,phpstan胜出。

结论

这只是一个用于您的Telegram机器人的SDK,而不是完整的框架,您可以按原样使用它,也可以根据需要扩展它。

如果您需要框架,请查看Phenogram