Repository: mr-linch/go-tg
Pull request #74 (2022-07-28 08:27:48)

feat(tg): add UpdateType and Update.Type method

codecov[bot]: # [Codecov](https://codecov.io/gh/mr-linch/go-tg/pull/74?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Sasha+Savchuk) Report
> Merging [#74](https://codecov.io/gh/mr-linch/go-tg/pull/74?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Sasha+Savchuk) (5a0fc18) into [main](https://codecov.io/gh/mr-linch/go-tg/commit/88bd98e977dfa4e6bb317565981cfaf54a9d905f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Sasha+Savchuk) (88bd98e) will **increase** coverage by `0.43%`.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff             @@
##             main      #74      +/-   ##
==========================================
+ Coverage   90.40%   90.83%   +0.43%     
==========================================
  Files          17       17              
  Lines        1896     1986      +90     
==========================================
+ Hits         1714     1804      +90     
  Misses        149      149              
  Partials       33       33              
```


| [Impacted Files](https://codecov.io/gh/mr-linch/go-tg/pull/74?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Sasha+Savchuk) | Coverage Δ | |
|---|---|---|
| [tgb/polling.go](https://codecov.io/gh/mr-linch/go-tg/pull/74/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Sasha+Savchuk#diff-dGdiL3BvbGxpbmcuZ28=) | `84.07% <100.00%> (ø)` | |
| [tgb/webhook.go](https://codecov.io/gh/mr-linch/go-tg/pull/74/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Sasha+Savchuk#diff-dGdiL3dlYmhvb2suZ28=) | `85.71% <100.00%> (ø)` | |
| [types\_gen\_ext.go](https://codecov.io/gh/mr-linch/go-tg/pull/74/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Sasha+Savchuk#diff-dHlwZXNfZ2VuX2V4dC5nbw==) | `100.00% <100.00%> (ø)` | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Sasha+Savchuk).


Patch:
diff --git a/methods_gen.go b/methods_gen.go
index cce5577..bc2904c 100644
--- a/methods_gen.go
+++ b/methods_gen.go
@@ -46,7 +46,7 @@ func (call *GetUpdatesCall) Timeout(timeout int) *GetUpdatesCall {
 }
 
 // AllowedUpdates A JSON-serialized list of the update types you want your bot to receive. For example, specify [“message”, “edited_channel_post”, “callback_query”] to only receive updates of these types. See Update for a complete list of available update types. Specify an empty list to receive all update types except chat_member (default). If not specified, the previous setting will be used.Please note that this parameter doesn't affect updates created before the call to the getUpdates, so unwanted updates may be received for a short period of time.
-func (call *GetUpdatesCall) AllowedUpdates(allowedUpdates []string) *GetUpdatesCall {
+func (call *GetUpdatesCall) AllowedUpdates(allowedUpdates []UpdateType) *GetUpdatesCall {
 	call.request.JSON("allowed_updates", allowedUpdates)
 	return call
 }
@@ -105,7 +105,7 @@ func (call *SetWebhookCall) MaxConnections(maxConnections int) *SetWebhookCall {
 }
 
 // AllowedUpdates A JSON-serialized list of the update types you want your bot to receive. For example, specify [“message”, “edited_channel_post”, “callback_query”] to only receive updates of these types. See Update for a complete list of available update types. Specify an empty list to receive all update types except chat_member (default). If not specified, the previous setting will be used.Please note that this parameter doesn't affect updates created before the call to the setWebhook, so unwanted updates may be received for a short period of time.
-func (call *SetWebhookCall) AllowedUpdates(allowedUpdates []string) *SetWebhookCall {
+func (call *SetWebhookCall) AllowedUpdates(allowedUpdates []UpdateType) *SetWebhookCall {
 	call.request.JSON("allowed_updates", allowedUpdates)
 	return call
 }
diff --git a/tgb/polling.go b/tgb/polling.go
index 3a9ea8e..6fec895 100644
--- a/tgb/polling.go
+++ b/tgb/polling.go
@@ -19,7 +19,7 @@ type Poller struct {
 	timeout        time.Duration
 	retryAfter     time.Duration
 	limit          int
-	allowedUpdates []string
+	allowedUpdates []tg.UpdateType
 
 	wg sync.WaitGroup
 }
@@ -55,7 +55,7 @@ func WithPollerLimit(limit int) PollerOption {
 }
 
 // WithPollerAllowedUpdates sets the allowed updates.
-func WithPollerAllowedUpdates(allowedUpdates ...string) PollerOption {
+func WithPollerAllowedUpdates(allowedUpdates ...tg.UpdateType) PollerOption {
 	return func(poller *Poller) {
 		poller.allowedUpdates = allowedUpdates
 	}
@@ -78,7 +78,7 @@ func NewPoller(handler Handler, client *tg.Client, opts ...PollerOption) *Poller
 		timeout:    time.Second * 5,
 		retryAfter: time.Second * 5,
 
-		allowedUpdates: []string{},
+		allowedUpdates: []tg.UpdateType{},
 
 		limit: defaultPollerLimit,
 	}
diff --git a/tgb/webhook.go b/tgb/webhook.go
index 3aa6c25..394121d 100644
--- a/tgb/webhook.go
+++ b/tgb/webhook.go
@@ -25,7 +25,7 @@ type Webhook struct {
 	ip                 string
 	maxConnections     int
 	dropPendingUpdates bool
-	allowedUpdates     []string
+	allowedUpdates     []tg.UpdateType
 
 	securitySubnets []netip.Prefix
 	securityToken   string
@@ -93,7 +93,7 @@ func WithWebhookMaxConnections(maxConnections int) WebhookOption {
 // If not specified, the previous setting will be used.
 // Please note that this parameter doesn't affect updates created before the call to the setWebhook,
 // so unwanted updates may be received for a short period of time.
-func WithWebhookAllowedUpdates(updates ...string) WebhookOption {
+func WithWebhookAllowedUpdates(updates ...tg.UpdateType) WebhookOption {
 	return func(webhook *Webhook) {
 		webhook.allowedUpdates = updates
 	}
@@ -111,7 +111,7 @@ func NewWebhook(handler Handler, client *tg.Client, url string, options ...Webho
 
 		dropPendingUpdates: false,
 
-		allowedUpdates:  []string{},
+		allowedUpdates:  []tg.UpdateType{},
 		securitySubnets: defaultSubnets,
 		securityToken:   token,
 	}
diff --git a/types_gen.go b/types_gen.go
index 0d88add..f33bacc 100644
--- a/types_gen.go
+++ b/types_gen.go
@@ -82,7 +82,7 @@ type WebhookInfo struct {
 	MaxConnections int `json:"max_connections,omitempty"`
 
 	// Optional. A list of update types the bot is subscribed to. Defaults to all update types except chat_member
-	AllowedUpdates []string `json:"allowed_updates,omitempty"`
+	AllowedUpdates []UpdateType `json:"allowed_updates,omitempty"`
 }
 
 // User this object represents a Telegram user or bot.
diff --git a/types_gen_ext.go b/types_gen_ext.go
index 883dd5f..faf24bb 100644
--- a/types_gen_ext.go
+++ b/types_gen_ext.go
@@ -862,3 +862,130 @@ func (msg *Message) Type() MessageType {
 		return MessageTypeUnknown
 	}
 }
+
+// UpdateType it's type for describe content of Update.
+type UpdateType int
+
+const (
+	UpdateTypeUnknown UpdateType = iota
+	UpdateTypeMessage
+	UpdateTypeEditedMessage
+	UpdateTypeChannelPost
+	UpdateTypeEditedChannelPost
+	UpdateTypeInlineQuery
+	UpdateTypeChosenInlineResult
+	UpdateTypeCallbackQuery
+	UpdateTypeShippingQuery
+	UpdateTypePreCheckoutQuery
+	UpdateTypePoll
+	UpdateTypePollAnswer
+	UpdateTypeMyChatMember
+	UpdateTypeChatMember
+	UpdateTypeChatJoinRequest
+)
+
+// MarshalText implements encoding.TextMarshaler.
+func (typ UpdateType) MarshalText() ([]byte, error) {
+	if typ != UpdateTypeUnknown {
+		return []byte(typ.String()), nil
+	}
+
+	return nil, fmt.Errorf("unknown update type")
+}
+
+// UnmarshalText implements encoding.TextUnmarshaler.
+func (typ *UpdateType) UnmarshalText(v []byte) error {
+	switch string(v) {
+	case "message":
+		*typ = UpdateTypeMessage
+	case "edited_message":
+		*typ = UpdateTypeEditedMessage
+	case "channel_post":
+		*typ = UpdateTypeChannelPost
+	case "edited_channel_post":
+		*typ = UpdateTypeEditedChannelPost
+	case "inline_query":
+		*typ = UpdateTypeInlineQuery
+	case "chosen_inline_result":
+		*typ = UpdateTypeChosenInlineResult
+	case "callback_query":
+		*typ = UpdateTypeCallbackQuery
+	case "shipping_query":
+		*typ = UpdateTypeShippingQuery
+	case "pre_checkout_query":
+		*typ = UpdateTypePreCheckoutQuery
+	case "poll":
+		*typ = UpdateTypePoll
+	case "poll_answer":
+		*typ = UpdateTypePollAnswer
+	case "my_chat_member":
+		*typ = UpdateTypeMyChatMember
+	case "chat_member":
+		*typ = UpdateTypeChatMember
+	case "chat_join_request":
+		*typ = UpdateTypeChatJoinRequest
+	default:
+		return fmt.Errorf("unknown update type")
+	}
+
+	return nil
+}
+
+// String returns string representation of UpdateType.
+func (typ UpdateType) String() string {
+	if typ > UpdateTypeUnknown && typ <= UpdateTypeChatJoinRequest {
+		return [...]string{
+			"message",
+			"edited_message",
+			"channel_post",
+			"edited_channel_post",
+			"inline_query",
+			"chosen_inline_result",
+			"callback_query",
+			"shipping_query",
+			"pre_checkout_query",
+			"poll",
+			"poll_answer",
+			"my_chat_member",
+			"chat_member",
+			"chat_join_request",
+		}[typ-1]
+	}
+
+	return "unknown"
+}
+
+func (update *Update) Type() UpdateType {
+	switch {
+	case update.Message != nil:
+		return UpdateTypeMessage
+	case update.EditedMessage != nil:
+		return UpdateTypeEditedMessage
+	case update.ChannelPost != nil:
+		return UpdateTypeChannelPost
+	case update.EditedChannelPost != nil:
+		return UpdateTypeEditedChannelPost
+	case update.InlineQuery != nil:
+		return UpdateTypeInlineQuery
+	case update.ChosenInlineResult != nil:
+		return UpdateTypeChosenInlineResult
+	case update.CallbackQuery != nil:
+		return UpdateTypeCallbackQuery
+	case update.ShippingQuery != nil:
+		return UpdateTypeShippingQuery
+	case update.PreCheckoutQuery != nil:
+		return UpdateTypePreCheckoutQuery
+	case update.Poll != nil:
+		return UpdateTypePoll
+	case update.PollAnswer != nil:
+		return UpdateTypePollAnswer
+	case update.MyChatMember != nil:
+		return UpdateTypeMyChatMember
+	case update.ChatMember != nil:
+		return UpdateTypeChatMember
+	case update.ChatJoinRequest != nil:
+		return UpdateTypeChatJoinRequest
+	default:
+		return UpdateTypeUnknown
+	}
+}


Test patch:
diff --git a/tgb/polling_test.go b/tgb/polling_test.go
index 0d4848b..6c94701 100644
--- a/tgb/polling_test.go
+++ b/tgb/polling_test.go
@@ -125,7 +125,7 @@ func TestPoller(t *testing.T) {
 			tg.New("1234:secret", tg.WithClientServerURL(server.URL), tg.WithClientDoer(server.Client())),
 			WithPollerRetryAfter(time.Millisecond),
 			WithPollerHandlerTimeout(time.Millisecond),
-			WithPollerAllowedUpdates("callback_query"),
+			WithPollerAllowedUpdates(tg.UpdateTypeCallbackQuery),
 			WithPollerLimit(50),
 			WithPollerTimeout(time.Second*2),
 		).Run(ctx)
diff --git a/tgb/webhook_test.go b/tgb/webhook_test.go
index c4c2680..881ce9a 100644
--- a/tgb/webhook_test.go
+++ b/tgb/webhook_test.go
@@ -344,7 +344,7 @@ func TestWebhook_Setup(t *testing.T) {
 			HandlerFunc(func(ctx context.Context, update *Update) error { return nil }),
 			tg.New("1234:secret", tg.WithClientServerURL(server.URL), tg.WithClientDoer(server.Client())),
 			"https://google.com",
-			WithWebhookAllowedUpdates("message"),
+			WithWebhookAllowedUpdates(tg.UpdateTypeMessage),
 			WithWebhookIP("1.1.1.1"),
 		)
 
diff --git a/types_gen_ext_test.go b/types_gen_ext_test.go
index 99b7a26..ccdf459 100644
--- a/types_gen_ext_test.go
+++ b/types_gen_ext_test.go
@@ -731,3 +731,155 @@ func TestMessage_Type(t *testing.T) {
 		assert.Equal(t, test.Want, test.Message.Type())
 	}
 }
+
+func TestUpdateType_String(t *testing.T) {
+	for _, test := range []struct {
+		Type UpdateType
+		Want string
+	}{
+		{UpdateTypeUnknown, "unknown"},
+		{UpdateTypeMessage, "message"},
+		{UpdateTypeEditedMessage, "edited_message"},
+		{UpdateTypeChannelPost, "channel_post"},
+		{UpdateTypeEditedChannelPost, "edited_channel_post"},
+		{UpdateTypeInlineQuery, "inline_query"},
+		{UpdateTypeChosenInlineResult, "chosen_inline_result"},
+		{UpdateTypeCallbackQuery, "callback_query"},
+		{UpdateTypeShippingQuery, "shipping_query"},
+		{UpdateTypePreCheckoutQuery, "pre_checkout_query"},
+		{UpdateTypePoll, "poll"},
+		{UpdateTypePollAnswer, "poll_answer"},
+		{UpdateTypeMyChatMember, "my_chat_member"},
+		{UpdateTypeChatMember, "chat_member"},
+		{UpdateTypeChatJoinRequest, "chat_join_request"},
+	} {
+		assert.Equal(t, test.Want, test.Type.String())
+	}
+}
+
+func TestUpdateType_UnmarshalText(t *testing.T) {
+	for _, test := range []struct {
+		Text string
+		Want UpdateType
+		Err  bool
+	}{
+		{"message", UpdateTypeMessage, false},
+		{"edited_message", UpdateTypeEditedMessage, false},
+		{"channel_post", UpdateTypeChannelPost, false},
+		{"edited_channel_post", UpdateTypeEditedChannelPost, false},
+		{"inline_query", UpdateTypeInlineQuery, false},
+		{"chosen_inline_result", UpdateTypeChosenInlineResult, false},
+		{"callback_query", UpdateTypeCallbackQuery, false},
+		{"shipping_query", UpdateTypeShippingQuery, false},
+		{"pre_checkout_query", UpdateTypePreCheckoutQuery, false},
+		{"poll", UpdateTypePoll, false},
+		{"poll_answer", UpdateTypePollAnswer, false},
+		{"my_chat_member", UpdateTypeMyChatMember, false},
+		{"chat_member", UpdateTypeChatMember, false},
+		{"chat_join_request", UpdateTypeChatJoinRequest, false},
+		{"test", UpdateTypeUnknown, true},
+	} {
+		var typ UpdateType
+
+		err := typ.UnmarshalText([]byte(test.Text))
+
+		if test.Err {
+			assert.Error(t, err)
+		} else {
+			assert.NoError(t, err)
+			assert.Equal(t, test.Want, typ)
+		}
+	}
+}
+
+func TestUpdateType_MarshalText(t *testing.T) {
+	v := UpdateTypeEditedMessage
+
+	b, err := v.MarshalText()
+	assert.NoError(t, err)
+	assert.Equal(t, []byte("edited_message"), b)
+
+	v = UpdateTypeUnknown
+	_, err = v.MarshalText()
+	assert.Error(t, err)
+
+	output, err := json.Marshal(struct {
+		Type []UpdateType `json:"type"`
+	}{
+		Type: []UpdateType{UpdateTypeCallbackQuery, UpdateTypeChannelPost},
+	})
+
+	assert.NoError(t, err)
+	assert.Equal(t, `{"type":["callback_query","channel_post"]}`, string(output))
+
+}
+
+func TestUpdate_Type(t *testing.T) {
+	for _, test := range []struct {
+		Update *Update
+		Want   UpdateType
+	}{
+		{
+			Update: &Update{},
+			Want:   UpdateTypeUnknown,
+		},
+		{
+			Update: &Update{Message: &Message{}},
+			Want:   UpdateTypeMessage,
+		},
+		{
+			Update: &Update{EditedMessage: &Message{}},
+			Want:   UpdateTypeEditedMessage,
+		},
+		{
+			Update: &Update{ChannelPost: &Message{}},
+			Want:   UpdateTypeChannelPost,
+		},
+		{
+			Update: &Update{EditedChannelPost: &Message{}},
+			Want:   UpdateTypeEditedChannelPost,
+		},
+		{
+			Update: &Update{InlineQuery: &InlineQuery{}},
+			Want:   UpdateTypeInlineQuery,
+		},
+		{
+			Update: &Update{ChosenInlineResult: &ChosenInlineResult{}},
+			Want:   UpdateTypeChosenInlineResult,
+		},
+		{
+			Update: &Update{CallbackQuery: &CallbackQuery{}},
+			Want:   UpdateTypeCallbackQuery,
+		},
+		{
+			Update: &Update{ShippingQuery: &ShippingQuery{}},
+			Want:   UpdateTypeShippingQuery,
+		},
+		{
+			Update: &Update{PreCheckoutQuery: &PreCheckoutQuery{}},
+			Want:   UpdateTypePreCheckoutQuery,
+		},
+		{
+			Update: &Update{Poll: &Poll{}},
+			Want:   UpdateTypePoll,
+		},
+		{
+			Update: &Update{PollAnswer: &PollAnswer{}},
+			Want:   UpdateTypePollAnswer,
+		},
+		{
+			Update: &Update{MyChatMember: &ChatMemberUpdated{}},
+			Want:   UpdateTypeMyChatMember,
+		},
+		{
+			Update: &Update{ChatJoinRequest: &ChatJoinRequest{}},
+			Want:   UpdateTypeChatJoinRequest,
+		},
+		{
+			Update: &Update{ChatMember: &ChatMemberUpdated{}},
+			Want:   UpdateTypeChatMember,
+		},
+	} {
+		assert.Equal(t, test.Want, test.Update.Type())
+	}
+}