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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Telegram Bot API for PHP Change Log

## 0.17 March 1, 2026

- New #188: Add `unixTime` and `dateTimeFormat` fields to `MessageEntity` type.
- New #188: Add `DATE_TIME` constant to `MessageEntityType`.
- New #188: Add `tag` field to `ChatMemberMember` and `ChatMemberRestricted` types.
- New #188: Add `canEditTag` field to `ChatMemberRestricted` and `ChatPermissions` types.
- New #188: Add `SetChatMemberTag` method.
- New #188: Add `canManageTags` field to `ChatMemberAdministrator` and `ChatAdministratorRights` types.
- New #188: Add `canManageTags` parameter to `PromoteChatMember` method.
- New #188: Add `senderTag` field to `Message` type.

## 0.16 February 28, 2026

- Chg #186: Remove `PsrTransport`, `PsrWebhookResponseFactory` and `StreamResourceReader` classes.
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.4 (February 9, 2026) is **fully supported**.
✔️ Telegram Bot API 9.5 (March 1, 2026) is **fully supported**.

♻️ **Zero dependencies** — no third-party libraries, only native PHP.

Expand Down
1 change: 1 addition & 0 deletions src/Constant/MessageEntityType.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ final class MessageEntityType
public const TEXT_LINK = 'text_link';
public const TEXT_MENTION = 'text_mention';
public const CUSTOM_EMOJI = 'custom_emoji';
public const DATE_TIME = 'date_time';
}
2 changes: 2 additions & 0 deletions src/Method/PromoteChatMember.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public function __construct(
private ?bool $canPinMessages = null,
private ?bool $canManageTopics = null,
private ?bool $canManageDirectMessages = null,
private ?bool $canManageTags = null,
) {}

public function getHttpMethod(): HttpMethod
Expand Down Expand Up @@ -68,6 +69,7 @@ public function getData(): array
'can_pin_messages' => $this->canPinMessages,
'can_manage_topics' => $this->canManageTopics,
'can_manage_direct_messages' => $this->canManageDirectMessages,
'can_manage_tags' => $this->canManageTags,
],
static fn(mixed $value): bool => $value !== null,
);
Expand Down
50 changes: 50 additions & 0 deletions src/Method/SetChatMemberTag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace Phptg\BotApi\Method;

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

/**
* @see https://core.telegram.org/bots/api#setchatmembertag
*
* @template-implements MethodInterface<true>
*/
final readonly class SetChatMemberTag implements MethodInterface
{
public function __construct(
private int|string $chatId,
private int $userId,
private ?string $tag = null,
) {}

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

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

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

public function getResultType(): TrueValue
{
return new TrueValue();
}
}
16 changes: 16 additions & 0 deletions src/TelegramBotApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
use Phptg\BotApi\Method\SetBusinessAccountUsername;
use Phptg\BotApi\Method\SetChatAdministratorCustomTitle;
use Phptg\BotApi\Method\SetChatDescription;
use Phptg\BotApi\Method\SetChatMemberTag;
use Phptg\BotApi\Method\SetChatMenuButton;
use Phptg\BotApi\Method\SetChatPermissions;
use Phptg\BotApi\Method\SetChatPhoto;
Expand Down Expand Up @@ -1648,6 +1649,7 @@ public function promoteChatMember(
?bool $canPinMessages = null,
?bool $canManageTopics = null,
?bool $canManageDirectMessages = null,
?bool $canManageTags = null,
): FailResult|true {
return $this->call(
new PromoteChatMember(
Expand All @@ -1669,6 +1671,7 @@ public function promoteChatMember(
$canPinMessages,
$canManageTopics,
$canManageDirectMessages,
$canManageTags,
),
);
}
Expand Down Expand Up @@ -2840,6 +2843,19 @@ public function setChatAdministratorCustomTitle(
);
}

/**
* @see https://core.telegram.org/bots/api#setchatmembertag
*/
public function setChatMemberTag(
int|string $chatId,
int $userId,
?string $tag = null,
): FailResult|true {
return $this->call(
new SetChatMemberTag($chatId, $userId, $tag),
);
}

