diff --git a/configs.go b/configs.go index 3989774..98abace 100644 --- a/configs.go +++ b/configs.go @@ -72,6 +72,18 @@ type BaseChat struct { DisableNotification bool } +func (chat *BaseChat) params() (Params, error) { + params := make(Params) + + params.AddFirstValid("chat_id", chat.ChatID, chat.ChannelUsername) + params.AddNonZero("reply_to_message_id", chat.ReplyToMessageID) + params.AddBool("disable_notification", chat.DisableNotification) + + err := params.AddInterface("reply_markup", chat.ReplyMarkup) + + return params, err +} + // values returns url.Values representation of BaseChat func (chat *BaseChat) values() (url.Values, error) { v := url.Values{} @@ -765,6 +777,47 @@ func (config ContactConfig) method() string { return "sendContact" } +// SendPollConfig allows you to send a poll. +type SendPollConfig struct { + BaseChat + Question string + Options []string + IsAnonymous bool + Type string + AllowsMultipleAnswers bool + CorrectOptionID int64 + Explanation string + ExplanationParseMode string + OpenPeriod int + CloseDate int + IsClosed bool +} + +func (config SendPollConfig) values() (url.Values, error) { + params, err := config.BaseChat.params() + if err != nil { + return params.toValues(), err + } + + params["question"] = config.Question + err = params.AddInterface("options", config.Options) + params["is_anonymous"] = strconv.FormatBool(config.IsAnonymous) + params.AddNonEmpty("type", config.Type) + params["allows_multiple_answers"] = strconv.FormatBool(config.AllowsMultipleAnswers) + params["correct_option_id"] = strconv.FormatInt(config.CorrectOptionID, 10) + params.AddBool("is_closed", config.IsClosed) + params.AddNonEmpty("explanation", config.Explanation) + params.AddNonEmpty("explanation_parse_mode", config.ExplanationParseMode) + params.AddNonZero("open_period", config.OpenPeriod) + params.AddNonZero("close_date", config.CloseDate) + + return params.toValues(), err +} + +func (SendPollConfig) method() string { + return "sendPoll" +} + // GameConfig allows you to send a game. type GameConfig struct { BaseChat diff --git a/params.go b/params.go new file mode 100644 index 0000000..6dce6fb --- /dev/null +++ b/params.go @@ -0,0 +1,116 @@ +package tgbotapi + +import ( + "encoding/json" + "net/url" + "reflect" + "strconv" +) + +// Params represents a set of parameters that gets passed to a request. +type Params map[string]string + +func newParams(values url.Values) Params { + params := Params{} + for k, v := range values { + if len(v) > 0 { + params[k] = v[0] + } + } + return params +} + +func (p Params) toValues() url.Values { + values := url.Values{} + for k, v := range p { + values[k] = []string{v} + } + return values +} + +// AddNonEmpty adds a value if it not an empty string. +func (p Params) AddNonEmpty(key, value string) { + if value != "" { + p[key] = value + } +} + +// AddNonZero adds a value if it is not zero. +func (p Params) AddNonZero(key string, value int) { + if value != 0 { + p[key] = strconv.Itoa(value) + } +} + +// AddNonZero64 is the same as AddNonZero except uses an int64. +func (p Params) AddNonZero64(key string, value int64) { + if value != 0 { + p[key] = strconv.FormatInt(value, 10) + } +} + +// AddBool adds a value of a bool if it is true. +func (p Params) AddBool(key string, value bool) { + if value { + p[key] = strconv.FormatBool(value) + } +} + +// AddNonZeroFloat adds a floating point value that is not zero. +func (p Params) AddNonZeroFloat(key string, value float64) { + if value != 0 { + p[key] = strconv.FormatFloat(value, 'f', 6, 64) + } +} + +// AddInterface adds an interface if it is not nill and can be JSON marshalled. +func (p Params) AddInterface(key string, value interface{}) error { + if value == nil || (reflect.ValueOf(value).Kind() == reflect.Ptr && reflect.ValueOf(value).IsNil()) { + return nil + } + + b, err := json.Marshal(value) + if err != nil { + return err + } + + p[key] = string(b) + + return nil +} + +// AddFirstValid attempts to add the first item that is not a default value. +// +// For example, AddFirstValid(0, "", "test") would add "test". +func (p Params) AddFirstValid(key string, args ...interface{}) error { + for _, arg := range args { + switch v := arg.(type) { + case int: + if v != 0 { + p[key] = strconv.Itoa(v) + return nil + } + case int64: + if v != 0 { + p[key] = strconv.FormatInt(v, 10) + return nil + } + case string: + if v != "" { + p[key] = v + return nil + } + case nil: + default: + b, err := json.Marshal(arg) + if err != nil { + return err + } + + p[key] = string(b) + return nil + } + } + + return nil +}