From 847e415a572b5cc66096a15f964445cb9be45643 Mon Sep 17 00:00:00 2001 From: miya0v0 Date: Thu, 12 Feb 2026 19:48:35 +0800 Subject: [PATCH] Support Telegram Bot API 9.4 (#250) Add support for Bot API 9.4 (February 9, 2026) with the following changes: New methods: setMyProfilePhoto, removeMyProfilePhoto, getUserProfileAudios, repostStory New types: VideoQuality, ChatOwnerLeft, ChatOwnerChanged, UserProfileAudios, UserRating New fields on existing types: - User: allows_users_to_create_topics - Video: qualities - Message: chat_owner_left, chat_owner_changed - InlineKeyboardButton/KeyboardButton: icon_custom_emoji_id, style - ChatFullInfo: rating, first_profile_audio - UniqueGiftModel: rarity - UniqueGift: is_burned - ForumTopic/ForumTopicCreated: is_name_implicit - ChecklistTask: completed_by_chat - ForwardMessageParams/CopyMessageParams: message_effect_id --- CHANGELOG.md | 27 +++++++++++++++++++++++++++ README.md | 2 +- methods.go | 28 ++++++++++++++++++++++++++++ methods_params.go | 24 ++++++++++++++++++++++++ models/chat.go | 2 ++ models/checklist.go | 1 + models/forum.go | 2 ++ models/gift.go | 2 ++ models/message.go | 12 ++++++++++++ models/reply_markup.go | 8 ++++++-- models/user.go | 11 +++++++++-- models/user_rating.go | 9 +++++++++ models/video.go | 33 ++++++++++++++++++++++----------- 13 files changed, 145 insertions(+), 16 deletions(-) create mode 100644 models/user_rating.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f77576a..4a7f3d77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog +## v1.19.0 (2026-02-12) + +- support API 9.4 (February 9, 2026 update) + - Bot Profile Management: + - Added `setMyProfilePhoto` and `removeMyProfilePhoto` methods + - Forum Topics in Private Chats: + - Added `allows_users_to_create_topics` field to User + - Added `is_name_implicit` field to ForumTopic and ForumTopicCreated + - Colored Buttons: + - Added `style` and `icon_custom_emoji_id` fields to KeyboardButton and InlineKeyboardButton + - Video Quality: + - Added VideoQuality type and `qualities` field to Video + - Chat Owner Events: + - Added ChatOwnerLeft and ChatOwnerChanged types + - Added `chat_owner_left` and `chat_owner_changed` fields to Message + - User Profile Audios: + - Added UserProfileAudios type and `getUserProfileAudios` method + - Added `first_profile_audio` field to ChatFullInfo + - Gifts: + - Added `rarity` field to UniqueGiftModel + - Added `is_burned` field to UniqueGift + - Miscellaneous: + - Added `repostStory` method + - Added UserRating type and `rating` field to ChatFullInfo + - Added `completed_by_chat` field to ChecklistTask + - Added `message_effect_id` to ForwardMessageParams and CopyMessageParams + ## v1.18.0 (2026-01-23) - support API 9.3 (December 31, 2025 update) diff --git a/README.md b/README.md index 3208034f..dd7701ba 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ > [Telegram Group](https://t.me/gotelegrambotui) -> Supports Bot API version: [9.3](https://core.telegram.org/bots/api#december-31-2025) from December 31, 2025 +> Supports Bot API version: [9.4](https://core.telegram.org/bots/api#february-9-2026) from February 9, 2026 It's a Go zero-dependencies telegram bot framework diff --git a/methods.go b/methods.go index 68e0a393..55e15207 100644 --- a/methods.go +++ b/methods.go @@ -1125,3 +1125,31 @@ func (b *Bot) SendMessageDraft(ctx context.Context, params *SendMessageDraftPara err := b.rawRequest(ctx, "sendMessageDraft", params, &result) return result, err } + +// RepostStory https://core.telegram.org/bots/api#repoststory +func (b *Bot) RepostStory(ctx context.Context, params *RepostStoryParams) (*models.Story, error) { + result := &models.Story{} + err := b.rawRequest(ctx, "repostStory", params, &result) + return result, err +} + +// SetMyProfilePhoto https://core.telegram.org/bots/api#setmyprofilephoto +func (b *Bot) SetMyProfilePhoto(ctx context.Context, params *SetMyProfilePhotoParams) (bool, error) { + var result bool + err := b.rawRequest(ctx, "setMyProfilePhoto", params, &result) + return result, err +} + +// RemoveMyProfilePhoto https://core.telegram.org/bots/api#removemyprofilephoto +func (b *Bot) RemoveMyProfilePhoto(ctx context.Context) (bool, error) { + var result bool + err := b.rawRequest(ctx, "removeMyProfilePhoto", nil, &result) + return result, err +} + +// GetUserProfileAudios https://core.telegram.org/bots/api#getuserprofileaudios +func (b *Bot) GetUserProfileAudios(ctx context.Context, params *GetUserProfileAudiosParams) (*models.UserProfileAudios, error) { + result := &models.UserProfileAudios{} + err := b.rawRequest(ctx, "getUserProfileAudios", params, &result) + return result, err +} diff --git a/methods_params.go b/methods_params.go index ccbe7e80..e72f0312 100644 --- a/methods_params.go +++ b/methods_params.go @@ -47,6 +47,7 @@ type ForwardMessageParams struct { DisableNotification bool `json:"disable_notification,omitempty"` ProtectContent bool `json:"protect_content,omitempty"` SuggestedPostParameters *models.SuggestedPostParameters `json:"suggested_post_parameters,omitempty"` + MessageEffectID string `json:"message_effect_id,omitempty"` MessageID int `json:"message_id"` } @@ -77,6 +78,7 @@ type CopyMessageParams struct { ProtectContent bool `json:"protect_content,omitempty"` AllowPaidBroadcast bool `json:"allow_paid_broadcast,omitempty"` SuggestedPostParameters *models.SuggestedPostParameters `json:"suggested_post_parameters,omitempty"` + MessageEffectID string `json:"message_effect_id,omitempty"` ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } @@ -1304,3 +1306,25 @@ type SendMessageDraftParams struct { ParseMode models.ParseMode `json:"parse_mode,omitempty"` Entities []models.MessageEntity `json:"entities,omitempty"` } + +// RepostStoryParams https://core.telegram.org/bots/api#repoststory +type RepostStoryParams struct { + BusinessConnectionID string `json:"business_connection_id"` + FromChatID int64 `json:"from_chat_id"` + FromStoryID int `json:"from_story_id"` + ActivePeriod int `json:"active_period"` + PostToChatPage bool `json:"post_to_chat_page,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` +} + +// SetMyProfilePhotoParams https://core.telegram.org/bots/api#setmyprofilephoto +type SetMyProfilePhotoParams struct { + Photo models.InputProfilePhoto `json:"photo"` +} + +// GetUserProfileAudiosParams https://core.telegram.org/bots/api#getuserprofileaudios +type GetUserProfileAudiosParams struct { + UserID int64 `json:"user_id"` + Offset int `json:"offset,omitempty"` + Limit int `json:"limit,omitempty"` +} diff --git a/models/chat.go b/models/chat.go index ef94517f..f3ffc8fb 100644 --- a/models/chat.go +++ b/models/chat.go @@ -153,4 +153,6 @@ type ChatFullInfo struct { LinkedChatID int64 `json:"linked_chat_id,omitempty"` Location *ChatLocation `json:"location,omitempty"` PaidMessageStarCount int `json:"paid_message_star_count,omitempty"` + Rating *UserRating `json:"rating,omitempty"` + FirstProfileAudio *Audio `json:"first_profile_audio,omitempty"` } diff --git a/models/checklist.go b/models/checklist.go index 92bb541e..7ecc2224 100644 --- a/models/checklist.go +++ b/models/checklist.go @@ -6,6 +6,7 @@ type ChecklistTask struct { Text string `json:"text"` TextEntities []MessageEntity `json:"text_entities,omitempty"` CompletedByUser *User `json:"completed_by_user,omitempty"` + CompletedByChat *Chat `json:"completed_by_chat,omitempty"` CompletionDate int `json:"completion_date,omitempty"` } diff --git a/models/forum.go b/models/forum.go index 66841998..747cd493 100644 --- a/models/forum.go +++ b/models/forum.go @@ -6,6 +6,7 @@ type ForumTopic struct { Name string `json:"name"` IconColor int `json:"icon_color,omitempty"` IconCustomEmojiID string `json:"icon_custom_emoji_id,omitempty"` + IsNameImplicit bool `json:"is_name_implicit,omitempty"` } // ForumTopicCreated https://core.telegram.org/bots/api#forumtopiccreated @@ -13,6 +14,7 @@ type ForumTopicCreated struct { Name string `json:"name"` IconColor int `json:"icon_color"` IconCustomEmojiID string `json:"icon_custom_emoji_id,omitempty"` + IsNameImplicit bool `json:"is_name_implicit,omitempty"` } // ForumTopicClosed https://core.telegram.org/bots/api#forumtopicclosed diff --git a/models/gift.go b/models/gift.go index 09eb57a6..1cd4358e 100644 --- a/models/gift.go +++ b/models/gift.go @@ -146,6 +146,7 @@ type UniqueGift struct { Backdrop UniqueGiftBackdrop `json:"backdrop"` IsPremium bool `json:"is_premium,omitempty"` IsFromBlockchain bool `json:"is_from_blockchain,omitempty"` + IsBurned bool `json:"is_burned,omitempty"` Colors *UniqueGiftColors `json:"colors,omitempty"` PublisherChat *Chat `json:"publisher_chat,omitempty"` } @@ -155,6 +156,7 @@ type UniqueGiftModel struct { Name string `json:"name"` Sticker Sticker `json:"sticker"` RarityPerMille int `json:"rarity_per_mille"` + Rarity string `json:"rarity,omitempty"` } // UniqueGiftSymbol https://core.telegram.org/bots/api#uniquegiftsymbol diff --git a/models/message.go b/models/message.go index d312b521..586fc021 100644 --- a/models/message.go +++ b/models/message.go @@ -68,6 +68,16 @@ type MessageAutoDeleteTimerChanged struct { MessageAutoDeleteTime int `json:"message_auto_delete_time"` } +// ChatOwnerLeft https://core.telegram.org/bots/api#chatownerleft +type ChatOwnerLeft struct { + NewOwner *User `json:"new_owner,omitempty"` +} + +// ChatOwnerChanged https://core.telegram.org/bots/api#chatownerchanged +type ChatOwnerChanged struct { + NewOwner User `json:"new_owner"` +} + // Message https://core.telegram.org/bots/api#message type Message struct { ID int `json:"message_id"` @@ -162,6 +172,8 @@ type Message struct { GiveawayWinners *GiveawayWinners `json:"giveaway_winners,omitempty"` GiveawayCompleted *GiveawayCompleted `json:"giveaway_completed,omitempty"` PaidMessagePriceChanged *PaidMessagePriceChanged `json:"paid_message_price_changed,omitempty"` + ChatOwnerLeft *ChatOwnerLeft `json:"chat_owner_left,omitempty"` + ChatOwnerChanged *ChatOwnerChanged `json:"chat_owner_changed,omitempty"` SuggestedPostApproved *SuggestedPostApproved `json:"suggested_post_approved,omitempty"` SuggestedPostApprovalFailed *SuggestedPostApprovalFailed `json:"suggested_post_approval_failed,omitempty"` SuggestedPostDeclined *SuggestedPostDeclined `json:"suggested_post_declined,omitempty"` diff --git a/models/reply_markup.go b/models/reply_markup.go index cd0d3edc..a59bc8fe 100644 --- a/models/reply_markup.go +++ b/models/reply_markup.go @@ -32,6 +32,8 @@ type CopyTextButton struct { // InlineKeyboardButton https://core.telegram.org/bots/api#inlinekeyboardbutton type InlineKeyboardButton struct { Text string `json:"text"` + IconCustomEmojiID string `json:"icon_custom_emoji_id,omitempty"` + Style string `json:"style,omitempty"` URL string `json:"url,omitempty"` CallbackData string `json:"callback_data,omitempty"` WebApp *WebAppInfo `json:"web_app,omitempty"` @@ -56,8 +58,10 @@ type ReplyKeyboardMarkup struct { // KeyboardButton https://core.telegram.org/bots/api#keyboardbutton type KeyboardButton struct { - Text string `json:"text"` - RequestUser *KeyboardButtonRequestUsers `json:"request_user,omitempty"` + Text string `json:"text"` + IconCustomEmojiID string `json:"icon_custom_emoji_id,omitempty"` + Style string `json:"style,omitempty"` + RequestUser *KeyboardButtonRequestUsers `json:"request_user,omitempty"` RequestUsers *KeyboardButtonRequestUsers `json:"request_users,omitempty"` RequestChat *KeyboardButtonRequestChat `json:"request_chat,omitempty"` RequestContact bool `json:"request_contact,omitempty"` diff --git a/models/user.go b/models/user.go index 712f888e..6274e397 100644 --- a/models/user.go +++ b/models/user.go @@ -19,6 +19,13 @@ type User struct { CanJoinGroups bool `json:"can_join_groups,omitempty"` CanReadAllGroupMessages bool `json:"can_read_all_group_messages,omitempty"` SupportInlineQueries bool `json:"support_inline_queries,omitempty"` - CanConnectToBusiness bool `json:"can_connect_to_business,omitempty"` - HasTopicsEnabled bool `json:"has_topics_enabled,omitempty"` + CanConnectToBusiness bool `json:"can_connect_to_business,omitempty"` + HasTopicsEnabled bool `json:"has_topics_enabled,omitempty"` + AllowsUsersToCreateTopics bool `json:"allows_users_to_create_topics,omitempty"` +} + +// UserProfileAudios https://core.telegram.org/bots/api#userprofileaudios +type UserProfileAudios struct { + TotalCount int `json:"total_count"` + Audios []Audio `json:"audios"` } diff --git a/models/user_rating.go b/models/user_rating.go new file mode 100644 index 00000000..4c4cd87a --- /dev/null +++ b/models/user_rating.go @@ -0,0 +1,9 @@ +package models + +// UserRating https://core.telegram.org/bots/api#userrating +type UserRating struct { + Level int `json:"level"` + Rating int `json:"rating"` + CurrentLevelRating int `json:"current_level_rating"` + NextLevelRating int `json:"next_level_rating,omitempty"` +} diff --git a/models/video.go b/models/video.go index 0f00a56f..24fa1d31 100644 --- a/models/video.go +++ b/models/video.go @@ -1,16 +1,27 @@ package models +// VideoQuality https://core.telegram.org/bots/api#videoquality +type VideoQuality struct { + FileID string `json:"file_id"` + FileUniqueID string `json:"file_unique_id"` + Width int `json:"width"` + Height int `json:"height"` + Codec string `json:"codec"` + FileSize int64 `json:"file_size,omitempty"` +} + // Video https://core.telegram.org/bots/api#video type Video struct { - FileID string `json:"file_id"` - FileUniqueID string `json:"file_unique_id"` - Width int `json:"width"` - Height int `json:"height"` - Duration int `json:"duration"` - Thumbnail *PhotoSize `json:"thumbnail,omitempty"` - Cover []PhotoSize `json:"cover,omitempty"` - StartTimestamp int `json:"start_timestamp,omitempty"` - FileName string `json:"file_name,omitempty"` - MimeType string `json:"mime_type,omitempty"` - FileSize int64 `json:"file_size,omitempty"` + FileID string `json:"file_id"` + FileUniqueID string `json:"file_unique_id"` + Width int `json:"width"` + Height int `json:"height"` + Duration int `json:"duration"` + Thumbnail *PhotoSize `json:"thumbnail,omitempty"` + Cover []PhotoSize `json:"cover,omitempty"` + StartTimestamp int `json:"start_timestamp,omitempty"` + FileName string `json:"file_name,omitempty"` + MimeType string `json:"mime_type,omitempty"` + FileSize int64 `json:"file_size,omitempty"` + Qualities []VideoQuality `json:"qualities,omitempty"` }