Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(telegram): parse correctly ChatID and MessageThreadID #198

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 51 additions & 4 deletions receivers/telegram/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,34 +28,81 @@ type Config struct {
DisableNotifications bool `json:"disable_notifications,omitempty" yaml:"disable_notifications,omitempty"`
}

type unmarshalConfig struct {
BotToken string `json:"bottoken,omitempty" yaml:"bottoken,omitempty"`
ChatID any `json:"chatid,omitempty" yaml:"chatid,omitempty"`
MessageThreadID any `json:"message_thread_id,omitempty" yaml:"message_thread_id,omitempty"`
Message string `json:"message,omitempty" yaml:"message,omitempty"`
ParseMode string `json:"parse_mode,omitempty" yaml:"parse_mode,omitempty"`
DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty" yaml:"disable_web_page_preview,omitempty"`
ProtectContent bool `json:"protect_content,omitempty" yaml:"protect_content,omitempty"`
DisableNotifications bool `json:"disable_notifications,omitempty" yaml:"disable_notifications,omitempty"`
}

func NewConfig(jsonData json.RawMessage, decryptFn receivers.DecryptFunc) (Config, error) {
settings := Config{}
err := json.Unmarshal(jsonData, &settings)

unmarshaledConfig := unmarshalConfig{}
err := json.Unmarshal(jsonData, &unmarshaledConfig)
if err != nil {
return settings, fmt.Errorf("failed to unmarshal settings: %w", err)
}

settings.BotToken = unmarshaledConfig.BotToken
settings.Message = unmarshaledConfig.Message
settings.ParseMode = unmarshaledConfig.ParseMode
settings.DisableWebPagePreview = unmarshaledConfig.DisableWebPagePreview
settings.ProtectContent = unmarshaledConfig.ProtectContent
settings.DisableNotifications = unmarshaledConfig.DisableNotifications

settings.BotToken = decryptFn("bottoken", settings.BotToken)
if settings.BotToken == "" {
return settings, errors.New("could not find Bot Token in settings")
}
if settings.ChatID == "" {

switch chatID := unmarshaledConfig.ChatID.(type) {
case string:
settings.ChatID = chatID

case float64:
settings.ChatID = strconv.Itoa(int(chatID))

case nil:
return settings, errors.New("could not find Chat Id in settings")

default:
return settings, errors.New("chat id must be either a string or an int")
}

if settings.Message == "" {
settings.Message = templates.DefaultMessageEmbed
}

var messageThreadID int
if settings.MessageThreadID != "" {
messageThreadID, err = strconv.Atoi(settings.MessageThreadID)
switch id := unmarshaledConfig.MessageThreadID.(type) {
case string:
messageThreadID, err = strconv.Atoi(id)
if err != nil {
return settings, errors.New("message thread id must be an integer")
}

case float64:
messageThreadID = int(id)

case nil:

default:
return settings, errors.New("message thread id must be either a string or an int")
}

if messageThreadID != 0 {
if messageThreadID != int(int32(messageThreadID)) {
return settings, errors.New("message thread id must be an int32")
}

settings.MessageThreadID = strconv.Itoa(messageThreadID)
}

// if field is missing, then we fall back to the previous default: HTML
if settings.ParseMode == "" {
settings.ParseMode = DefaultTelegramParseMode
Expand Down
73 changes: 63 additions & 10 deletions receivers/telegram/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,33 @@ func TestNewConfig(t *testing.T) {
settings: `{ "bottoken" : "12345" }`,
expectedInitError: `could not find Chat Id in settings`,
},

{
name: "Error if chatid is not a string or an int",
settings: `{ "bottoken": "12345", "chatid" : {} }`,
expectedInitError: `chat id must be either a string or an int`,
},
{
name: "should be able to parse an int ChatID",
settings: `{"chatid": 12345678}`,
secureSettings: map[string][]byte{
"bottoken": []byte("test-token"),
},
expectedConfig: Config{
BotToken: "test-token",
ChatID: "12345678",
Message: templates.DefaultMessageEmbed,
ParseMode: "HTML",
DisableWebPagePreview: false,
ProtectContent: false,
DisableNotifications: false,
},
},
{
name: "Minimal valid configuration",
settings: `{ "bottoken": "test-token", "chatid": "test-chat-id" }`,
settings: `{ "bottoken": "test-token", "chatid": "-1312" }`,
expectedConfig: Config{
BotToken: "test-token",
ChatID: "test-chat-id",
ChatID: "-1312",
Message: templates.DefaultMessageEmbed,
ParseMode: DefaultTelegramParseMode,
DisableWebPagePreview: false,
Expand All @@ -54,13 +74,13 @@ func TestNewConfig(t *testing.T) {
},
{
name: "Minimal valid configuration from secrets",
settings: `{"chatid": "test-chat-id" }`,
settings: `{"chatid": "-1312" }`,
secureSettings: map[string][]byte{
"bottoken": []byte("test-token"),
},
expectedConfig: Config{
BotToken: "test-token",
ChatID: "test-chat-id",
ChatID: "-1312",
Message: templates.DefaultMessageEmbed,
ParseMode: DefaultTelegramParseMode,
DisableWebPagePreview: false,
Expand All @@ -70,13 +90,13 @@ func TestNewConfig(t *testing.T) {
},
{
name: "Should overwrite token from secrets",
settings: `{"bottoken": "token", "chatid" : "test-chat-id" }`,
settings: `{"bottoken": "token", "chatid" : "-1312" }`,
secureSettings: map[string][]byte{
"bottoken": []byte("test-token-key"),
},
expectedConfig: Config{
BotToken: "test-token-key",
ChatID: "test-chat-id",
ChatID: "-1312",
Message: templates.DefaultMessageEmbed,
ParseMode: DefaultTelegramParseMode,
DisableWebPagePreview: false,
Expand All @@ -87,7 +107,7 @@ func TestNewConfig(t *testing.T) {
{
name: "All empty fields = minimal valid configuration",
settings: `{
"chatid" :"chat-id",
"chatid" :"-1312",
"message" :"",
"parse_mode" :"",
"disable_notifications" : null
Expand All @@ -97,7 +117,7 @@ func TestNewConfig(t *testing.T) {
},
expectedConfig: Config{
BotToken: "test-token",
ChatID: "chat-id",
ChatID: "-1312",
Message: templates.DefaultMessageEmbed,
ParseMode: DefaultTelegramParseMode,
DisableWebPagePreview: false,
Expand Down Expand Up @@ -191,13 +211,38 @@ func TestNewConfig(t *testing.T) {
},
},
{
name: "should fail if message_thread_id is not an int",
name: "should be able to parse an int MessageThreadID",
settings: `{"chatid": -1312, "message_thread_id": 12345678}`,
secureSettings: map[string][]byte{
"bottoken": []byte("test-token"),
},
expectedConfig: Config{
BotToken: "test-token",
ChatID: "-1312",
MessageThreadID: "12345678",
Message: templates.DefaultMessageEmbed,
ParseMode: "HTML",
DisableWebPagePreview: false,
ProtectContent: false,
DisableNotifications: false,
},
},
{
name: "should fail if message_thread_id is not an int #1",
settings: `{"chatid": "12345678", "message_thread_id": "notanint"}`,
secureSettings: map[string][]byte{
"bottoken": []byte("test-token"),
},
expectedInitError: "message thread id must be an integer",
},
{
name: "should fail if message_thread_id is not an int #2",
settings: `{"chatid": "12345678", "message_thread_id": {}}`,
secureSettings: map[string][]byte{
"bottoken": []byte("test-token"),
},
expectedInitError: "message thread id must be either a string or an int",
},
{
name: "should fail if message_thread_id is not a valid int32",
settings: `{"chatid": "12345678", "message_thread_id": "21474836471"}`,
Expand All @@ -206,6 +251,14 @@ func TestNewConfig(t *testing.T) {
},
expectedInitError: "message thread id must be an int32",
},
{
name: "should fail if message_thread_id is not a valid int32",
settings: `{"chatid": -1312, "message_thread_id": 21474836471}`,
secureSettings: map[string][]byte{
"bottoken": []byte("test-token"),
},
expectedInitError: "message thread id must be an int32",
},
}

for _, c := range cases {
Expand Down