Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Telegram Bot API for PHP Change Log

## 0.14.1 February 9, 2026

- New #186: Add `SetMyProfilePhoto`, `RemoveMyProfilePhoto` and `GetUserProfileAudios` methods.
- New #186: Add `ChatOwnerLeft`, `ChatOwnerChanged`, `VideoQuality` and `UserProfileAudios` types.
- New #186: Add `allowsUsersToCreateTopics` field to `User` type.
- New #186: Add `iconCustomEmojiId` and `style` fields to `KeyboardButton` type.
- New #186: Add `iconCustomEmojiId` and `style` fields to `InlineKeyboardButton` type.
- New #186: Add `chatOwnerLeft` and `chatOwnerChanged` fields to `Message` type.
- New #186: Add `qualities` field to `Video` type.
- New #186: Add `firstProfileAudio` field to `ChatFullInfo` type.
- New #186: Add `rarity` field to `UniqueGiftModel` type.
- New #186: Add `isBurned` field to `UniqueGift` type.

## 0.14 February 7, 2026

- New #182: Introduce resource readers that handle reading content from different types of resources stored in
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

The package provides a simple and convenient way to interact with the Telegram Bot API.

✔️ Telegram Bot API 9.3 (December 31, 2025) is **fully supported**.
✔️ Telegram Bot API 9.4 (February 9, 2026) is **fully supported**.

> [!IMPORTANT]
> This project is developed and maintained by [Sergei Predvoditelev](https://github.com/vjik).
Expand Down
51 changes: 51 additions & 0 deletions src/Method/GetUserProfileAudios.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace Phptg\BotApi\Method;

use Phptg\BotApi\MethodInterface;
use Phptg\BotApi\ParseResult\ValueProcessor\ObjectValue;
use Phptg\BotApi\Transport\HttpMethod;
use Phptg\BotApi\Type\UserProfileAudios;

/**
* @see https://core.telegram.org/bots/api#getuserprofileaudios
*
* @template-implements MethodInterface<UserProfileAudios>
*/
final readonly class GetUserProfileAudios implements MethodInterface
{
public function __construct(
private int $userId,
private ?int $offset = null,
private ?int $limit = null,
) {}

public function getHttpMethod(): HttpMethod
{
return HttpMethod::GET;
}

public function getApiMethod(): string
{
return 'getUserProfileAudios';
}

public function getData(): array
{
return array_filter(
[
'user_id' => $this->userId,
'offset' => $this->offset,
'limit' => $this->limit,
],
static fn(mixed $value): bool => $value !== null,
);
}

public function getResultType(): ObjectValue
{
return new ObjectValue(UserProfileAudios::class);
}
}
39 changes: 39 additions & 0 deletions src/Method/RemoveMyProfilePhoto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Phptg\BotApi\Method;

use Phptg\BotApi\MethodInterface;
use Phptg\BotApi\ParseResult\ValueProcessor\TrueValue;
use Phptg\BotApi\Transport\HttpMethod;

/**
* @see https://core.telegram.org/bots/api#removemyprofilephoto
*
* @template-implements MethodInterface<true>
*
* @api
*/
final readonly class RemoveMyProfilePhoto implements MethodInterface
{
public function getHttpMethod(): HttpMethod
{
return HttpMethod::POST;
}

public function getApiMethod(): string
{
return 'removeMyProfilePhoto';
}

public function getData(): array
{
return [];
}

public function getResultType(): TrueValue
{
return new TrueValue();
}
}
51 changes: 51 additions & 0 deletions src/Method/SetMyProfilePhoto.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace Phptg\BotApi\Method;

use Phptg\BotApi\FileCollector;
use Phptg\BotApi\MethodInterface;
use Phptg\BotApi\ParseResult\ValueProcessor\TrueValue;
use Phptg\BotApi\Transport\HttpMethod;
use Phptg\BotApi\Type\InputProfilePhoto;

/**
* @see https://core.telegram.org/bots/api#setmyprofilephoto
*
* @template-implements MethodInterface<true>
*
* @api
*/
final readonly class SetMyProfilePhoto implements MethodInterface
{
public function __construct(
private InputProfilePhoto $photo,
) {}

public function getHttpMethod(): HttpMethod
{
return HttpMethod::POST;
}

public function getApiMethod(): string
{
return 'setMyProfilePhoto';
}

public function getData(): array
{
$fileCollector = new FileCollector();
$photo = $this->photo->toRequestArray($fileCollector);

return [
'photo' => $photo,
...$fileCollector->get(),
];
}

public function getResultType(): TrueValue
{
return new TrueValue();
}
}
33 changes: 33 additions & 0 deletions src/TelegramBotApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
use Phptg\BotApi\Method\GetMyStarBalance;
use Phptg\BotApi\Method\GetUserChatBoosts;
use Phptg\BotApi\Method\GetUserGifts;
use Phptg\BotApi\Method\GetUserProfileAudios;
use Phptg\BotApi\Method\GetUserProfilePhotos;
use Phptg\BotApi\Method\GiftPremiumSubscription;
use Phptg\BotApi\Method\HideGeneralForumTopic;
Expand All @@ -82,6 +83,7 @@
use Phptg\BotApi\Method\PromoteChatMember;
use Phptg\BotApi\Method\RepostStory;
use Phptg\BotApi\Method\RemoveBusinessAccountProfilePhoto;
use Phptg\BotApi\Method\RemoveMyProfilePhoto;
use Phptg\BotApi\Method\RemoveChatVerification;
use Phptg\BotApi\Method\RemoveUserVerification;
use Phptg\BotApi\Method\ReopenForumTopic;
Expand Down Expand Up @@ -123,6 +125,7 @@
use Phptg\BotApi\Method\SetMyDefaultAdministratorRights;
use Phptg\BotApi\Method\SetMyDescription;
use Phptg\BotApi\Method\SetMyName;
use Phptg\BotApi\Method\SetMyProfilePhoto;
use Phptg\BotApi\Method\SetMyShortDescription;
use Phptg\BotApi\Method\SetUserEmojiStatus;
use Phptg\BotApi\Method\Sticker\AddStickerToSet;
Expand Down Expand Up @@ -236,6 +239,7 @@
use Phptg\BotApi\Type\Update\WebhookInfo;
use Phptg\BotApi\Type\User;
use Phptg\BotApi\Type\UserChatBoosts;
use Phptg\BotApi\Type\UserProfileAudios;
use Phptg\BotApi\Type\UserProfilePhotos;

use function extension_loaded;
Expand Down Expand Up @@ -1459,6 +1463,19 @@ public function getUserGifts(
);
}