/**
* @see https://core.telegram.org/bots/api#setchatdescription
*/
Expand Down
2 changes: 2 additions & 0 deletions src/Type/ChatAdministratorRights.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function __construct(
public ?bool $canPinMessages = null,
public ?bool $canManageTopics = null,
public ?bool $canManageDirectMessages = null,
public ?bool $canManageTags = null,
) {}

public function toRequestArray(): array
Expand All @@ -50,6 +51,7 @@ public function toRequestArray(): array
'can_pin_messages' => $this->canPinMessages,
'can_manage_topics' => $this->canManageTopics,
'can_manage_direct_messages' => $this->canManageDirectMessages,
'can_manage_tags' => $this->canManageTags,
],
static fn(mixed $value): bool => $value !== null,
);
Expand Down
1 change: 1 addition & 0 deletions src/Type/ChatMemberAdministrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public function __construct(
public ?bool $canManageTopics = null,
public ?string $customTitle = null,
public ?bool $canManageDirectMessages = null,
public ?bool $canManageTags = null,
) {}

public function getStatus(): string
Expand Down
1 change: 1 addition & 0 deletions src/Type/ChatMemberMember.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
public function __construct(
public User $user,
public ?DateTimeImmutable $untilDate = null,
public ?string $tag = null,
) {}

public function getStatus(): string
Expand Down
2 changes: 2 additions & 0 deletions src/Type/ChatMemberRestricted.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ public function __construct(
public bool $canSendPolls,
public bool $canSendOtherMessages,
public bool $canAddWebPagePreviews,
public bool $canEditTag,
public bool $canChangeInfo,
public bool $canInviteUsers,
public bool $canPinMessages,
public bool $canManageTopics,
#[ChatMemberUntilDateValue]
public DateTimeImmutable|false $untilDate,
public ?string $tag = null,
) {}

public function getStatus(): string
Expand Down
2 changes: 2 additions & 0 deletions src/Type/ChatPermissions.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function __construct(
public ?bool $canSendPolls = null,
public ?bool $canSendOtherMessages = null,
public ?bool $canAddWebPagePreviews = null,
public ?bool $canEditTag = null,
public ?bool $canChangeInfo = null,
public ?bool $canInviteUsers = null,
public ?bool $canPinMessages = null,
Expand All @@ -42,6 +43,7 @@ public function toRequestArray(): array
'can_send_polls' => $this->canSendPolls,
'can_send_other_messages' => $this->canSendOtherMessages,
'can_add_web_page_previews' => $this->canAddWebPagePreviews,
'can_edit_tag' => $this->canEditTag,
'can_change_info' => $this->canChangeInfo,
'can_invite_users' => $this->canInviteUsers,
'can_pin_messages' => $this->canPinMessages,
Expand Down
1 change: 1 addition & 0 deletions src/Type/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public function __construct(
public ?Chat $senderChat = null,
public ?int $senderBoostCount = null,
public ?User $senderBusinessBot = null,
public ?string $senderTag = null,
public ?string $businessConnectionId = null,
public ?MessageOrigin $forwardOrigin = null,
public ?true $isTopicMessage = null,
Expand Down
9 changes: 9 additions & 0 deletions src/Type/MessageEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@

namespace Phptg\BotApi\Type;

use Phptg\BotApi\Constant\MessageEntityType;

/**
* @see https://core.telegram.org/bots/api#messageentity
*
* @api
*/
final readonly class MessageEntity
{
/**
* @param string $type Type of the entity ({@see MessageEntityType}).
*/
public function __construct(
public string $type,
public int $offset,
Expand All @@ -19,6 +24,8 @@ public function __construct(
public ?User $user = null,
public ?string $language = null,
public ?string $customEmojiId = null,
public ?int $unixTime = null,
public ?string $dateTimeFormat = null,
) {}

public function toRequestArray(): array
Expand All @@ -32,6 +39,8 @@ public function toRequestArray(): array
'user' => $this->user?->toRequestArray(),
'language' => $this->language,
'custom_emoji_id' => $this->customEmojiId,
'unix_time' => $this->unixTime,
'date_time_format' => $this->dateTimeFormat,
],
static fn(mixed $value): bool => $value !== null,
);
Expand Down
2 changes: 2 additions & 0 deletions tests/Method/PromoteChatMemberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public function testFull(): void
true,
true,
false,
true,
);

assertSame(
Expand All @@ -72,6 +73,7 @@ public function testFull(): void
'can_pin_messages' => true,
'can_manage_topics' => true,
'can_manage_direct_messages' => false,
'can_manage_tags' => true,
],
$method->getData(),
);
Expand Down
56 changes: 56 additions & 0 deletions tests/Method/SetChatMemberTagTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

