From 8a48993c092960e12904eec8aee0f7cd0119d3fb Mon Sep 17 00:00:00 2001 From: negasus Date: Mon, 24 Jun 2024 13:11:45 +0300 Subject: [PATCH 1/2] api v7.5 --- methods.go | 7 +++ methods_params.go | 64 +++++++++++-------- models/star.go | 142 ++++++++++++++++++++++++++++++++++++++++++ models/star_test.go | 148 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 335 insertions(+), 26 deletions(-) create mode 100644 models/star.go create mode 100644 models/star_test.go diff --git a/methods.go b/methods.go index 4098cf4..541de4c 100644 --- a/methods.go +++ b/methods.go @@ -811,6 +811,13 @@ func (b *Bot) AnswerPreCheckoutQuery(ctx context.Context, params *AnswerPreCheck return result, err } +// GetStarTransactions https://core.telegram.org/bots/api#getstartransactions +func (b *Bot) GetStarTransactions(ctx context.Context, params *GetStarTransactionsParams) (*models.StarTransactions, error) { + result := models.StarTransactions{} + err := b.rawRequest(ctx, "getStarTransactions", params, &result) + return &result, err +} + // RefundStarPayment https://core.telegram.org/bots/api#refundstarpayment func (b *Bot) RefundStarPayment(ctx context.Context, params *RefundStarPaymentParams) (bool, error) { var result bool diff --git a/methods_params.go b/methods_params.go index 7ddaa7f..da2fbea 100644 --- a/methods_params.go +++ b/methods_params.go @@ -246,7 +246,8 @@ type SendLocationParams struct { } type EditMessageLiveLocationParams struct { - ChatID any `json:"chat_id"` + BusinessConnectionID string `json:"business_connection_id,omitempty"` + ChatID any `json:"chat_id,omitempty"` MessageID int `json:"message_id,omitempty"` InlineMessageID string `json:"inline_message_id,omitempty"` Latitude float64 `json:"latitude"` @@ -259,10 +260,11 @@ type EditMessageLiveLocationParams struct { } type StopMessageLiveLocationParams struct { - ChatID any `json:"chat_id,omitempty"` - MessageID int `json:"message_id,omitempty"` - InlineMessageID string `json:"inline_message_id,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` + BusinessConnectionID string `json:"business_connection_id,omitempty"` + ChatID any `json:"chat_id,omitempty"` + MessageID int `json:"message_id,omitempty"` + InlineMessageID string `json:"inline_message_id,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } // SendVenueParams https://core.telegram.org/bots/api#sendvenue @@ -665,18 +667,20 @@ type GetMyDefaultAdministratorRightsParams struct { // 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"` - LinkPreviewOptions *models.LinkPreviewOptions `json:"link_preview_options,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` + BusinessConnectionID string `json:"business_connection_id,omitempty"` + ChatID any `json:"chat_id,omitempty"` + 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 { - ChatID any `json:"chat_id"` + BusinessConnectionID string `json:"business_connection_id,omitempty"` + ChatID any `json:"chat_id,omitempty"` MessageID int `json:"message_id,omitempty"` InlineMessageID string `json:"inline_message_id,omitempty"` Caption string `json:"caption,omitempty"` @@ -688,24 +692,27 @@ type EditMessageCaptionParams struct { } type EditMessageMediaParams struct { - ChatID any `json:"chat_id"` - MessageID int `json:"message_id,omitempty"` - InlineMessageID string `json:"inline_message_id,omitempty"` - Media models.InputMedia `json:"media"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` + BusinessConnectionID string `json:"business_connection_id,omitempty"` + ChatID any `json:"chat_id,omitempty"` + MessageID int `json:"message_id,omitempty"` + InlineMessageID string `json:"inline_message_id,omitempty"` + Media models.InputMedia `json:"media"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } type EditMessageReplyMarkupParams struct { - ChatID any `json:"chat_id"` - MessageID int `json:"message_id,omitempty"` - InlineMessageID string `json:"inline_message_id,omitempty"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` + BusinessConnectionID string `json:"business_connection_id,omitempty"` + ChatID any `json:"chat_id,omitempty"` + MessageID int `json:"message_id,omitempty"` + InlineMessageID string `json:"inline_message_id,omitempty"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } type StopPollParams struct { - ChatID any `json:"chat_id"` - MessageID int `json:"message_id"` - ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` + BusinessConnectionID string `json:"business_connection_id,omitempty"` + ChatID any `json:"chat_id"` + MessageID int `json:"message_id"` + ReplyMarkup models.ReplyMarkup `json:"reply_markup,omitempty"` } // DeleteMessageParams https://core.telegram.org/bots/api#deletemessage @@ -896,6 +903,11 @@ type AnswerPreCheckoutQueryParams struct { ErrorMessage string `json:"error_message,omitempty"` } +type GetStarTransactionsParams struct { + Offset int `json:"offset,omitempty"` + Limit int `json:"limit,omitempty"` +} + type RefundStarPaymentParams struct { UserID int64 `json:"user_id"` TelegramPaymentChargeID string `json:"telegram_payment_charge_id"` diff --git a/models/star.go b/models/star.go new file mode 100644 index 0000000..e557182 --- /dev/null +++ b/models/star.go @@ -0,0 +1,142 @@ +package models + +import ( + "encoding/json" + "fmt" +) + +type TransactionPartnerType string + +const ( + TransactionPartnerTypeFragment TransactionPartnerType = "fragment" + TransactionPartnerTypeUser TransactionPartnerType = "user" + TransactionPartnerTypeOther TransactionPartnerType = "other" +) + +// TransactionPartner https://core.telegram.org/bots/api#transactionpartner +type TransactionPartner struct { + Type TransactionPartnerType + + Fragment *TransactionPartnerFragment `json:"fragment,omitempty"` + User *TransactionPartnerUser `json:"user,omitempty"` + Other *TransactionPartnerOther `json:"other,omitempty"` +} + +func (m *TransactionPartner) UnmarshalJSON(data []byte) error { + v := struct { + Type TransactionPartnerType `json:"type"` + }{} + err := json.Unmarshal(data, &v) + if err != nil { + return err + } + + switch v.Type { + case TransactionPartnerTypeFragment: + m.Type = TransactionPartnerTypeFragment + m.Fragment = &TransactionPartnerFragment{} + return json.Unmarshal(data, m.Fragment) + case TransactionPartnerTypeUser: + m.Type = TransactionPartnerTypeUser + m.User = &TransactionPartnerUser{} + return json.Unmarshal(data, m.User) + case TransactionPartnerTypeOther: + m.Type = TransactionPartnerTypeOther + m.Other = &TransactionPartnerOther{} + return json.Unmarshal(data, m.Other) + } + + return fmt.Errorf("unsupported TransactionPartner type") +} + +// TransactionPartnerFragment https://core.telegram.org/bots/api#transactionpartnerfragment +type TransactionPartnerFragment struct { + Type TransactionPartnerType `json:"type"` + WithdrawalState *RevenueWithdrawalState `json:"withdrawal_state,omitempty"` +} + +// TransactionPartnerUser https://core.telegram.org/bots/api#transactionpartneruser +type TransactionPartnerUser struct { + Type TransactionPartnerType `json:"type"` + User User `json:"user"` +} + +// TransactionPartnerOther https://core.telegram.org/bots/api#transactionpartnerother +type TransactionPartnerOther struct { + Type TransactionPartnerType `json:"type"` +} + +type RevenueWithdrawalStateType string + +const ( + RevenueWithdrawalStateTypePending RevenueWithdrawalStateType = "pending" + RevenueWithdrawalStateTypeSucceeded RevenueWithdrawalStateType = "succeeded" + RevenueWithdrawalStateTypeFailed RevenueWithdrawalStateType = "failed" +) + +// RevenueWithdrawalState https://core.telegram.org/bots/api#revenuewithdrawalstate +type RevenueWithdrawalState struct { + Type RevenueWithdrawalStateType `json:"type"` + + Pending *RevenueWithdrawalStatePending `json:"pending,omitempty"` + Succeeded *RevenueWithdrawalStateSucceeded `json:"succeeded,omitempty"` + Failed *RevenueWithdrawalStateFailed `json:"failed,omitempty"` +} + +func (m *RevenueWithdrawalState) UnmarshalJSON(data []byte) error { + v := struct { + Type RevenueWithdrawalStateType `json:"type"` + }{} + err := json.Unmarshal(data, &v) + if err != nil { + return err + } + + switch v.Type { + case RevenueWithdrawalStateTypePending: + m.Type = RevenueWithdrawalStateTypePending + m.Pending = &RevenueWithdrawalStatePending{} + return json.Unmarshal(data, m.Pending) + case RevenueWithdrawalStateTypeSucceeded: + m.Type = RevenueWithdrawalStateTypeSucceeded + m.Succeeded = &RevenueWithdrawalStateSucceeded{} + return json.Unmarshal(data, m.Succeeded) + case RevenueWithdrawalStateTypeFailed: + m.Type = RevenueWithdrawalStateTypeFailed + m.Failed = &RevenueWithdrawalStateFailed{} + return json.Unmarshal(data, m.Failed) + } + + return fmt.Errorf("unsupported RevenueWithdrawalState type") +} + +// RevenueWithdrawalStatePending https://core.telegram.org/bots/api#revenuewithdrawalstatepending +type RevenueWithdrawalStatePending struct { + Type RevenueWithdrawalStateType `json:"type"` +} + +// RevenueWithdrawalStateSucceeded https://core.telegram.org/bots/api#revenuewithdrawalstatesucceeded +type RevenueWithdrawalStateSucceeded struct { + Type RevenueWithdrawalStateType `json:"type"` + Date int `json:"date"` + URL string `json:"url"` +} + +// RevenueWithdrawalStateFailed https://core.telegram.org/bots/api#revenuewithdrawalstatefailed +type RevenueWithdrawalStateFailed struct { + Type RevenueWithdrawalStateType `json:"type"` +} + +// StarTransaction https://core.telegram.org/bots/api#startransaction +type StarTransaction struct { + ID string `json:"id"` + Amount int `json:"amount"` + Date int `json:"date"` + Source *TransactionPartner `json:"source,omitempty"` + Receiver *TransactionPartner `json:"receiver,omitempty"` +} + +// StarTransactions https://core.telegram.org/bots/api#startransactions +type StarTransactions struct { + Transactions []StarTransaction `json:"transactions"` +} diff --git a/models/star_test.go b/models/star_test.go new file mode 100644 index 0000000..db882b6 --- /dev/null +++ b/models/star_test.go @@ -0,0 +1,148 @@ +package models + +import ( + "encoding/json" + "testing" +) + +func TestTransactionPartner_UnmarshalJSON_User(t *testing.T) { + src := `{"type":"user","user":{"id":42}}` + + m := TransactionPartner{} + + err := json.Unmarshal([]byte(src), &m) + if err != nil { + t.Fatal(err) + } + + if m.Type != TransactionPartnerTypeUser { + t.Fatalf("invalid type %s, expect %s", m.Type, TransactionPartnerTypeUser) + } + + if m.User == nil { + t.Fatal("invalid User") + } + + if m.User.User.ID != 42 { + t.Fatalf("invalid id %d, expect 42", m.User.User.ID) + } +} + +func TestTransactionPartner_UnmarshalJSON_Other(t *testing.T) { + src := `{"type":"other"}` + + m := TransactionPartner{} + + err := json.Unmarshal([]byte(src), &m) + if err != nil { + t.Fatal(err) + } + + if m.Type != TransactionPartnerTypeOther { + t.Fatalf("invalid type %s, expect %s", m.Type, TransactionPartnerTypeOther) + } +} + +func TestTransactionPartner_UnmarshalJSON_Fragment(t *testing.T) { + src := `{"type":"fragment","withdrawal_state":{"type":"pending"}}` + + m := TransactionPartner{} + + err := json.Unmarshal([]byte(src), &m) + if err != nil { + t.Fatal(err) + } + + if m.Type != TransactionPartnerTypeFragment { + t.Fatalf("invalid type %s, expect %s", m.Type, TransactionPartnerTypeFragment) + } + + if m.Fragment == nil { + t.Fatal("invalid Fragment") + } + + if m.Fragment.WithdrawalState == nil { + t.Fatal("invalid WithdrawalState") + } + + if m.Fragment.WithdrawalState.Type != RevenueWithdrawalStateTypePending { + t.Fatalf("invalid type %s, expect %s", m.Fragment.WithdrawalState.Type, RevenueWithdrawalStateTypePending) + } +} + +func TestRevenueWithdrawalState_UnmarshalJSON_Pending(t *testing.T) { + src := `{"type":"pending"}` + + m := RevenueWithdrawalState{} + + err := json.Unmarshal([]byte(src), &m) + if err != nil { + t.Fatal(err) + } + + if m.Type != RevenueWithdrawalStateTypePending { + t.Fatalf("invalid type %s, expect %s", m.Type, RevenueWithdrawalStateTypePending) + } + + if m.Pending == nil { + t.Fatal("invalid Pending") + } + + if m.Pending.Type != RevenueWithdrawalStateTypePending { + t.Fatalf("invalid type %s, expect %s", m.Pending.Type, RevenueWithdrawalStateTypePending) + } +} + +func TestRevenueWithdrawalState_UnmarshalJSON_Succeeded(t *testing.T) { + src := `{"type":"succeeded","date":1,"url":"xxx"}` + + m := RevenueWithdrawalState{} + + err := json.Unmarshal([]byte(src), &m) + if err != nil { + t.Fatal(err) + } + + if m.Type != RevenueWithdrawalStateTypeSucceeded { + t.Fatalf("invalid type %s, expect %s", m.Type, RevenueWithdrawalStateTypeSucceeded) + } + + if m.Succeeded == nil { + t.Fatal("invalid Succeeded") + } + + if m.Succeeded.Type != RevenueWithdrawalStateTypeSucceeded { + t.Fatalf("invalid type %s, expect %s", m.Pending.Type, RevenueWithdrawalStateTypeSucceeded) + } + + if m.Succeeded.Date != 1 { + t.Fatalf("invalid date %d, expect 1", m.Succeeded.Date) + } + + if m.Succeeded.URL != "xxx" { + t.Fatalf("invalid url %s, expect xxx", m.Succeeded.URL) + } +} + +func TestRevenueWithdrawalState_UnmarshalJSON_Failed(t *testing.T) { + src := `{"type":"failed"}` + + m := RevenueWithdrawalState{} + + err := json.Unmarshal([]byte(src), &m) + if err != nil { + t.Fatal(err) + } + + if m.Type != RevenueWithdrawalStateTypeFailed { + t.Fatalf("invalid type %s, expect %s", m.Type, RevenueWithdrawalStateTypeFailed) + } + + if m.Failed == nil { + t.Fatal("invalid Failed") + } + + if m.Failed.Type != RevenueWithdrawalStateTypeFailed { + t.Fatalf("invalid type %s, expect %s", m.Pending.Type, RevenueWithdrawalStateTypeFailed) + } +} From 598e71ff3c21ff5c6757dd408bb6a258c4947f4d Mon Sep 17 00:00:00 2001 From: negasus Date: Mon, 24 Jun 2024 13:12:40 +0300 Subject: [PATCH 2/2] update readme, changelog --- CHANGELOG.md | 4 ++++ README.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 564ca36..b2c2411 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v1.5.0 (2024-06-24) + +- support API v7.5 + ## v1.4.1 (2024-06-19) - fix: getGameHighScores returns an array of high scores instead of a single object (#94) diff --git a/README.md b/README.md index 3c8d061..b1be162 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ > [Telegram Group](https://t.me/gotelegrambotui) -> Supports Bot API version: [7.4](https://core.telegram.org/bots/api#may-28-2024) from May 28, 2024 +> Supports Bot API version: [7.5](https://core.telegram.org/bots/api#june-18-2024) from June 18, 2024 It's a Go zero-dependencies telegram bot framework