Refactoring and DRYing
@@ -183,27 +183,10 @@ //
// Requires ChatID and Text. // DisableWebPagePreview, ReplyToMessageID, and ReplyMarkup are optional. func (bot *BotAPI) SendMessage(config MessageConfig) (Message, error) { - v := url.Values{} - if config.ChannelUsername != "" { - v.Add("chat_id", config.ChannelUsername) - } else { - v.Add("chat_id", strconv.Itoa(config.ChatID)) - } - v.Add("text", config.Text) - v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview)) - if config.ParseMode != "" { - v.Add("parse_mode", config.ParseMode) - } - if config.ReplyToMessageID != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) - } - if config.ReplyMarkup != nil { - data, err := json.Marshal(config.ReplyMarkup) - if err != nil { - return Message{}, err - } + v, err := config.Values() - v.Add("reply_markup", string(data)) + if err != nil { + return Message{}, err } resp, err := bot.MakeRequest("SendMessage", v)@@ -226,18 +209,7 @@ // ForwardMessage forwards a message from one chat to another.
// // Requires ChatID (destination), FromChatID (source), and MessageID. func (bot *BotAPI) ForwardMessage(config ForwardConfig) (Message, error) { - v := url.Values{} - if config.ChannelUsername != "" { - v.Add("chat_id", config.ChannelUsername) - } else { - v.Add("chat_id", strconv.Itoa(config.ChatID)) - } - if config.FromChannelUsername != "" { - v.Add("chat_id", config.FromChannelUsername) - } else { - v.Add("chat_id", strconv.Itoa(config.FromChatID)) - } - v.Add("message_id", strconv.Itoa(config.MessageID)) + v, _:= config.Values() resp, err := bot.MakeRequest("forwardMessage", v) if err != nil {@@ -262,26 +234,10 @@ // Caption, ReplyToMessageID, and ReplyMarkup are optional.
// File should be either a string, FileBytes, or FileReader. func (bot *BotAPI) SendPhoto(config PhotoConfig) (Message, error) { if config.UseExistingPhoto { - v := url.Values{} - if config.ChannelUsername != "" { - v.Add("chat_id", config.ChannelUsername) - } else { - v.Add("chat_id", strconv.Itoa(config.ChatID)) - } - v.Add("photo", config.FileID) - if config.Caption != "" { - v.Add("caption", config.Caption) - } - if config.ReplyToMessageID != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) - } - if config.ReplyMarkup != nil { - data, err := json.Marshal(config.ReplyMarkup) - if err != nil { - return Message{}, err - } + v, err := config.Values() - v.Add("reply_markup", string(data)) + if err != nil { + return Message{}, err } resp, err := bot.MakeRequest("SendPhoto", v)@@ -356,32 +312,9 @@ // ReplyToMessageID and ReplyMarkup are optional.
// File should be either a string, FileBytes, or FileReader. func (bot *BotAPI) SendAudio(config AudioConfig) (Message, error) { if config.UseExistingAudio { - v := url.Values{} - if config.ChannelUsername != "" { - v.Add("chat_id", config.ChannelUsername) - } else { - v.Add("chat_id", strconv.Itoa(config.ChatID)) - } - v.Add("audio", config.FileID) - if config.ReplyToMessageID != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) - } - if config.Duration != 0 { - v.Add("duration", strconv.Itoa(config.Duration)) - } - if config.ReplyMarkup != nil { - data, err := json.Marshal(config.ReplyMarkup) - if err != nil { - return Message{}, err - } - - v.Add("reply_markup", string(data)) - } - if config.Performer != "" { - v.Add("performer", config.Performer) - } - if config.Title != "" { - v.Add("title", config.Title) + v, err := config.Values() + if err != nil { + return Message{}, err } resp, err := bot.MakeRequest("sendAudio", v)@@ -457,23 +390,9 @@ // ReplyToMessageID and ReplyMarkup are optional.
// File should be either a string, FileBytes, or FileReader. func (bot *BotAPI) SendDocument(config DocumentConfig) (Message, error) { if config.UseExistingDocument { - v := url.Values{} - if config.ChannelUsername != "" { - v.Add("chat_id", config.ChannelUsername) - } else { - v.Add("chat_id", strconv.Itoa(config.ChatID)) - } - v.Add("document", config.FileID) - if config.ReplyToMessageID != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) - } - if config.ReplyMarkup != nil { - data, err := json.Marshal(config.ReplyMarkup) - if err != nil { - return Message{}, err - } - - v.Add("reply_markup", string(data)) + v, err := config.Values() + if err != nil { + return Message{}, err } resp, err := bot.MakeRequest("sendDocument", v)@@ -542,26 +461,9 @@ // ReplyToMessageID and ReplyMarkup are optional.
// File should be either a string, FileBytes, or FileReader. func (bot *BotAPI) SendVoice(config VoiceConfig) (Message, error) { if config.UseExistingVoice { - v := url.Values{} - if config.ChannelUsername != "" { - v.Add("chat_id", config.ChannelUsername) - } else { - v.Add("chat_id", strconv.Itoa(config.ChatID)) - } - v.Add("voice", config.FileID) - if config.ReplyToMessageID != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) - } - if config.Duration != 0 { - v.Add("duration", strconv.Itoa(config.Duration)) - } - if config.ReplyMarkup != nil { - data, err := json.Marshal(config.ReplyMarkup) - if err != nil { - return Message{}, err - } - - v.Add("reply_markup", string(data)) + v, err := config.Values() + if err != nil { + return Message{}, err } resp, err := bot.MakeRequest("sendVoice", v)@@ -631,23 +533,9 @@ // ReplyToMessageID and ReplyMarkup are optional.
// File should be either a string, FileBytes, or FileReader. func (bot *BotAPI) SendSticker(config StickerConfig) (Message, error) { if config.UseExistingSticker { - v := url.Values{} - if config.ChannelUsername != "" { - v.Add("chat_id", config.ChannelUsername) - } else { - v.Add("chat_id", strconv.Itoa(config.ChatID)) - } - v.Add("sticker", config.FileID) - if config.ReplyToMessageID != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) - } - if config.ReplyMarkup != nil { - data, err := json.Marshal(config.ReplyMarkup) - if err != nil { - return Message{}, err - } - - v.Add("reply_markup", string(data)) + v, err := config.Values() + if err != nil { + return Message{}, err } resp, err := bot.MakeRequest("sendSticker", v)@@ -714,29 +602,9 @@ // ReplyToMessageID and ReplyMarkup are optional.
// File should be either a string, FileBytes, or FileReader. func (bot *BotAPI) SendVideo(config VideoConfig) (Message, error) { if config.UseExistingVideo { - v := url.Values{} - if config.ChannelUsername != "" { - v.Add("chat_id", config.ChannelUsername) - } else { - v.Add("chat_id", strconv.Itoa(config.ChatID)) - } - v.Add("video", config.FileID) - if config.ReplyToMessageID != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) - } - if config.Duration != 0 { - v.Add("duration", strconv.Itoa(config.Duration)) - } - if config.Caption != "" { - v.Add("caption", config.Caption) - } - if config.ReplyMarkup != nil { - data, err := json.Marshal(config.ReplyMarkup) - if err != nil { - return Message{}, err - } - - v.Add("reply_markup", string(data)) + v, err := config.Values() + if err != nil { + return Message{}, err } resp, err := bot.MakeRequest("sendVideo", v)@@ -801,24 +669,9 @@ //
// Requires ChatID, Latitude, and Longitude. // ReplyToMessageID and ReplyMarkup are optional. func (bot *BotAPI) SendLocation(config LocationConfig) (Message, error) { - v := url.Values{} - if config.ChannelUsername != "" { - v.Add("chat_id", config.ChannelUsername) - } else { - v.Add("chat_id", strconv.Itoa(config.ChatID)) - } - v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64)) - v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64)) - if config.ReplyToMessageID != 0 { - v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) - } - if config.ReplyMarkup != nil { - data, err := json.Marshal(config.ReplyMarkup) - if err != nil { - return Message{}, err - } - - v.Add("reply_markup", string(data)) + v, err := config.Values() + if err != nil { + return Message{}, err } resp, err := bot.MakeRequest("sendLocation", v)@@ -841,13 +694,7 @@ // SendChatAction sets a current action in a chat.
// // Requires ChatID and a valid Action (see Chat constants). func (bot *BotAPI) SendChatAction(config ChatActionConfig) error { - v := url.Values{} - if config.ChannelUsername != "" { - v.Add("chat_id", config.ChannelUsername) - } else { - v.Add("chat_id", strconv.Itoa(config.ChatID)) - } - v.Add("action", config.Action) + v, _ := config.Values() _, err := bot.MakeRequest("sendChatAction", v) if err != nil {
@@ -3,6 +3,8 @@
import ( "io" "net/url" + "strconv" + "encoding/json" ) // Telegram constants@@ -42,6 +44,16 @@ ChatID int
ChannelUsername string } +func (chattable *Chattable) Values() (url.Values, error){ + v := url.Values{} + if chattable.ChannelUsername != "" { + v.Add("chat_id", chattable.ChannelUsername) + } else { + v.Add("chat_id", strconv.Itoa(chattable.ChatID)) + } + return v, nil +} + // MessageConfig contains information about a SendMessage request. type MessageConfig struct { Chattable@@ -52,6 +64,29 @@ ReplyToMessageID int
ReplyMarkup interface{} } +func (config *MessageConfig) Values() (url.Values, error) { + v, _ := config.Chattable.Values() + v.Add("text", config.Text) + v.Add("disable_web_page_preview", strconv.FormatBool(config.DisableWebPagePreview)) + if config.ParseMode != "" { + v.Add("parse_mode", config.ParseMode) + } + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) + } + if config.ReplyMarkup != nil { + data, err := json.Marshal(config.ReplyMarkup) + if err != nil { + return v, err + } + + v.Add("reply_markup", string(data)) + } + + + return v, nil +} + // ForwardConfig contains information about a ForwardMessage request. type ForwardConfig struct { Chattable@@ -60,6 +95,19 @@ FromChannelUsername string
MessageID int } +func (config *ForwardConfig) Values() (url.Values, error) { + v, _ := config.Chattable.Values() + + if config.FromChannelUsername != "" { + v.Add("chat_id", config.FromChannelUsername) + } else { + v.Add("chat_id", strconv.Itoa(config.FromChatID)) + } + v.Add("message_id", strconv.Itoa(config.MessageID)) + + return v, nil +} + // PhotoConfig contains information about a SendPhoto request. type PhotoConfig struct { Chattable@@ -72,6 +120,28 @@ File interface{}
FileID string } +func (config *PhotoConfig) Values() (url.Values, error) { + v, _ := config.Chattable.Values() + + v.Add("photo", config.FileID) + if config.Caption != "" { + v.Add("caption", config.Caption) + } + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) + } + if config.ReplyMarkup != nil { + data, err := json.Marshal(config.ReplyMarkup) + if err != nil { + return v, err + } + + v.Add("reply_markup", string(data)) + } + + return v, nil +} + // AudioConfig contains information about a SendAudio request. type AudioConfig struct { Chattable@@ -86,6 +156,34 @@ File interface{}
FileID string } +func (config *AudioConfig) Values() (url.Values, error) { + v, _ := config.Chattable.Values() + + v.Add("audio", config.FileID) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) + } + if config.Duration != 0 { + v.Add("duration", strconv.Itoa(config.Duration)) + } + if config.ReplyMarkup != nil { + data, err := json.Marshal(config.ReplyMarkup) + if err != nil { + return v, err + } + + v.Add("reply_markup", string(data)) + } + if config.Performer != "" { + v.Add("performer", config.Performer) + } + if config.Title != "" { + v.Add("title", config.Title) + } + + return v, nil +} + // DocumentConfig contains information about a SendDocument request. type DocumentConfig struct { Chattable@@ -97,6 +195,25 @@ File interface{}
FileID string } +func (config *DocumentConfig) Values() (url.Values, error) { + v, _ := config.Chattable.Values() + + v.Add("document", config.FileID) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) + } + if config.ReplyMarkup != nil { + data, err := json.Marshal(config.ReplyMarkup) + if err != nil { + return v, err + } + + v.Add("reply_markup", string(data)) + } + + return v, nil +} + // StickerConfig contains information about a SendSticker request. type StickerConfig struct { Chattable@@ -108,6 +225,25 @@ File interface{}
FileID string } +func (config *StickerConfig) Values() (url.Values, error) { + v, _ := config.Chattable.Values() + + v.Add("sticker", config.FileID) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) + } + if config.ReplyMarkup != nil { + data, err := json.Marshal(config.ReplyMarkup) + if err != nil { + return v, err + } + + v.Add("reply_markup", string(data)) + } + + return v, nil +} + // VideoConfig contains information about a SendVideo request. type VideoConfig struct { Chattable@@ -121,6 +257,31 @@ File interface{}
FileID string } +func (config *VideoConfig) Values() (url.Values, error) { + v, _ := config.Chattable.Values() + + v.Add("video", config.FileID) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) + } + if config.Duration != 0 { + v.Add("duration", strconv.Itoa(config.Duration)) + } + if config.Caption != "" { + v.Add("caption", config.Caption) + } + if config.ReplyMarkup != nil { + data, err := json.Marshal(config.ReplyMarkup) + if err != nil { + return v, err + } + + v.Add("reply_markup", string(data)) + } + + return v, nil +} + // VoiceConfig contains information about a SendVoice request. type VoiceConfig struct { Chattable@@ -131,6 +292,28 @@ UseExistingVoice bool
FilePath string File interface{} FileID string +} + +func (config *VoiceConfig) Values() (url.Values, error) { + v, _ := config.Chattable.Values() + + v.Add("voice", config.FileID) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) + } + if config.Duration != 0 { + v.Add("duration", strconv.Itoa(config.Duration)) + } + if config.ReplyMarkup != nil { + data, err := json.Marshal(config.ReplyMarkup) + if err != nil { + return v, err + } + + v.Add("reply_markup", string(data)) + } + + return v, nil } // LocationConfig contains information about a SendLocation request.@@ -142,10 +325,36 @@ ReplyToMessageID int
ReplyMarkup interface{} } +func (config *LocationConfig) Values() (url.Values, error) { + v, _ := config.Chattable.Values() + + v.Add("latitude", strconv.FormatFloat(config.Latitude, 'f', 6, 64)) + v.Add("longitude", strconv.FormatFloat(config.Longitude, 'f', 6, 64)) + if config.ReplyToMessageID != 0 { + v.Add("reply_to_message_id", strconv.Itoa(config.ReplyToMessageID)) + } + if config.ReplyMarkup != nil { + data, err := json.Marshal(config.ReplyMarkup) + if err != nil { + return v, err + } + + v.Add("reply_markup", string(data)) + } + + return v, nil +} + // ChatActionConfig contains information about a SendChatAction request. type ChatActionConfig struct { Chattable Action string +} + +func (config *ChatActionConfig) Values() (url.Values, error) { + v, _ := config.Chattable.Values() + v.Add("action", config.Action) + return v, nil } // UserProfilePhotosConfig contains information about a GetUserProfilePhotos request.