/**
* @see https://core.telegram.org/bots/api#getuserprofileaudios
*/
public function getUserProfileAudios(
int $userId,
?int $offset = null,
?int $limit = null,
): FailResult|UserProfileAudios {
return $this->call(
new GetUserProfileAudios($userId, $offset, $limit),
);
}

/**
* @see https://core.telegram.org/bots/api#getuserprofilephotos
*/
Expand Down Expand Up @@ -1683,6 +1700,14 @@ public function removeBusinessAccountProfilePhoto(
);
}

/**
* @see https://core.telegram.org/bots/api#removemyprofilephoto
*/
public function removeMyProfilePhoto(): FailResult|true
{
return $this->call(new RemoveMyProfilePhoto());
}

/**
* @see https://core.telegram.org/bots/api#removechatverification
*/
Expand Down Expand Up @@ -2956,6 +2981,14 @@ public function setMyName(?string $name = null, ?string $languageCode = null): F
return $this->call(new SetMyName($name, $languageCode));
}

/**
* @see https://core.telegram.org/bots/api#setmyprofilephoto
*/
public function setMyProfilePhoto(InputProfilePhoto $photo): FailResult|true
{
return $this->call(new SetMyProfilePhoto($photo));
}

/**
* @see https://core.telegram.org/bots/api#setmyshortdescription
*/
Expand Down
1 change: 1 addition & 0 deletions src/Type/ChatFullInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,6 @@ public function __construct(
public ?UserRating $rating = null,
public ?UniqueGiftColors $uniqueGiftColors = null,
public ?int $paidMessageStarCount = null,
public ?Audio $firstProfileAudio = null,
) {}
}
17 changes: 17 additions & 0 deletions src/Type/ChatOwnerChanged.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Phptg\BotApi\Type;

