From 96a4c359a7100ec6fff4b48b4ad710f797279d7e Mon Sep 17 00:00:00 2001 From: Andrew Privalov Date: Wed, 10 Jan 2024 15:16:04 +0300 Subject: [PATCH] v7.0 (#55) * API v7.0 * readme --- CHANGELOG.md | 4 + README.md | 2 +- methods.go | 35 +++ methods_params.go | 578 +++++++++++++++++++++------------------ models/boost.go | 96 +++++++ models/boost_test.go | 72 +++++ models/callback_query.go | 14 +- models/chat.go | 6 + models/chat_member.go | 26 +- models/forum.go | 6 + models/giveaway.go | 38 +++ models/inline_query.go | 8 +- models/link_preview.go | 10 + models/message.go | 65 ++++- models/message_test.go | 55 ++++ models/reaction.go | 82 ++++++ models/reaction_test.go | 47 ++++ models/reply.go | 133 +++++++++ models/reply_markup.go | 23 +- models/reply_test.go | 110 ++++++++ models/update.go | 34 ++- 21 files changed, 1123 insertions(+), 321 deletions(-) create mode 100644 models/boost.go create mode 100644 models/boost_test.go create mode 100644 models/giveaway.go create mode 100644 models/link_preview.go create mode 100644 models/message_test.go create mode 100644 models/reaction.go create mode 100644 models/reaction_test.go create mode 100644 models/reply.go create mode 100644 models/reply_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 35a4ab8..3bc8500 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v1.0.0 (2024-01-10) + +- support API v7.0 + ## v0.8.3 (2023-12-07) - Fix typo for setChatDescription params (#49) diff --git a/README.md b/README.md index bd7a86f..be3d67b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ > [Telegram Group](https://t.me/gotelegrambotui) -> Supports Bot API version: [6.9](https://core.telegram.org/bots/api#september-22-2023) from September 22, 2023 +> Supports Bot API version: [7.0](https://core.telegram.org/bots/api#december-29-2023) from December 29, 2023 It's a Go zero-dependencies telegram bot framework diff --git a/methods.go b/methods.go index 018d263..606e7cd 100644 --- a/methods.go +++ b/methods.go @@ -62,6 +62,13 @@ func (b *Bot) ForwardMessage(ctx context.Context, params *ForwardMessageParams) return result, err } +// ForwardMessages https://core.telegram.org/bots/api#forwardmessages +func (b *Bot) ForwardMessages(ctx context.Context, params *ForwardMessagesParams) ([]models.Message, error) { + var result []models.Message + err := b.rawRequest(ctx, "forwardMessages", params, result) + return result, err +} + // CopyMessage https://core.telegram.org/bots/api#copymessage func (b *Bot) CopyMessage(ctx context.Context, params *CopyMessageParams) (*models.MessageID, error) { result := &models.MessageID{} @@ -69,6 +76,13 @@ func (b *Bot) CopyMessage(ctx context.Context, params *CopyMessageParams) (*mode return result, err } +// CopyMessages https://core.telegram.org/bots/api#copymessages +func (b *Bot) CopyMessages(ctx context.Context, params *CopyMessagesParams) ([]models.MessageID, error) { + var result []models.MessageID + err := b.rawRequest(ctx, "copyMessages", params, result) + return result, err +} + // SendPhoto https://core.telegram.org/bots/api#sendphoto func (b *Bot) SendPhoto(ctx context.Context, params *SendPhotoParams) (*models.Message, error) { mes := &models.Message{} @@ -181,6 +195,13 @@ func (b *Bot) SendChatAction(ctx context.Context, params *SendChatActionParams) return result, err } +// SetMessageReaction https://core.telegram.org/bots/api#setmessagereaction +func (b *Bot) SetMessageReaction(ctx context.Context, params *SetMessageReactionParams) (bool, error) { + var result bool + err := b.rawRequest(ctx, "setMessageReaction", params, result) + return result, err +} + // GetUserProfilePhotos https://core.telegram.org/bots/api#getuserprofilephotos func (b *Bot) GetUserProfilePhotos(ctx context.Context, params *GetUserProfilePhotosParams) (*models.UserProfilePhotos, error) { result := &models.UserProfilePhotos{} @@ -489,6 +510,13 @@ func (b *Bot) AnswerCallbackQuery(ctx context.Context, params *AnswerCallbackQue return result, err } +// GetUserChatBoosts https://core.telegram.org/bots/api#getuserchatboosts +func (b *Bot) GetUserChatBoosts(ctx context.Context, params *GetUserChatBoostsParams) (*models.UserChatBoosts, error) { + result := &models.UserChatBoosts{} + err := b.rawRequest(ctx, "getUserChatBoosts", params, &result) + return result, err +} + // SetMyCommands https://core.telegram.org/bots/api#setmycommands func (b *Bot) SetMyCommands(ctx context.Context, params *SetMyCommandsParams) (bool, error) { var result bool @@ -622,6 +650,13 @@ func (b *Bot) DeleteMessage(ctx context.Context, params *DeleteMessageParams) (b return result, err } +// DeleteMessages https://core.telegram.org/bots/api#deletemessages +func (b *Bot) DeleteMessages(ctx context.Context, params *DeleteMessagesParams) (bool, error) { + var result bool + err := b.rawRequest(ctx, "deleteMessages", params, &result) + return result, err +} + // SendSticker https://core.telegram.org/bots/api#sendsticker func (b *Bot) SendSticker(ctx context.Context, params *SendStickerParams) (*models.Message, error) { result := &models.Message{} diff --git a/methods_params.go b/methods_params.go index 3ec44cb..24873cb 100644 --- a/methods_params.go +++ b/methods_params.go @@ -18,20 +18,21 @@ type DeleteWebhookParams struct { DropPendingUpdates bool `json:"drop_pending_updates,omitempty"` } +// SendMessageParams https://core.telegram.org/bots/api#sendmessage type SendMessageParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Text string `json:"text"` - ParseMode models.ParseMode `json:"parse_mode,omitempty"` - Entities []models.MessageEntity `json:"entities,omitempty"` - DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` -} - + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Text string `json:"text"` + ParseMode models.ParseMode `json:"parse_mode,omitempty"` + Entities []models.MessageEntity `json:"entities,omitempty"` + LinkPreviewOptions *models.LinkPreviewOptions `json:"link_preview_options,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +} + +// ForwardMessageParams https://core.telegram.org/bots/api#forwardmessage type ForwardMessageParams struct { ChatID any `json:"chat_id"` MessageThreadID int `json:"message_thread_id,omitempty"` @@ -41,162 +42,183 @@ type ForwardMessageParams struct { MessageID int `json:"message_id"` } -type CopyMessageParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - FromChatID string `json:"from_chat_id"` - MessageID int `json:"message_id"` - Caption string `json:"caption,omitempty"` - ParseMode models.ParseMode `json:"parse_mode,omitempty"` - CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +// ForwardMessagesParams https://core.telegram.org/bots/api#forwardmessages +type ForwardMessagesParams struct { + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + FromChatID string `json:"from_chat_id"` + MessageIDs []int `json:"message_ids"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` } -type SendPhotoParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Photo models.InputFile `json:"photo"` - Caption string `json:"caption,omitempty"` - ParseMode models.ParseMode `json:"parse_mode,omitempty"` - CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` - HasSpoiler bool `json:"has_spoiler,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +// CopyMessageParams https://core.telegram.org/bots/api#copymessage +type CopyMessageParams struct { + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + FromChatID string `json:"from_chat_id"` + MessageID int `json:"message_id"` + Caption string `json:"caption,omitempty"` + ParseMode models.ParseMode `json:"parse_mode,omitempty"` + CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +} + +// CopyMessagesParams https://core.telegram.org/bots/api#copymessages +type CopyMessagesParams struct { + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + FromChatID string `json:"from_chat_id"` + MessageIDs []int `json:"message_ids"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + RemoveCaption bool `json:"remove_caption,omitempty"` } +// SendPhotoParams https://core.telegram.org/bots/api#sendphoto +type SendPhotoParams struct { + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Photo models.InputFile `json:"photo"` + Caption string `json:"caption,omitempty"` + ParseMode models.ParseMode `json:"parse_mode,omitempty"` + CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` + HasSpoiler bool `json:"has_spoiler,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +} + +// SendAudioParams https://core.telegram.org/bots/api#sendaudio type SendAudioParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Audio models.InputFile `json:"audio"` - Caption string `json:"caption,omitempty"` - ParseMode models.ParseMode `json:"parse_mode,omitempty"` - CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` - Duration int `json:"duration,omitempty"` - Performer string `json:"performer,omitempty"` - Title string `json:"title,omitempty"` - Thumbnail models.InputFile `json:"thumbnail,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` -} - + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Audio models.InputFile `json:"audio"` + Caption string `json:"caption,omitempty"` + ParseMode models.ParseMode `json:"parse_mode,omitempty"` + CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` + Duration int `json:"duration,omitempty"` + Performer string `json:"performer,omitempty"` + Title string `json:"title,omitempty"` + Thumbnail models.InputFile `json:"thumbnail,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +} + +// SendDocumentParams https://core.telegram.org/bots/api#senddocument type SendDocumentParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Document models.InputFile `json:"document"` - Thumbnail models.InputFile `json:"thumbnail,omitempty"` - Caption string `json:"caption,omitempty"` - ParseMode models.ParseMode `json:"parse_mode,omitempty"` - CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` - DisableContentTypeDetection bool `json:"disable_content_type_detection,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` -} - + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Document models.InputFile `json:"document"` + Thumbnail models.InputFile `json:"thumbnail,omitempty"` + Caption string `json:"caption,omitempty"` + ParseMode models.ParseMode `json:"parse_mode,omitempty"` + CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` + DisableContentTypeDetection bool `json:"disable_content_type_detection,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +} + +// SendVideoParams https://core.telegram.org/bots/api#sendvideo type SendVideoParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Video models.InputFile `json:"video"` - Duration int `json:"duration,omitempty"` - Width int `json:"width,omitempty"` - Height int `json:"height,omitempty"` - Thumbnail models.InputFile `json:"thumbnail,omitempty"` - Caption string `json:"caption,omitempty"` - ParseMode models.ParseMode `json:"parse_mode,omitempty"` - CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` - HasSpoiler bool `json:"has_spoiler,omitempty"` - SupportsStreaming bool `json:"supports_streaming,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` -} - + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Video models.InputFile `json:"video"` + Duration int `json:"duration,omitempty"` + Width int `json:"width,omitempty"` + Height int `json:"height,omitempty"` + Thumbnail models.InputFile `json:"thumbnail,omitempty"` + Caption string `json:"caption,omitempty"` + ParseMode models.ParseMode `json:"parse_mode,omitempty"` + CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` + HasSpoiler bool `json:"has_spoiler,omitempty"` + SupportsStreaming bool `json:"supports_streaming,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +} + +// SendAnimationParams https://core.telegram.org/bots/api#sendanimation type SendAnimationParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Animation models.InputFile `json:"animation"` - Duration int `json:"duration,omitempty"` - Width int `json:"width,omitempty"` - Height int `json:"height,omitempty"` - Thumbnail models.InputFile `json:"thumbnail,omitempty"` - Caption string `json:"caption,omitempty"` - ParseMode models.ParseMode `json:"parse_mode,omitempty"` - CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` - HasSpoiler bool `json:"has_spoiler,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` -} - + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Animation models.InputFile `json:"animation"` + Duration int `json:"duration,omitempty"` + Width int `json:"width,omitempty"` + Height int `json:"height,omitempty"` + Thumbnail models.InputFile `json:"thumbnail,omitempty"` + Caption string `json:"caption,omitempty"` + ParseMode models.ParseMode `json:"parse_mode,omitempty"` + CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` + HasSpoiler bool `json:"has_spoiler,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +} + +// SendVoiceParams https://core.telegram.org/bots/api#sendvoice type SendVoiceParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Voice models.InputFile `json:"voice"` - Caption string `json:"caption,omitempty"` - ParseMode models.ParseMode `json:"parse_mode,omitempty"` - CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` - Duration int `json:"duration,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` -} - + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Voice models.InputFile `json:"voice"` + Caption string `json:"caption,omitempty"` + ParseMode models.ParseMode `json:"parse_mode,omitempty"` + CaptionEntities []models.MessageEntity `json:"caption_entities,omitempty"` + Duration int `json:"duration,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +} + +// SendVideoNoteParams https://core.telegram.org/bots/api#sendvideonote type SendVideoNoteParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - VideoNote models.InputFile `json:"video_note"` - Duration int `json:"duration,omitempty"` - Length int `json:"length,omitempty"` - Thumbnail models.InputFile `json:"thumbnail,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` -} - + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + VideoNote models.InputFile `json:"video_note"` + Duration int `json:"duration,omitempty"` + Length int `json:"length,omitempty"` + Thumbnail models.InputFile `json:"thumbnail,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +} + +// SendMediaGroupParams https://core.telegram.org/bots/api#sendmediagroup type SendMediaGroupParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Media []models.InputMedia `json:"media"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Media []models.InputMedia `json:"media"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` } +// SendLocationParams https://core.telegram.org/bots/api#sendlocation type SendLocationParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Latitude float64 `json:"latitude"` - Longitude float64 `json:"longitude"` - HorizontalAccuracy float64 `json:"horizontal_accuracy,omitempty"` - LivePeriod int `json:"live_period,omitempty"` - Heading int `json:"heading,omitempty"` - ProximityAlertRadius int `json:"proximity_alert_radius,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Latitude float64 `json:"latitude"` + Longitude float64 `json:"longitude"` + HorizontalAccuracy float64 `json:"horizontal_accuracy,omitempty"` + LivePeriod int `json:"live_period,omitempty"` + Heading int `json:"heading,omitempty"` + ProximityAlertRadius int `json:"proximity_alert_radius,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } type EditMessageLiveLocationParams struct { @@ -218,69 +240,69 @@ type StopMessageLiveLocationParams struct { ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } +// SendVenueParams https://core.telegram.org/bots/api#sendvenue type SendVenueParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Latitude float64 `json:"latitude"` - Longitude float64 `json:"longitude"` - Title string `json:"title"` - Address string `json:"address"` - FoursquareID string `json:"foursquare_id,omitempty"` - FoursquareType string `json:"foursquare_type,omitempty"` - GooglePlaceID string `json:"google_place_id,omitempty"` - GooglePlaceType string `json:"google_place_type,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` -} - + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Latitude float64 `json:"latitude"` + Longitude float64 `json:"longitude"` + Title string `json:"title"` + Address string `json:"address"` + FoursquareID string `json:"foursquare_id,omitempty"` + FoursquareType string `json:"foursquare_type,omitempty"` + GooglePlaceID string `json:"google_place_id,omitempty"` + GooglePlaceType string `json:"google_place_type,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +} + +// SendContactParams https://core.telegram.org/bots/api#sendcontact type SendContactParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - PhoneNumber string `json:"phone_number"` - FirstName string `json:"first_name"` - LastName string `json:"last_name,omitempty"` - VCard string `json:"vcard,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` -} - + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + PhoneNumber string `json:"phone_number"` + FirstName string `json:"first_name"` + LastName string `json:"last_name,omitempty"` + VCard string `json:"vcard,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +} + +// SendPollParams https://core.telegram.org/bots/api#sendpoll type SendPollParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Question string `json:"question"` - Options []string `json:"options"` - IsAnonymous *bool `json:"is_anonymous,omitempty"` - Type string `json:"type,omitempty"` - AllowsMultipleAnswers bool `json:"allows_multiple_answers,omitempty"` - CorrectOptionID int `json:"correct_option_id"` - Explanation string `json:"explanation,omitempty"` - ExplanationParseMode string `json:"explanation_parse_mode,omitempty"` - ExplanationEntities []models.MessageEntity `json:"explanation_entities,omitempty"` - OpenPeriod int `json:"open_period,omitempty"` - CloseDate int `json:"close_date,omitempty"` - IsClosed bool `json:"is_closed,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` -} - + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Question string `json:"question"` + Options []string `json:"options"` + IsAnonymous *bool `json:"is_anonymous,omitempty"` + Type string `json:"type,omitempty"` + AllowsMultipleAnswers bool `json:"allows_multiple_answers,omitempty"` + CorrectOptionID int `json:"correct_option_id"` + Explanation string `json:"explanation,omitempty"` + ExplanationParseMode string `json:"explanation_parse_mode,omitempty"` + ExplanationEntities []models.MessageEntity `json:"explanation_entities,omitempty"` + OpenPeriod int `json:"open_period,omitempty"` + CloseDate int `json:"close_date,omitempty"` + IsClosed bool `json:"is_closed,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` +} + +// SendDiceParams https://core.telegram.org/bots/api#senddice type SendDiceParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Emoji string `json:"emoji,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Emoji string `json:"emoji,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } type SendChatActionParams struct { @@ -289,6 +311,14 @@ type SendChatActionParams struct { Action models.ChatAction `json:"action"` } +// SetMessageReactionParams https://core.telegram.org/bots/api#setmessagereaction +type SetMessageReactionParams struct { + ChatID any `json:"chat_id"` + MessageID int `json:"message_id"` + Reaction []models.ReactionType `json:"reaction,omitempty"` + IsBig *bool `json:"is_big,omitempty"` +} + type GetUserProfilePhotosParams struct { UserID int64 `json:"user_id"` Offset int `json:"offset,omitempty"` @@ -530,6 +560,12 @@ type AnswerCallbackQueryParams struct { CacheTime int `json:"cache_time,omitempty"` } +// GetUserChatBoostsParams https://core.telegram.org/bots/api#getuserchatboosts +type GetUserChatBoostsParams struct { + ChatID any `json:"chat_id"` + UserID int `json:"user_id"` +} + type SetMyCommandsParams struct { Commands []models.BotCommand `json:"commands"` Scope models.BotCommandScope `json:"scope,omitempty"` @@ -591,15 +627,16 @@ type GetMyDefaultAdministratorRightsParams struct { ForChannels bool `json:"for_channels,omitempty"` } +// EditMessageTextParams https://core.telegram.org/bots/api#editmessagetext type EditMessageTextParams struct { - ChatID any `json:"chat_id"` - MessageID int `json:"message_id,omitempty"` - InlineMessageID string `json:"inline_message_id,omitempty"` - Text string `json:"text"` - ParseMode models.ParseMode `json:"parse_mode,omitempty"` - Entities []models.MessageEntity `json:"entities,omitempty"` - DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` + ChatID any `json:"chat_id"` + MessageID int `json:"message_id,omitempty"` + InlineMessageID string `json:"inline_message_id,omitempty"` + Text string `json:"text"` + ParseMode models.ParseMode `json:"parse_mode,omitempty"` + Entities []models.MessageEntity `json:"entities,omitempty"` + LinkPreviewOptions *models.LinkPreviewOptions `json:"link_preview_options,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } type EditMessageCaptionParams struct { @@ -634,21 +671,28 @@ type StopPollParams struct { ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } +// DeleteMessageParams https://core.telegram.org/bots/api#deletemessage type DeleteMessageParams struct { ChatID any `json:"chat_id"` MessageID int `json:"message_id"` } +// DeleteMessagesParams https://core.telegram.org/bots/api#deletemessages +type DeleteMessagesParams struct { + ChatID any `json:"chat_id"` + MessageIDs []int `json:"messages_id"` +} + +// SendStickerParams https://core.telegram.org/bots/api#sendsticker type SendStickerParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Sticker models.InputFile `json:"sticker"` - Emoji string `json:"emoji,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Sticker models.InputFile `json:"sticker"` + Emoji string `json:"emoji,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } type GetStickerSetParams struct { @@ -738,35 +782,35 @@ type AnswerWebAppQueryParams struct { Result models.InlineQueryResult `json:"result"` } +// SendInvoiceParams https://core.telegram.org/bots/api#sendinvoice type SendInvoiceParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - Title string `json:"title"` - Description string `json:"description"` - Payload string `json:"payload"` - ProviderToken string `json:"provider_token"` - Currency string `json:"currency"` - Prices []models.LabeledPrice `json:"prices"` - MaxTipAmount int `json:"max_tip_amount,omitempty"` - SuggestedTipAmounts []int `json:"suggested_tip_amounts,omitempty"` - StartParameter string `json:"start_parameter,omitempty"` - ProviderData string `json:"provider_data,omitempty"` - PhotoURL string `json:"photo_url,omitempty"` - PhotoSize int `json:"photo_size,omitempty"` - PhotoWidth int `json:"photo_width,omitempty"` - PhotoHeight int `json:"photo_height,omitempty"` - NeedName bool `json:"need_name,omitempty"` - NeedPhoneNumber bool `json:"need_phone_number,omitempty"` - NeedEmail bool `json:"need_email,omitempty"` - NeedShippingAddress bool `json:"need_shipping_address,omitempty"` - SendPhoneNumberToProvider bool `json:"send_phone_number_to_provider,omitempty"` - SendEmailToProvider bool `json:"send_email_to_provider,omitempty"` - IsFlexible bool `json:"is_flexible,omitempty"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + Title string `json:"title"` + Description string `json:"description"` + Payload string `json:"payload"` + ProviderToken string `json:"provider_token"` + Currency string `json:"currency"` + Prices []models.LabeledPrice `json:"prices"` + MaxTipAmount int `json:"max_tip_amount,omitempty"` + SuggestedTipAmounts []int `json:"suggested_tip_amounts,omitempty"` + StartParameter string `json:"start_parameter,omitempty"` + ProviderData string `json:"provider_data,omitempty"` + PhotoURL string `json:"photo_url,omitempty"` + PhotoSize int `json:"photo_size,omitempty"` + PhotoWidth int `json:"photo_width,omitempty"` + PhotoHeight int `json:"photo_height,omitempty"` + NeedName bool `json:"need_name,omitempty"` + NeedPhoneNumber bool `json:"need_phone_number,omitempty"` + NeedEmail bool `json:"need_email,omitempty"` + NeedShippingAddress bool `json:"need_shipping_address,omitempty"` + SendPhoneNumberToProvider bool `json:"send_phone_number_to_provider,omitempty"` + SendEmailToProvider bool `json:"send_email_to_provider,omitempty"` + IsFlexible bool `json:"is_flexible,omitempty"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } type CreateInvoiceLinkParams struct { @@ -810,15 +854,15 @@ type SetPassportDataErrorsParams struct { Errors []models.PassportElementError `json:"errors"` } +// SendGameParams https://core.telegram.org/bots/api#sendgame type SendGameParams struct { - ChatID any `json:"chat_id"` - MessageThreadID int `json:"message_thread_id,omitempty"` - GameShorName string `json:"game_short_name"` - DisableNotification bool `json:"disable_notification,omitempty"` - ProtectContent bool `json:"protect_content,omitempty"` - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` + ChatID any `json:"chat_id"` + MessageThreadID int `json:"message_thread_id,omitempty"` + GameShorName string `json:"game_short_name"` + DisableNotification bool `json:"disable_notification,omitempty"` + ProtectContent bool `json:"protect_content,omitempty"` + ReplyParameters *models.ReplyParameters `json:"reply_parameters,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } type SetGameScoreParams struct { diff --git a/models/boost.go b/models/boost.go new file mode 100644 index 0000000..b37b6e5 --- /dev/null +++ b/models/boost.go @@ -0,0 +1,96 @@ +package models + +import ( + "encoding/json" + "fmt" +) + +// ChatBoostUpdated https://core.telegram.org/bots/api#chatboostupdated +type ChatBoostUpdated struct { + Chat Chat `json:"chat"` + Boost ChatBoost `json:"boost"` +} + +// ChatBoostRemoved https://core.telegram.org/bots/api#chatboostremoved +type ChatBoostRemoved struct { + Chat Chat `json:"chat"` + BoostID string `json:"boost_id"` + RemoveDate int `json:"remove_date"` + Source ChatBoostSource `json:"source"` +} + +// UserChatBoosts https://core.telegram.org/bots/api#userchatboosts +type UserChatBoosts struct { + Boosts []ChatBoost `json:"boosts"` +} + +// ChatBoost https://core.telegram.org/bots/api#chatboost +type ChatBoost struct { + BoostID string `json:"boost_id"` + AddDate int `json:"add_date"` + ExpirationDate int `json:"expiration_date"` + Source ChatBoostSource `json:"source"` +} + +// ChatBoostSource https://core.telegram.org/bots/api#chatboostsource +type ChatBoostSource struct { + Source ChatBoostSourceType + + ChatBoostSourcePremium *ChatBoostSourcePremium + ChatBoostSourceGiftCode *ChatBoostSourceGiftCode + ChatBoostSourceGiveaway *ChatBoostSourceGiveaway +} + +func (cbs *ChatBoostSource) UnmarshalJSON(data []byte) error { + v := struct { + Source string `json:"source"` + }{} + err := json.Unmarshal(data, &v) + if err != nil { + return err + } + + switch v.Source { + case "premium": + cbs.Source = ChatBoostSourceTypePremium + cbs.ChatBoostSourcePremium = &ChatBoostSourcePremium{} + return json.Unmarshal(data, cbs.ChatBoostSourcePremium) + case "gift_code": + cbs.Source = ChatBoostSourceTypeGiftCode + cbs.ChatBoostSourceGiftCode = &ChatBoostSourceGiftCode{} + return json.Unmarshal(data, cbs.ChatBoostSourceGiftCode) + case "giveaway": + cbs.Source = ChatBoostSourceTypeGiveaway + cbs.ChatBoostSourceGiveaway = &ChatBoostSourceGiveaway{} + return json.Unmarshal(data, cbs.ChatBoostSourceGiveaway) + } + + return fmt.Errorf("unsupported ChatBoostSource type") +} + +// ChatBoostSourceType https://core.telegram.org/bots/api#chatboostsource +type ChatBoostSourceType int + +const ( + ChatBoostSourceTypePremium ChatBoostSourceType = iota + ChatBoostSourceTypeGiftCode + ChatBoostSourceTypeGiveaway +) + +// ChatBoostSourcePremium https://core.telegram.org/bots/api#chatboostsourcepremium +type ChatBoostSourcePremium struct { + Source string `json:"source"` // always “premium” + User User `json:"user"` +} + +// ChatBoostSourceGiftCode https://core.telegram.org/bots/api#chatboostsourcegiftcode +type ChatBoostSourceGiftCode struct { + Source string `json:"source"` // always “gift_code” + User User `json:"user"` +} + +// ChatBoostSourceGiveaway https://core.telegram.org/bots/api#chatboostsourcegiveaway +type ChatBoostSourceGiveaway struct { + Source string `json:"source"` // always “giveaway” + User User `json:"user"` +} diff --git a/models/boost_test.go b/models/boost_test.go new file mode 100644 index 0000000..3ae1304 --- /dev/null +++ b/models/boost_test.go @@ -0,0 +1,72 @@ +package models + +import ( + "encoding/json" + "testing" +) + +func TestChatBoostSource_premium(t *testing.T) { + src := `{"source":"premium","user":{"id":123}}` + + var cbs ChatBoostSource + err := json.Unmarshal([]byte(src), &cbs) + if err != nil { + t.Fatal(err) + } + + if cbs.Source != ChatBoostSourceTypePremium { + t.Fatal("invalid type") + } + + if cbs.ChatBoostSourcePremium == nil { + t.Fatal("invalid ChatBoostSourcePremium") + } + + if cbs.ChatBoostSourcePremium.User.ID != 123 { + t.Fatal("invalid user id") + } +} + +func TestChatBoostSource_gift_code(t *testing.T) { + src := `{"source":"gift_code","user":{"id":123}}` + + var cbs ChatBoostSource + err := json.Unmarshal([]byte(src), &cbs) + if err != nil { + t.Fatal(err) + } + + if cbs.Source != ChatBoostSourceTypeGiftCode { + t.Fatal("invalid type") + } + + if cbs.ChatBoostSourceGiftCode == nil { + t.Fatal("invalid ChatBoostSourceGiftCode") + } + + if cbs.ChatBoostSourceGiftCode.User.ID != 123 { + t.Fatal("invalid user id") + } +} + +func TestChatBoostSource_giveaway(t *testing.T) { + src := `{"source":"giveaway","user":{"id":123}}` + + var cbs ChatBoostSource + err := json.Unmarshal([]byte(src), &cbs) + if err != nil { + t.Fatal(err) + } + + if cbs.Source != ChatBoostSourceTypeGiveaway { + t.Fatal("invalid type") + } + + if cbs.ChatBoostSourceGiveaway == nil { + t.Fatal("invalid ChatBoostSourceGiveaway") + } + + if cbs.ChatBoostSourceGiveaway.User.ID != 123 { + t.Fatal("invalid user id") + } +} diff --git a/models/callback_query.go b/models/callback_query.go index 8f14906..9ce5f57 100644 --- a/models/callback_query.go +++ b/models/callback_query.go @@ -2,11 +2,11 @@ package models // CallbackQuery https://core.telegram.org/bots/api#callbackquery type CallbackQuery struct { - ID string `json:"id"` - Sender User `json:"from,omitempty"` - Message *Message `json:"message,omitempty"` - InlineMessageID string `json:"inline_message_id,omitempty"` - ChatInstance string `json:"chat_instance,omitempty"` - Data string `json:"data,omitempty"` - GameShortName string `json:"game_short_name,omitempty"` + ID string `json:"id"` + From User `json:"from,omitempty"` + Message InaccessibleMessage `json:"message,omitempty"` + InlineMessageID string `json:"inline_message_id,omitempty"` + ChatInstance string `json:"chat_instance,omitempty"` + Data string `json:"data,omitempty"` + GameShortName string `json:"game_short_name,omitempty"` } diff --git a/models/chat.go b/models/chat.go index b0d4fc4..958588e 100644 --- a/models/chat.go +++ b/models/chat.go @@ -85,6 +85,11 @@ type Chat struct { IsForum bool `json:"is_forum,omitempty"` Photo *ChatPhoto `json:"photo,omitempty"` ActiveUsernames []string `json:"active_usernames,omitempty"` + AvailableReactions []ReactionType `json:"available_reactions,omitempty"` + AccentColorID int `json:"accent_color_id,omitempty"` + BackgroundCustomEmojiID string `json:"background_custom_emoji_id,omitempty"` + ProfileAccentColorID int `json:"profile_accent_color_id,omitempty"` + ProfileBackgroundCustomEmojiID string `json:"profile_background_custom_emoji_id,omitempty"` EmojiStatusCustomEmojiID string `json:"emoji_status_custom_emoji_id,omitempty"` EmojiStatusExpirationDate int `json:"emoji_status_expiration_date,omitempty"` Bio string `json:"bio"` @@ -101,6 +106,7 @@ type Chat struct { HasAggressiveAntiSpamEnabled bool `json:"has_aggressive_anti_spam_enabled,omitempty"` HasHiddenMembers bool `json:"has_hidden_members,omitempty"` HasProtectedContent bool `json:"has_protected_content,omitempty"` + HasVisibleHistory bool `json:"has_visible_history,omitempty"` StickerSetName string `json:"sticker_set_name,omitempty"` CanSetStickerSet bool `json:"can_set_sticker_set,omitempty"` LinkedChatID int64 `json:"linked_chat_id,omitempty"` diff --git a/models/chat_member.go b/models/chat_member.go index d9b77ec..d48dee6 100644 --- a/models/chat_member.go +++ b/models/chat_member.go @@ -1,7 +1,6 @@ package models import ( - "bytes" "encoding/json" "fmt" ) @@ -41,32 +40,35 @@ type ChatMember struct { } func (c *ChatMember) UnmarshalJSON(data []byte) error { - if bytes.Contains(data, []byte(`"status":"creator"`)) { + v := struct { + Status string `json:"status"` + }{} + if err := json.Unmarshal(data, &v); err != nil { + return err + } + + switch v.Status { + case "creator": c.Type = ChatMemberTypeOwner c.Owner = &ChatMemberOwner{} return json.Unmarshal(data, c.Owner) - } - if bytes.Contains(data, []byte(`"status":"administrator"`)) { + case "administrator": c.Type = ChatMemberTypeAdministrator c.Administrator = &ChatMemberAdministrator{} return json.Unmarshal(data, c.Administrator) - } - if bytes.Contains(data, []byte(`"status":"member"`)) { + case "member": c.Type = ChatMemberTypeMember c.Member = &ChatMemberMember{} return json.Unmarshal(data, c.Member) - } - if bytes.Contains(data, []byte(`"status":"restricted"`)) { + case "restricted": c.Type = ChatMemberTypeRestricted c.Restricted = &ChatMemberRestricted{} return json.Unmarshal(data, c.Restricted) - } - if bytes.Contains(data, []byte(`"status":"left"`)) { + case "left": c.Type = ChatMemberTypeLeft c.Left = &ChatMemberLeft{} return json.Unmarshal(data, c.Left) - } - if bytes.Contains(data, []byte(`"status":"kicked"`)) { + case "kicked": c.Type = ChatMemberTypeBanned c.Banned = &ChatMemberBanned{} return json.Unmarshal(data, c.Banned) diff --git a/models/forum.go b/models/forum.go index a234146..aecd5fb 100644 --- a/models/forum.go +++ b/models/forum.go @@ -43,6 +43,12 @@ type UserShared struct { UserID int64 `json:"user_id"` } +// UsersShared https://core.telegram.org/bots/api#usersshared +type UsersShared struct { + RequestID int `json:"request_id"` + UserIDs []int64 `json:"users_id"` +} + // ChatShared https://core.telegram.org/bots/api#chatshared type ChatShared struct { RequestID int `json:"request_id"` diff --git a/models/giveaway.go b/models/giveaway.go new file mode 100644 index 0000000..1a09056 --- /dev/null +++ b/models/giveaway.go @@ -0,0 +1,38 @@ +package models + +// Giveaway https://core.telegram.org/bots/api#giveaway +type Giveaway struct { + Chats []Chat `json:"chats"` + WinnersSelectionDate int `json:"winners_selection_date"` + WinnerCount int `json:"winner_count"` + OnlyNewMembers bool `json:"only_new_members,omitempty"` + HasPublicWinners bool `json:"has_public_winners,omitempty"` + PrizeDescription string `json:"prize_description,omitempty"` + CountryCodes []string `json:"country_codes,omitempty"` + PremiumSubscriptionMonthCount int `json:"premium_subscription_month_count,omitempty"` +} + +// GiveawayCreated https://core.telegram.org/bots/api#giveawaycreated +type GiveawayCreated struct{} + +// GiveawayWinners https://core.telegram.org/bots/api#giveawaywinners +type GiveawayWinners struct { + Chat Chat `json:"chat"` + GiveawayMessageID int `json:"giveaway_message_id"` + WinnersSelectionDate int `json:"winners_selection_date"` + WinnerCount int `json:"winner_count"` + Winners []User `json:"winners"` + AdditionalChatCount int `json:"additional_chat_count,omitempty"` + PremiumSubscriptionMonthCount int `json:"premium_subscription_month_count,omitempty"` + UnclaimedPrizeCount int `json:"unclaimed_prize_count,omitempty"` + OnlyNewMembers bool `json:"only_new_members,omitempty"` + WasRefunded bool `json:"was_refunded,omitempty"` + PrizeDescription string `json:"prize_description,omitempty"` +} + +// GiveawayCompleted https://core.telegram.org/bots/api#giveawaycompleted +type GiveawayCompleted struct { + WinnerCount int `json:"winner_count"` + UnclaimedPrizeCount int `json:"unclaimed_prize_count,omitempty"` + GiveawayMessage *Message `json:"giveaway_message,omitempty"` +} diff --git a/models/inline_query.go b/models/inline_query.go index f634170..f1c2f7f 100644 --- a/models/inline_query.go +++ b/models/inline_query.go @@ -602,10 +602,10 @@ type InputMessageContent interface { // InputTextMessageContent https://core.telegram.org/bots/api#inputtextmessagecontent type InputTextMessageContent struct { - MessageText string `json:"message_text"` - ParseMode ParseMode `json:"parse_mode,omitempty"` - Entities []MessageEntity `json:"entities,omitempty"` - DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"` + MessageText string `json:"message_text"` + ParseMode ParseMode `json:"parse_mode,omitempty"` + Entities []MessageEntity `json:"entities,omitempty"` + LinkPreviewOptions *LinkPreviewOptions `json:"link_preview_options,omitempty"` } func (InputTextMessageContent) inputMessageContentTag() {} diff --git a/models/link_preview.go b/models/link_preview.go new file mode 100644 index 0000000..62170b4 --- /dev/null +++ b/models/link_preview.go @@ -0,0 +1,10 @@ +package models + +// LinkPreviewOptions https://core.telegram.org/bots/api#linkpreviewoptions +type LinkPreviewOptions struct { + IsDisabled *bool `json:"is_disabled,omitempty"` + URL *string `json:"url"` + PreferSmallMedia *bool `json:"prefer_small_media,omitempty"` + PreferLargeMedia *bool `json:"prefer_large_media,omitempty"` + ShowAboveText *bool `json:"show_above_text,omitempty"` +} diff --git a/models/message.go b/models/message.go index 3973ddf..ee61a7f 100644 --- a/models/message.go +++ b/models/message.go @@ -1,5 +1,52 @@ package models +import ( + "encoding/json" +) + +// MaybeInaccessibleMessageType https://core.telegram.org/bots/api#maybeinaccessiblemessage +type MaybeInaccessibleMessageType int + +const ( + MaybeInaccessibleMessageTypeMessage MaybeInaccessibleMessageType = iota + MaybeInaccessibleMessageTypeInaccessibleMessage +) + +// MaybeInaccessibleMessage https://core.telegram.org/bots/api#maybeinaccessiblemessage +type MaybeInaccessibleMessage struct { + Type MaybeInaccessibleMessageType + + Message *Message + InaccessibleMessage *InaccessibleMessage +} + +func (mim *MaybeInaccessibleMessage) UnmarshalJSON(data []byte) error { + v := struct { + Date int `json:"date"` + }{} + err := json.Unmarshal(data, &v) + if err != nil { + return err + } + + if v.Date == 0 { + mim.Type = MaybeInaccessibleMessageTypeInaccessibleMessage + mim.InaccessibleMessage = &InaccessibleMessage{} + return json.Unmarshal(data, mim.InaccessibleMessage) + } + + mim.Type = MaybeInaccessibleMessageTypeMessage + mim.Message = &Message{} + return json.Unmarshal(data, mim.Message) +} + +// InaccessibleMessage https://core.telegram.org/bots/api#inaccessiblemessage +type InaccessibleMessage struct { + Chat Chat `json:"chat"` + MessageID int `json:"message_id"` + Date int `json:"date"` +} + type MessageID struct { ID int `json:"message_id"` } @@ -17,15 +64,12 @@ type Message struct { SenderChat *Chat `json:"sender_chat,omitempty"` Date int `json:"date"` Chat Chat `json:"chat"` - ForwardFrom *User `json:"forward_from,omitempty"` - ForwardFromChat *Chat `json:"forward_from_chat,omitempty"` - ForwardFromMessageID int `json:"forward_from_message_id,omitempty"` - ForwardSignature string `json:"forward_signature,omitempty"` - ForwardSenderName string `json:"forward_sender_name,omitempty"` - ForwardDate int `json:"forward_date,omitempty"` + ForwardOrigin *MessageOrigin `json:"forward_origin,omitempty"` IsTopicMessage bool `json:"is_topic_message,omitempty"` IsAutomaticForward bool `json:"is_automatic_forward,omitempty"` ReplyToMessage *Message `json:"reply_to_message,omitempty"` + ExternalReply *ExternalReplyInfo `json:"external_reply,omitempty"` + Quote *TextQuote `json:"quote,omitempty"` ViaBot *User `json:"via_bot,omitempty"` EditDate int `json:"edit_date,omitempty"` HasProtectedContent bool `json:"has_protected_content,omitempty"` @@ -33,6 +77,7 @@ type Message struct { AuthorSignature string `json:"author_signature,omitempty"` Text string `json:"text,omitempty"` Entities []MessageEntity `json:"entities,omitempty"` + LinkPreviewOptions *LinkPreviewOptions `json:"link_preview_options,omitempty"` Animation *Animation `json:"animation,omitempty"` Audio *Audio `json:"audio,omitempty"` Document *Document `json:"document,omitempty"` @@ -62,10 +107,10 @@ type Message struct { MessageAutoDeleteTimerChanged *MessageAutoDeleteTimerChanged `json:"message_auto_delete_timer_changed,omitempty"` MigrateToChatID int64 `json:"migrate_to_chat_id,omitempty"` MigrateFromChatID int64 `json:"migrate_from_chat_id,omitempty"` - PinnedMessage *Message `json:"pinned_message,omitempty"` + PinnedMessage MaybeInaccessibleMessage `json:"pinned_message,omitempty"` Invoice *Invoice `json:"invoice,omitempty"` SuccessfulPayment *SuccessfulPayment `json:"successful_payment,omitempty"` - UserShared *UserShared `json:"user_shared,omitempty"` + UsersShared *UsersShared `json:"users_shared,omitempty"` ChatShared *ChatShared `json:"chat_shared,omitempty"` ConnectedWebsite string `json:"connected_website,omitempty"` WriteAccessAllowed *WriteAccessAllowed `json:"write_access_allowed,omitempty"` @@ -77,6 +122,10 @@ type Message struct { ForumTopicReopened *ForumTopicReopened `json:"forum_topic_reopened,omitempty"` GeneralForumTopicHidden *GeneralForumTopicHidden `json:"general_forum_topic_hidden,omitempty"` GeneralForumTopicUnhidden *GeneralForumTopicUnhidden `json:"general_forum_topic_unhidden,omitempty"` + GiveawayCreated *GiveawayCreated `json:"giveaway_created,omitempty"` + Giveaway *Giveaway `json:"giveaway,omitempty"` + GiveawayWinners *GiveawayWinners `json:"giveaway_winners,omitempty"` + GiveawayCompleted *GiveawayCompleted `json:"giveaway_completed,omitempty"` VoiceChatScheduled *VoiceChatScheduled `json:"voice_chat_scheduled,omitempty"` VoiceChatStarted *VoiceChatStarted `json:"voice_chat_started,omitempty"` VoiceChatEnded *VoiceChatEnded `json:"voice_chat_ended,omitempty"` diff --git a/models/message_test.go b/models/message_test.go new file mode 100644 index 0000000..e33580c --- /dev/null +++ b/models/message_test.go @@ -0,0 +1,55 @@ +package models + +import "testing" + +func TestUnmarshalMaybeInaccessibleMessage_inaccessible(t *testing.T) { + src := `{"date":0,"chat":{"id":123},"message_id":987}` + + mim := MaybeInaccessibleMessage{} + err := mim.UnmarshalJSON([]byte(src)) + if err != nil { + t.Fatal(err) + } + + if mim.Type != MaybeInaccessibleMessageTypeInaccessibleMessage { + t.Fatal("wrong type") + } + + if mim.InaccessibleMessage == nil { + t.Fatal("InaccessibleMessage is nil") + } + + if mim.InaccessibleMessage.Chat.ID != 123 { + t.Fatal("wrong chat id") + } + + if mim.InaccessibleMessage.MessageID != 987 { + t.Fatal("wrong message id") + } +} + +func TestUnmarshalMaybeInaccessibleMessage_message(t *testing.T) { + src := `{"date":42,"chat":{"id":123},"message_id":987}` + + mim := MaybeInaccessibleMessage{} + err := mim.UnmarshalJSON([]byte(src)) + if err != nil { + t.Fatal(err) + } + + if mim.Type != MaybeInaccessibleMessageTypeMessage { + t.Fatal("wrong type") + } + + if mim.Message == nil { + t.Fatal("Message is nil") + } + + if mim.Message.Chat.ID != 123 { + t.Fatal("wrong chat id") + } + + if mim.Message.ID != 987 { + t.Fatal("wrong message id") + } +} diff --git a/models/reaction.go b/models/reaction.go new file mode 100644 index 0000000..e30bc3b --- /dev/null +++ b/models/reaction.go @@ -0,0 +1,82 @@ +package models + +import ( + "encoding/json" + "fmt" +) + +// ReactionTypeType https://core.telegram.org/bots/api#reactiontype +type ReactionTypeType int + +const ( + ReactionTypeTypeEmoji ReactionTypeType = iota + ReactionTypeTypeCustomEmoji +) + +// ReactionType https://core.telegram.org/bots/api#reactiontype +type ReactionType struct { + Type ReactionTypeType + + ReactionTypeEmoji *ReactionTypeEmoji + ReactionTypeCustomEmoji *ReactionTypeCustomEmoji +} + +func (rt *ReactionType) UnmarshalJSON(data []byte) error { + v := struct { + Type string `json:"type"` + }{} + err := json.Unmarshal(data, &v) + if err != nil { + return err + } + + switch v.Type { + case "emoji": + rt.Type = ReactionTypeTypeEmoji + rt.ReactionTypeEmoji = &ReactionTypeEmoji{} + return json.Unmarshal(data, rt.ReactionTypeEmoji) + case "custom_emoji": + rt.Type = ReactionTypeTypeCustomEmoji + rt.ReactionTypeCustomEmoji = &ReactionTypeCustomEmoji{} + return json.Unmarshal(data, rt.ReactionTypeCustomEmoji) + } + + return fmt.Errorf("unsupported ReactionType type") +} + +// ReactionTypeEmoji https://core.telegram.org/bots/api#reactiontypeemoji +type ReactionTypeEmoji struct { + Type string `json:"type"` + Emoji string `json:"emoji"` +} + +// ReactionTypeCustomEmoji https://core.telegram.org/bots/api#reactiontypecustomemoji +type ReactionTypeCustomEmoji struct { + Type string `json:"type"` + CustomEmojiID string `json:"custom_emoji_id"` +} + +// MessageReactionUpdated https://core.telegram.org/bots/api#messagereactionupdated +type MessageReactionUpdated struct { + Chat Chat `json:"chat"` + MessageID int `json:"message_id"` + User *User `json:"user,omitempty"` + ActorChat *Chat `json:"actor_chat,omitempty"` + Date int `json:"date"` + OldReaction []ReactionType `json:"old_reaction"` + NewReaction []ReactionType `json:"new_reaction"` +} + +// ReactionCount https://core.telegram.org/bots/api#reactioncount +type ReactionCount struct { + Type ReactionType `json:"type"` + TotalCount int `json:"total_count"` +} + +// MessageReactionCountUpdated https://core.telegram.org/bots/api#messagereactioncountupdated +type MessageReactionCountUpdated struct { + Chat Chat `json:"chat"` + MessageID int `json:"message_id"` + Date int `json:"date"` + Reactions []ReactionCount `json:"reactions"` +} diff --git a/models/reaction_test.go b/models/reaction_test.go new file mode 100644 index 0000000..af0de88 --- /dev/null +++ b/models/reaction_test.go @@ -0,0 +1,47 @@ +package models + +import "testing" + +func TestUnmarshalReactionType_emoji(t *testing.T) { + src := `{"type":"emoji","emoji":"foo"}` + + var rt ReactionType + err := rt.UnmarshalJSON([]byte(src)) + if err != nil { + t.Fatal(err) + } + + if rt.Type != ReactionTypeTypeEmoji { + t.Fatal("wrong type") + } + + if rt.ReactionTypeEmoji == nil { + t.Fatal("ReactionTypeEmoji is nil") + } + + if rt.ReactionTypeEmoji.Emoji != "foo" { + t.Fatal("wrong emoji") + } +} + +func TestUnmarshalReactionType_custom_emoji(t *testing.T) { + src := `{"type":"custom_emoji","custom_emoji_id":"bar"}` + + var rt ReactionType + err := rt.UnmarshalJSON([]byte(src)) + if err != nil { + t.Fatal(err) + } + + if rt.Type != ReactionTypeTypeCustomEmoji { + t.Fatal("wrong type") + } + + if rt.ReactionTypeCustomEmoji == nil { + t.Fatal("ReactionTypeCustomEmoji is nil") + } + + if rt.ReactionTypeCustomEmoji.CustomEmojiID != "bar" { + t.Fatal("wrong custom emoji id") + } +} diff --git a/models/reply.go b/models/reply.go new file mode 100644 index 0000000..7983022 --- /dev/null +++ b/models/reply.go @@ -0,0 +1,133 @@ +package models + +import ( + "encoding/json" + "fmt" +) + +// TextQuote https://core.telegram.org/bots/api#textquote +type TextQuote struct { + Text string `json:"text"` + Entities []MessageEntity `json:"entities,omitempty"` + Position int `json:"position"` + IsManual bool `json:"is_manual,omitempty"` +} + +// ExternalReplyInfo https://core.telegram.org/bots/api#externalreplyinfo +type ExternalReplyInfo struct { + Origin MessageOrigin `json:"origin"` + Chat *Chat `json:"chat,omitempty"` + MessageID int `json:"message_id,omitempty"` + LinkPreviewOptions *LinkPreviewOptions `json:"link_preview_options,omitempty"` + Animation *Animation `json:"animation,omitempty"` + Audio *Audio `json:"audio,omitempty"` + Document *Document `json:"document,omitempty"` + Photo []PhotoSize `json:"photo,omitempty"` + Sticker *Sticker `json:"sticker,omitempty"` + Story *Story `json:"story,omitempty"` + Video *Video `json:"video,omitempty"` + VideoNote *VideoNote `json:"video_note,omitempty"` + Voice *Voice `json:"voice,omitempty"` + HasMediaSpoiler bool `json:"has_media_spoiler,omitempty"` + Contact *Contact `json:"contact,omitempty"` + Dice *Dice `json:"dice,omitempty"` + Game *Game `json:"game,omitempty"` + Giveaway *Giveaway `json:"giveaway,omitempty"` + GiveawayWinners *GiveawayWinners `json:"giveaway_winners,omitempty"` + Invoice *Invoice `json:"invoice,omitempty"` + Location *Location `json:"location,omitempty"` + Poll *Poll `json:"poll,omitempty"` + Venue *Venue `json:"venue,omitempty"` +} + +// ReplyParameters https://core.telegram.org/bots/api#replyparameters +type ReplyParameters struct { + MessageID int `json:"message_id"` + ChatID any `json:"chat_id,omitempty"` + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + Quote string `json:"quote,omitempty"` + QuoteParseMode ParseMode `json:"quote_parse_mode,omitempty"` + QuoteEntities []MessageEntity `json:"quote_entities,omitempty"` + QuotePosition int `json:"quote_position,omitempty"` +} + +// MessageOriginType https://core.telegram.org/bots/api#messageorigin +type MessageOriginType int + +const ( + MessageOriginTypeUser MessageOriginType = iota + MessageOriginTypeHiddenUser + MessageOriginTypeChat + MessageOriginTypeChannel +) + +// MessageOrigin https://core.telegram.org/bots/api#messageorigin +type MessageOrigin struct { + Type MessageOriginType + + MessageOriginUser *MessageOriginUser + MessageOriginHiddenUser *MessageOriginHiddenUser + MessageOriginChat *MessageOriginChat + MessageOriginChannel *MessageOriginChannel +} + +func (mo *MessageOrigin) UnmarshalJSON(data []byte) error { + v := struct { + Type string `json:"type"` + }{} + if err := json.Unmarshal(data, &v); err != nil { + return err + } + + switch v.Type { + case "user": + mo.Type = MessageOriginTypeUser + mo.MessageOriginUser = &MessageOriginUser{} + return json.Unmarshal(data, mo.MessageOriginUser) + case "hidden_user": + mo.Type = MessageOriginTypeHiddenUser + mo.MessageOriginHiddenUser = &MessageOriginHiddenUser{} + return json.Unmarshal(data, mo.MessageOriginHiddenUser) + case "chat": + mo.Type = MessageOriginTypeChat + mo.MessageOriginChat = &MessageOriginChat{} + return json.Unmarshal(data, mo.MessageOriginChat) + case "channel": + mo.Type = MessageOriginTypeChannel + mo.MessageOriginChannel = &MessageOriginChannel{} + return json.Unmarshal(data, mo.MessageOriginChannel) + } + + return fmt.Errorf("unsupported MessageOrigin type") +} + +// MessageOriginUser https://core.telegram.org/bots/api#messageoriginuser +type MessageOriginUser struct { + Type string `json:"type"` // always “user” + Date int `json:"date"` + SenderUser User `json:"sender_user"` +} + +// MessageOriginHiddenUser https://core.telegram.org/bots/api#messageoriginhiddenuser +type MessageOriginHiddenUser struct { + Type string `json:"type"` // always “hidden_user” + Date int `json:"date"` + SenderUserName string `json:"sender_user_name"` +} + +// MessageOriginChat https://core.telegram.org/bots/api#messageoriginchat +type MessageOriginChat struct { + Type string `json:"type"` // always “chat” + Date int `json:"date"` + SenderChat Chat `json:"sender_chat"` + AuthorSignature *string `json:"author_signature,omitempty"` +} + +// MessageOriginChannel https://core.telegram.org/bots/api#messageoriginchannel +type MessageOriginChannel struct { + Type string `json:"type"` // always “channel” + Date int `json:"date"` + Chat Chat `json:"chat"` + MessageID int `json:"message_id"` + AuthorSignature *string `json:"author_signature,omitempty"` +} diff --git a/models/reply_markup.go b/models/reply_markup.go index d22267a..7031584 100644 --- a/models/reply_markup.go +++ b/models/reply_markup.go @@ -50,13 +50,14 @@ type ReplyKeyboardMarkup struct { // KeyboardButton https://core.telegram.org/bots/api#keyboardbutton type KeyboardButton struct { - Text string `json:"text"` - RequestUser *KeyboardButtonRequestUser `json:"request_user,omitempty"` - RequestChat *KeyboardButtonRequestChat `json:"request_chat,omitempty"` - RequestContact bool `json:"request_contact,omitempty"` - RequestLocation bool `json:"request_location,omitempty"` - RequestPoll *KeyboardButtonPollType `json:"request_poll,omitempty"` - WebApp *WebAppInfo `json:"web_app,omitempty"` + Text string `json:"text"` + RequestUser *KeyboardButtonRequestUsers `json:"request_user,omitempty"` + RequestUsers *KeyboardButtonRequestUsers `json:"request_users,omitempty"` + RequestChat *KeyboardButtonRequestChat `json:"request_chat,omitempty"` + RequestContact bool `json:"request_contact,omitempty"` + RequestLocation bool `json:"request_location,omitempty"` + RequestPoll *KeyboardButtonPollType `json:"request_poll,omitempty"` + WebApp *WebAppInfo `json:"web_app,omitempty"` } // KeyboardButtonRequestUser https://core.telegram.org/bots/api#keyboardbuttonrequestuser @@ -66,6 +67,14 @@ type KeyboardButtonRequestUser struct { UserIsPremium bool `json:"user_is_premium,omitempty"` } +// KeyboardButtonRequestUsers https://core.telegram.org/bots/api#keyboardbuttonrequestusers +type KeyboardButtonRequestUsers struct { + RequestID int32 `json:"request_id"` + UserIsBot bool `json:"user_is_bot,omitempty"` + UserIsPremium bool `json:"user_is_premium,omitempty"` + MaxQuantity int `json:"max_quantity,omitempty"` +} + // KeyboardButtonRequestChat https://core.telegram.org/bots/api#keyboardbuttonrequestchat type KeyboardButtonRequestChat struct { RequestID int32 `json:"request_id"` diff --git a/models/reply_test.go b/models/reply_test.go new file mode 100644 index 0000000..1333c2d --- /dev/null +++ b/models/reply_test.go @@ -0,0 +1,110 @@ +package models + +import ( + "encoding/json" + "testing" +) + +func TestUnmarshalMessageOrigin_user(t *testing.T) { + src := `{"type":"user","date":123,"sender_user":{"id":123}}` + + var mo MessageOrigin + err := json.Unmarshal([]byte(src), &mo) + if err != nil { + t.Fatal(err) + } + + if mo.Type != MessageOriginTypeUser { + t.Fatal("wrong type") + } + + if mo.MessageOriginUser == nil { + t.Fatal("MessageOriginUser is nil") + } + + if mo.MessageOriginUser.Date != 123 { + t.Fatal("wrong date") + } + + if mo.MessageOriginUser.SenderUser.ID != 123 { + t.Fatal("wrong sender user id") + } +} + +func TestUnmarshalMessageOrigin_hidden_user(t *testing.T) { + src := `{"type":"hidden_user","date":123,"sender_user_name":"bar"}` + + var mo MessageOrigin + err := json.Unmarshal([]byte(src), &mo) + if err != nil { + t.Fatal(err) + } + + if mo.Type != MessageOriginTypeHiddenUser { + t.Fatal("wrong type") + } + + if mo.MessageOriginHiddenUser == nil { + t.Fatal("MessageOriginHiddenUser is nil") + } + + if mo.MessageOriginHiddenUser.Date != 123 { + t.Fatal("wrong date") + } + + if mo.MessageOriginHiddenUser.SenderUserName != "bar" { + t.Fatal("wrong sender user name") + } +} + +func TestUnmarshalMessageOrigin_chat(t *testing.T) { + src := `{"type":"chat","date":123,"sender_chat":{"id":123}}` + + var mo MessageOrigin + err := json.Unmarshal([]byte(src), &mo) + if err != nil { + t.Fatal(err) + } + + if mo.Type != MessageOriginTypeChat { + t.Fatal("wrong type") + } + + if mo.MessageOriginChat == nil { + t.Fatal("MessageOriginChat is nil") + } + + if mo.MessageOriginChat.Date != 123 { + t.Fatal("wrong date") + } + + if mo.MessageOriginChat.SenderChat.ID != 123 { + t.Fatal("wrong chat id") + } +} + +func TestUnmarshalMessageOrigin_channel(t *testing.T) { + src := `{"type":"channel","date":123,"chat":{"id":123}}` + + var mo MessageOrigin + err := json.Unmarshal([]byte(src), &mo) + if err != nil { + t.Fatal(err) + } + + if mo.Type != MessageOriginTypeChannel { + t.Fatal("wrong type") + } + + if mo.MessageOriginChannel == nil { + t.Fatal("MessageOriginChannel is nil") + } + + if mo.MessageOriginChannel.Date != 123 { + t.Fatal("wrong date") + } + + if mo.MessageOriginChannel.Chat.ID != 123 { + t.Fatal("wrong chat id") + } +} diff --git a/models/update.go b/models/update.go index c670fb0..3e8b691 100644 --- a/models/update.go +++ b/models/update.go @@ -2,19 +2,23 @@ package models // Update https://core.telegram.org/bots/api#update type Update struct { - ID int64 `json:"update_id"` - Message *Message `json:"message,omitempty"` - EditedMessage *Message `json:"edited_message,omitempty"` - ChannelPost *Message `json:"channel_post,omitempty"` - EditedChannelPost *Message `json:"edited_channel_post,omitempty"` - InlineQuery *InlineQuery `json:"inline_query,omitempty"` - ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result,omitempty"` - CallbackQuery *CallbackQuery `json:"callback_query,omitempty"` - ShippingQuery *ShippingQuery `json:"shipping_query,omitempty"` - PreCheckoutQuery *PreCheckoutQuery `json:"pre_checkout_query,omitempty"` - Poll *Poll `json:"poll,omitempty"` - PollAnswer *PollAnswer `json:"poll_answer,omitempty"` - MyChatMember *ChatMemberUpdated `json:"my_chat_member,omitempty"` - ChatMember *ChatMemberUpdated `json:"chat_member,omitempty"` - ChatJoinRequest *ChatJoinRequest `json:"chat_join_request,omitempty"` + ID int64 `json:"update_id"` + Message *Message `json:"message,omitempty"` + EditedMessage *Message `json:"edited_message,omitempty"` + ChannelPost *Message `json:"channel_post,omitempty"` + EditedChannelPost *Message `json:"edited_channel_post,omitempty"` + MessageReaction *MessageReactionUpdated `json:"message_reaction,omitempty"` + MessageReactionCount *MessageReactionCountUpdated `json:"message_reaction_count,omitempty"` + InlineQuery *InlineQuery `json:"inline_query,omitempty"` + ChosenInlineResult *ChosenInlineResult `json:"chosen_inline_result,omitempty"` + CallbackQuery *CallbackQuery `json:"callback_query,omitempty"` + ShippingQuery *ShippingQuery `json:"shipping_query,omitempty"` + PreCheckoutQuery *PreCheckoutQuery `json:"pre_checkout_query,omitempty"` + Poll *Poll `json:"poll,omitempty"` + PollAnswer *PollAnswer `json:"poll_answer,omitempty"` + MyChatMember *ChatMemberUpdated `json:"my_chat_member,omitempty"` + ChatMember *ChatMemberUpdated `json:"chat_member,omitempty"` + ChatJoinRequest *ChatJoinRequest `json:"chat_join_request,omitempty"` + ChatBoost *ChatBoostUpdated `json:"chat_boost,omitempty"` + RemovedChatBoost *ChatBoostRemoved `json:"removed_chat_boost,omitempty"` }