namespace Phptg\BotApi\Tests\Method;

use PHPUnit\Framework\TestCase;
use Phptg\BotApi\Method\SetChatMemberTag;
use Phptg\BotApi\Transport\HttpMethod;
use Phptg\BotApi\Tests\Support\TestHelper;

use function PHPUnit\Framework\assertSame;
use function PHPUnit\Framework\assertTrue;

final class SetChatMemberTagTest extends TestCase
{
public function testBase(): void
{
$method = new SetChatMemberTag(1, 2);

assertSame(HttpMethod::POST, $method->getHttpMethod());
assertSame('setChatMemberTag', $method->getApiMethod());
assertSame(
[
'chat_id' => 1,
'user_id' => 2,
],
$method->getData(),
);
}

public function testFull(): void
{
$method = new SetChatMemberTag(1, 2, 'test');

assertSame(HttpMethod::POST, $method->getHttpMethod());
assertSame('setChatMemberTag', $method->getApiMethod());
assertSame(
[
'chat_id' => 1,
'user_id' => 2,
'tag' => 'test',
],
$method->getData(),
);
}

public function testPrepareResult(): void
{
$method = new SetChatMemberTag(1, 2);

$preparedResult = TestHelper::createSuccessStubApi(true)->call($method);

assertTrue($preparedResult);
}
}
1 change: 1 addition & 0 deletions tests/ParseResult/ValueProcessor/ChatMemberValueTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public static function dataBase(): array
'can_send_polls' => false,
'can_send_other_messages' => false,
'can_add_web_page_previews' => false,
'can_edit_tag' => false,
'can_change_info' => false,
'can_invite_users' => false,
'can_pin_messages' => false,
Expand Down
9 changes: 9 additions & 0 deletions tests/TelegramBotApi/TelegramBotApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2212,6 +2212,15 @@ public function testSetChatAdministratorCustomTitle(): void
assertTrue($result);
}

public function testSetChatMemberTag(): void
{
$api = TestHelper::createSuccessStubApi(true);

$result = $api->setChatMemberTag(1, 2, 'test');

assertTrue($result);
}

public function testSetChatPermissions(): void
{
$api = TestHelper::createSuccessStubApi(true);
Expand Down
4 changes: 4 additions & 0 deletions tests/Type/ChatAdministratorRightsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public function testBase(): void
assertNull($rights->canPinMessages);
assertNull($rights->canManageTopics);
assertNull($rights->canManageDirectMessages);
assertNull($rights->canManageTags);

assertSame(
[
Expand Down Expand Up @@ -73,6 +74,7 @@ public function testFromTelegramResult(): void
'can_pin_messages' => false,
'can_manage_topics' => true,
'can_manage_direct_messages' => false,
'can_manage_tags' => true,
], null, ChatAdministratorRights::class);

assertTrue($type->isAnonymous);
Expand All @@ -91,6 +93,7 @@ public function testFromTelegramResult(): void
assertFalse($type->canPinMessages);
assertTrue($type->canManageTopics);
assertFalse($type->canManageDirectMessages);
assertTrue($type->canManageTags);
assertSame(
[
'is_anonymous' => true,
Expand All @@ -109,6 +112,7 @@ public function testFromTelegramResult(): void
'can_pin_messages' => false,
'can_manage_topics' => true,
'can_manage_direct_messages' => false,
'can_manage_tags' => true,
],
$type->toRequestArray(),
);
Expand Down
Loading