Update for Telegram Bot API 10.3 - #10
Merged
Merged
Conversation
Owner
|
Looks solid. Thanks! I left a few minor comments. |
Author
|
Hi, unfortunately I don't see any comments right now. i will be glad to fix any issues. |
luzrain
reviewed
Sep 24, 2026
Owner
|
Check now. Thanks. |
- Remove reflection-based parameter position/name/type tests - Remove positional-argument construction tests - Remove nested InputFile list from README
Author
|
Fixed |
Owner
|
Thank you! |
Owner
|
Released in v3.18.0. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bot API 10.3
Brings the library from Bot API 10.1 to 10.3, covering both skipped releases: 10.2 (July 14, 2026) and 10.3 (August 24, 2026).
48 new classes under
src/, 36 modified source files, 8 new test files with 5 test doubles and 4 fixtures. The README badge moves to 10.3.Rich messages
Bot API 10.2 introduced the outgoing half of the rich block system, and 10.3 extended both halves.
New namespace
Luzrain\TelegramBotApi\Type\InputRichBlockholds 26 classes: theInputRichBlockbase, 24 concrete blocks andInputRichBlockListItem. It mirrors the existing incomingType\RichBlockfamily. I kept it separate because merging would leave a single directory of 54 files.InputRichMessagegainsblocksandmedia. Two new types support them:InputRichMessageMediaaddresses media from markdown or HTML throughtg://photo?id=links, andInputMediaVoiceNotecarries a voice message.10.3 adds
RichMessageButton, which bothRichTextButtonandRichBlockButtonsreference, plusRichBlockExpandableBlockQuotation,RichBlockDocumentand their input counterparts. Tables gainis_compact.Telegram reuses
RichBlockCaption,RichBlockTableCellandLocationas input types in 10.2. All three hadprotectedconstructors, so a caller could not buildInputRichBlockPhoto,InputRichBlockTableorInputRichBlockMap. I widened the three constructors topublic.Ephemeral messages
10.2 introduced ephemeral messages and 10.3 replaced their parameter shape before this library ever shipped the first form. The code carries only the 10.3 object,
EphemeralMessageParameters, and never the intermediatereceiver_user_id/callback_query_idpair.Five new methods:
editEphemeralMessageText,editEphemeralMessageMedia,editEphemeralMessageCaption,editEphemeralMessageReplyMarkup,deleteEphemeralMessage.Fourteen
send*methods acceptephemeralMessageParameters. Seven others (sendMediaGroup,sendPoll,sendDice,sendChecklist,sendGame,sendInvoice,sendPaidMedia) do not, matching the documentation.Messagegainsreceiver_userandephemeral_message_id.BotCommandgainsis_ephemeral.ReplyParametersgainsephemeral_message_idand itsmessage_idbecomes optional.10.2 also rewrote descriptions on fields it did not otherwise touch. Those rewrites appear in no changelog entry. Six of them changed meaning and are now reflected:
Message.message_idreads 0 for ephemeral messages,Message.reply_to_messagemay be omitted, threeReplyParametersfields gained ephemeral caveats, andsendLocation.live_periodmust be 0 for ephemeral messages.Communities
Community,CommunityChatAdded,CommunityChatRemovedandCommunityChatJoined, with the three matching service-message fields onMessageandcommunityonChatFullInfo.Updates
Two new update types with handlers:
subscription(BotSubscriptionUpdated) andstopped_message_generation(MessageGenerationStopped). Both appear inUpdate::UPDATE_TYPESand both have anEventsubclass.Reply markup and the rest
DisabledButtonplusdisabledonInlineKeyboardButton.force_replyonInlineKeyboardMarkupandReplyKeyboardMarkup.can_send_welcome_messagesonChatAdministratorRights,ChatMemberAdministratorandpromoteChatMember.can_stopandkeep_on_stopon both draft methods.text,entitiesandis_privateonUniqueGiftInfo.Behaviour change in BotApi
BotApi::call()used to findInputFileinstances through a closure that checked four fixed property names, plus a special case for themediaarray ofsendMediaGroupandsendPaidMedia. Rich blocks nest to arbitrary depth and carryInputMediaobjects inside them, so that scan cannot reach them.The closure now walks the parameter graph: it collects an
InputFile, recurses into an array, and recurses through the properties of aType. Both special cases went away.This also fixes uploads that never worked.
InputSticker,InputProfilePhotoStatic,InputProfilePhotoAnimated,InputStoryContentPhotoandInputStoryContentVideomatched neither old branch, so passing a local file tocreateNewStickerSet,addStickerToSet,replaceStickerInSet,postStory,editStory,setMyProfilePhotoorsetBusinessAccountProfilePhotoproduced JSON referencingattach://<name>with no matching multipart part. Telegram rejected those calls. They work now, andtests/BotApiFileUploadTest.phpguards the sticker case.One
InputFileinstance referenced from two places in the same request now streams once. The old code opened the file twice and dropped the first handle.Compatibility
All new constructor parameters go at the end, including where the documentation places them earlier.
ephemeralMessageParameterssits fifth in thesendMessagedocumentation and last in the code.UniqueGiftInfogets its three new fields appended rather than inserted afterorigin. Serialization runs by name, so the wire format matches either way, and positional calls keep working.tests/EphemeralMessageTest.phppins this.ReplyParameters::$messageIdchanges from requiredinttoint|nullwith a default. Callers passing it stay valid.ChatMemberAdministratorplacescan_send_welcome_messagesbeforecustom_title, as documented. Its constructor isprotectedand hydration maps by name, so no caller is affected.Widening three constructors from
protectedtopubliccannot break a caller.Tests
114 tests and 539 assertions, up from 26 and 304. I changed no existing test and no existing fixture:
git diff -- tests/against the base commit lists new files only.Four areas the five-check gate cannot see:
tests/BotApiFileUploadTest.phpparses the multipart body and asserts everyattach://<name>reference has a part of that name, plus the GET/POST switch and the request URL.TYPEconstants against their incoming twins. A mistyped discriminator passes every static check and fails only against Telegram.return truewould hijack unrelated updates and pass a positive-only test.Update::UPDATE_TYPESagainst the constructor properties. A missing entry drops that update type for anyone callingsetWebhook(allowedUpdates:), and nothing reports it.The five PSR-7/17/18 doubles in
tests/Helper/add no dependency tocomposer.json.Not implemented
10.2 hardened Mini App security by rejecting calls from origins other than the Mini App domain. Telegram enforces this server side and exposes the opt-out through @Botfather. No client code applies.
10.3 announced
tg://document?id=links for general file uploads in rich messages.InputRichMessage.mediaandInputRichMessageMediaalready cover the mechanism.Pre-existing issues left alone
Three divergences predate this change and stay untouched:
UniqueGiftInfo::$lastResaleCurrencyand$lastResaleAmountsay "toncoins" and "nanotoncoins" where Telegram now says "TON grams" and "nanograms".InlineKeyboardButton::$copyTexthas a stray space in its union type.Verification
All five pass on PHP 8.2.33 with Psalm 6.17.2, PHP CS Fixer 3.95.25 and PHPUnit 10.5.64.