/**
* @see https://core.telegram.org/bots/api#chatownerchanged
*
* @api
*/
final readonly class ChatOwnerChanged
{
public function __construct(
public User $newOwner,
) {}
}
17 changes: 17 additions & 0 deletions src/Type/ChatOwnerLeft.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Phptg\BotApi\Type;

/**
* @see https://core.telegram.org/bots/api#chatownerleft
*
* @api
*/
final readonly class ChatOwnerLeft
{
public function __construct(
public ?User $newOwner = null,
) {}
}
4 changes: 4 additions & 0 deletions src/Type/InlineKeyboardButton.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@ public function __construct(
public ?CallbackGame $callbackGame = null,
public ?bool $pay = null,
public ?CopyTextButton $copyText = null,
public ?string $iconCustomEmojiId = null,
public ?string $style = null,
) {}

public function toRequestArray(): array
{
return array_filter(
[
'text' => $this->text,
'icon_custom_emoji_id' => $this->iconCustomEmojiId,
'style' => $this->style,
'url' => $this->url,
'callback_data' => $this->callbackData,
'web_app' => $this->webApp?->toRequestArray(),
Expand Down
4 changes: 4 additions & 0 deletions src/Type/KeyboardButton.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ public function __construct(
public ?bool $requestLocation = null,
public ?KeyboardButtonPollType $requestPoll = null,
public ?WebAppInfo $webApp = null,
public ?string $iconCustomEmojiId = null,
public ?string $style = null,
) {}

public function toRequestArray(): array
{
return array_filter(
[
'text' => $this->text,
'icon_custom_emoji_id' => $this->iconCustomEmojiId,
'style' => $this->style,
'request_users' => $this->requestUsers?->toRequestArray(),
'request_chat' => $this->requestChat?->toRequestArray(),
'request_contact' => $this->requestContact,
Expand Down
2 changes: 2 additions & 0 deletions src/Type/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,7 @@ public function __construct(
public ?SuggestedPostDeclined $suggestedPostDeclined = null,
public ?SuggestedPostPaid $suggestedPostPaid = null,
public ?SuggestedPostRefunded $suggestedPostRefunded = null,
public ?ChatOwnerLeft $chatOwnerLeft = null,
public ?ChatOwnerChanged $chatOwnerChanged = null,
) {}
}
1 change: 1 addition & 0 deletions src/Type/UniqueGift.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ public function __construct(
public ?true $isFromBlockchain = null,
public ?UniqueGiftColors $colors = null,
public ?Chat $publisherChat = null,
public ?true $isBurned = null,
) {}
}
1 change: 1 addition & 0 deletions src/Type/UniqueGiftModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ public function __construct(
public string $name,
public Sticker $sticker,
public int $rarityPerMille,
public ?string $rarity = null,
) {}
}
2 changes: 2 additions & 0 deletions src/Type/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public function __construct(
public ?bool $canConnectToBusiness = null,
public ?bool $hasMainWebApp = null,
public ?bool $hasTopicsEnabled = null,
public ?bool $allowsUsersToCreateTopics = null,
) {}

public function toRequestArray(): array
Expand All @@ -46,6 +47,7 @@ public function toRequestArray(): array
'can_connect_to_business' => $this->canConnectToBusiness,
'has_main_web_app' => $this->hasMainWebApp,
'has_topics_enabled' => $this->hasTopicsEnabled,
'allows_users_to_create_topics' => $this->allowsUsersToCreateTopics,
],
static fn(mixed $value): bool => $value !== null,
);
Expand Down
24 changes: 24 additions & 0 deletions src/Type/UserProfileAudios.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Phptg\BotApi\Type;

use Phptg\BotApi\ParseResult\ValueProcessor\ArrayOfObjectsValue;

/**
* @see https://core.telegram.org/bots/api#userprofileaudios
*
* @api
*/
final readonly class UserProfileAudios
{
/**
* @param Audio[] $audios
*/
public function __construct(
public int $totalCount,
#[ArrayOfObjectsValue(Audio::class)]
public array $audios,
) {}
}
Loading
Loading