Unify params and values, introduce helpers to deal with fields.

This commit is contained in:
Syfaro 2018-10-08 18:21:29 -05:00
parent 9d2d117c0e
commit 03815bf5bd
5 changed files with 547 additions and 904 deletions

219
bot.go
View file

@ -12,7 +12,6 @@ import (
"net/http"
"net/url"
"os"
"strconv"
"strings"
"time"
@ -59,15 +58,31 @@ func NewBotAPIWithClient(token string, client *http.Client) (*BotAPI, error) {
return bot, nil
}
func buildParams(in Params) (out url.Values) {
if in == nil {
return url.Values{}
}
out = url.Values{}
for key, value := range in {
out.Set(key, value)
}
return
}
// MakeRequest makes a request to a specific endpoint with our token.
func (bot *BotAPI) MakeRequest(endpoint string, params url.Values) (APIResponse, error) {
func (bot *BotAPI) MakeRequest(endpoint string, params Params) (APIResponse, error) {
if bot.Debug {
log.Printf("Endpoint: %s, values: %v\n", endpoint, params)
log.Printf("Endpoint: %s, params: %v\n", endpoint, params)
}
method := fmt.Sprintf(APIEndpoint, bot.Token, endpoint)
resp, err := bot.Client.PostForm(method, params)
values := buildParams(params)
resp, err := bot.Client.PostForm(method, values)
if err != nil {
return APIResponse{}, err
}
@ -131,7 +146,7 @@ func (bot *BotAPI) decodeAPIResponse(responseBody io.Reader, resp *APIResponse)
//
// Note that if your FileReader has a size set to -1, it will read
// the file into memory to calculate a size.
func (bot *BotAPI) UploadFile(endpoint string, params map[string]string, fieldname string, file interface{}) (APIResponse, error) {
func (bot *BotAPI) UploadFile(endpoint string, params Params, fieldname string, file interface{}) (APIResponse, error) {
ms := multipartstreamer.New()
switch f := file.(type) {
@ -261,30 +276,20 @@ func (bot *BotAPI) IsMessageToMe(message Message) bool {
// Request sends a Chattable to Telegram, and returns the APIResponse.
func (bot *BotAPI) Request(c Chattable) (APIResponse, error) {
params, err := c.params()
if err != nil {
return APIResponse{}, err
}
switch t := c.(type) {
case Fileable:
if t.useExistingFile() {
v, err := t.values()
if err != nil {
return APIResponse{}, err
}
return bot.MakeRequest(t.method(), v)
return bot.MakeRequest(t.method(), params)
}
p, err := t.params()
if err != nil {
return APIResponse{}, err
}
return bot.UploadFile(t.method(), p, t.name(), t.getFile())
return bot.UploadFile(t.method(), params, t.name(), t.getFile())
default:
v, err := c.values()
if err != nil {
return APIResponse{}, err
}
return bot.MakeRequest(c.method(), v)
return bot.MakeRequest(c.method(), params)
}
}
@ -307,16 +312,9 @@ func (bot *BotAPI) Send(c Chattable) (Message, error) {
// It requires UserID.
// Offset and Limit are optional.
func (bot *BotAPI) GetUserProfilePhotos(config UserProfilePhotosConfig) (UserProfilePhotos, error) {
v := url.Values{}
v.Add("user_id", strconv.Itoa(config.UserID))
if config.Offset != 0 {
v.Add("offset", strconv.Itoa(config.Offset))
}
if config.Limit != 0 {
v.Add("limit", strconv.Itoa(config.Limit))
}
params, _ := config.params()
resp, err := bot.MakeRequest("getUserProfilePhotos", v)
resp, err := bot.MakeRequest(config.method(), params)
if err != nil {
return UserProfilePhotos{}, err
}
@ -331,8 +329,9 @@ func (bot *BotAPI) GetUserProfilePhotos(config UserProfilePhotosConfig) (UserPro
//
// Requires FileID.
func (bot *BotAPI) GetFile(config FileConfig) (File, error) {
v := url.Values{}
v.Add("file_id", config.FileID)
v := make(Params)
v["file_id"] = config.FileID
resp, err := bot.MakeRequest("getFile", v)
if err != nil {
@ -353,18 +352,9 @@ func (bot *BotAPI) GetFile(config FileConfig) (File, error) {
// Set Timeout to a large number to reduce requests so you can get updates
// instantly instead of having to wait between requests.
func (bot *BotAPI) GetUpdates(config UpdateConfig) ([]Update, error) {
v := url.Values{}
if config.Offset != 0 {
v.Add("offset", strconv.Itoa(config.Offset))
}
if config.Limit > 0 {
v.Add("limit", strconv.Itoa(config.Limit))
}
if config.Timeout > 0 {
v.Add("timeout", strconv.Itoa(config.Timeout))
}
params, _ := config.params()
resp, err := bot.MakeRequest("getUpdates", v)
resp, err := bot.MakeRequest(config.method(), params)
if err != nil {
return []Update{}, err
}
@ -378,7 +368,7 @@ func (bot *BotAPI) GetUpdates(config UpdateConfig) ([]Update, error) {
// GetWebhookInfo allows you to fetch information about a webhook and if
// one currently is set, along with pending update count and error messages.
func (bot *BotAPI) GetWebhookInfo() (WebhookInfo, error) {
resp, err := bot.MakeRequest("getWebhookInfo", url.Values{})
resp, err := bot.MakeRequest("getWebhookInfo", nil)
if err != nil {
return WebhookInfo{}, err
}
@ -448,13 +438,9 @@ func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
// GetChat gets information about a chat.
func (bot *BotAPI) GetChat(config ChatConfig) (Chat, error) {
v := url.Values{}
v := make(Params)
if config.SuperGroupUsername == "" {
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
} else {
v.Add("chat_id", config.SuperGroupUsername)
}
v.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
resp, err := bot.MakeRequest("getChat", v)
if err != nil {
@ -472,13 +458,9 @@ func (bot *BotAPI) GetChat(config ChatConfig) (Chat, error) {
// If none have been appointed, only the creator will be returned.
// Bots are not shown, even if they are an administrator.
func (bot *BotAPI) GetChatAdministrators(config ChatConfig) ([]ChatMember, error) {
v := url.Values{}
v := make(Params)
if config.SuperGroupUsername == "" {
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
} else {
v.Add("chat_id", config.SuperGroupUsername)
}
v.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
resp, err := bot.MakeRequest("getChatAdministrators", v)
if err != nil {
@ -493,13 +475,9 @@ func (bot *BotAPI) GetChatAdministrators(config ChatConfig) ([]ChatMember, error
// GetChatMembersCount gets the number of users in a chat.
func (bot *BotAPI) GetChatMembersCount(config ChatConfig) (int, error) {
v := url.Values{}
v := make(Params)
if config.SuperGroupUsername == "" {
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
} else {
v.Add("chat_id", config.SuperGroupUsername)
}
v.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
resp, err := bot.MakeRequest("getChatMembersCount", v)
if err != nil {
@ -514,14 +492,10 @@ func (bot *BotAPI) GetChatMembersCount(config ChatConfig) (int, error) {
// GetChatMember gets a specific chat member.
func (bot *BotAPI) GetChatMember(config ChatConfigWithUser) (ChatMember, error) {
v := url.Values{}
v := make(Params)
if config.SuperGroupUsername == "" {
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
} else {
v.Add("chat_id", config.SuperGroupUsername)
}
v.Add("user_id", strconv.Itoa(config.UserID))
v.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
v.AddNonZero("user_id", config.UserID)
resp, err := bot.MakeRequest("getChatMember", v)
if err != nil {
@ -537,16 +511,10 @@ func (bot *BotAPI) GetChatMember(config ChatConfigWithUser) (ChatMember, error)
// UnbanChatMember unbans a user from a chat. Note that this only will work
// in supergroups and channels, and requires the bot to be an admin.
func (bot *BotAPI) UnbanChatMember(config ChatMemberConfig) (APIResponse, error) {
v := url.Values{}
v := make(Params)
if config.SuperGroupUsername != "" {
v.Add("chat_id", config.SuperGroupUsername)
} else if config.ChannelUsername != "" {
v.Add("chat_id", config.ChannelUsername)
} else {
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
}
v.Add("user_id", strconv.Itoa(config.UserID))
v.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
v.AddNonZero("user_id", config.UserID)
return bot.MakeRequest("unbanChatMember", v)
}
@ -556,80 +524,45 @@ func (bot *BotAPI) UnbanChatMember(config ChatMemberConfig) (APIResponse, error)
//appropriate admin rights. Pass True for all boolean parameters to lift
//restrictions from a user. Returns True on success.
func (bot *BotAPI) RestrictChatMember(config RestrictChatMemberConfig) (APIResponse, error) {
v := url.Values{}
v := make(Params)
if config.SuperGroupUsername != "" {
v.Add("chat_id", config.SuperGroupUsername)
} else if config.ChannelUsername != "" {
v.Add("chat_id", config.ChannelUsername)
} else {
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
}
v.Add("user_id", strconv.Itoa(config.UserID))
v.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
v.AddNonZero("user_id", config.UserID)
if config.CanSendMessages != nil {
v.Add("can_send_messages", strconv.FormatBool(*config.CanSendMessages))
}
if config.CanSendMediaMessages != nil {
v.Add("can_send_media_messages", strconv.FormatBool(*config.CanSendMediaMessages))
}
if config.CanSendOtherMessages != nil {
v.Add("can_send_other_messages", strconv.FormatBool(*config.CanSendOtherMessages))
}
if config.CanAddWebPagePreviews != nil {
v.Add("can_add_web_page_previews", strconv.FormatBool(*config.CanAddWebPagePreviews))
}
if config.UntilDate != 0 {
v.Add("until_date", strconv.FormatInt(config.UntilDate, 10))
}
v.AddNonNilBool("can_send_messages", config.CanSendMessages)
v.AddNonNilBool("can_send_media_messages", config.CanSendMediaMessages)
v.AddNonNilBool("can_send_other_messages", config.CanSendOtherMessages)
v.AddNonNilBool("can_add_web_page_previews", config.CanAddWebPagePreviews)
v.AddNonZero64("until_date", config.UntilDate)
return bot.MakeRequest("restrictChatMember", v)
}
// PromoteChatMember add admin rights to user
func (bot *BotAPI) PromoteChatMember(config PromoteChatMemberConfig) (APIResponse, error) {
v := url.Values{}
v := make(Params)
if config.SuperGroupUsername != "" {
v.Add("chat_id", config.SuperGroupUsername)
} else if config.ChannelUsername != "" {
v.Add("chat_id", config.ChannelUsername)
} else {
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
}
v.Add("user_id", strconv.Itoa(config.UserID))
v.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
v.AddNonZero("user_id", config.UserID)
if config.CanChangeInfo != nil {
v.Add("can_change_info", strconv.FormatBool(*config.CanChangeInfo))
}
if config.CanPostMessages != nil {
v.Add("can_post_messages", strconv.FormatBool(*config.CanPostMessages))
}
if config.CanEditMessages != nil {
v.Add("can_edit_messages", strconv.FormatBool(*config.CanEditMessages))
}
if config.CanDeleteMessages != nil {
v.Add("can_delete_messages", strconv.FormatBool(*config.CanDeleteMessages))
}
if config.CanInviteUsers != nil {
v.Add("can_invite_users", strconv.FormatBool(*config.CanInviteUsers))
}
if config.CanRestrictMembers != nil {
v.Add("can_restrict_members", strconv.FormatBool(*config.CanRestrictMembers))
}
if config.CanPinMessages != nil {
v.Add("can_pin_messages", strconv.FormatBool(*config.CanPinMessages))
}
if config.CanPromoteMembers != nil {
v.Add("can_promote_members", strconv.FormatBool(*config.CanPromoteMembers))
}
v.AddNonNilBool("can_change_info", config.CanChangeInfo)
v.AddNonNilBool("can_post_messages", config.CanPostMessages)
v.AddNonNilBool("can_edit_messages", config.CanEditMessages)
v.AddNonNilBool("can_delete_messages", config.CanDeleteMessages)
v.AddNonNilBool("can_invite_members", config.CanInviteUsers)
v.AddNonNilBool("can_restrict_members", config.CanRestrictMembers)
v.AddNonNilBool("can_pin_messages", config.CanPinMessages)
v.AddNonNilBool("can_promote_members", config.CanPromoteMembers)
return bot.MakeRequest("promoteChatMember", v)
}
// GetGameHighScores allows you to get the high scores for a game.
func (bot *BotAPI) GetGameHighScores(config GetGameHighScoresConfig) ([]GameHighScore, error) {
v, _ := config.values()
v, err := config.params()
if err != nil {
return nil, err
}
resp, err := bot.MakeRequest(config.method(), v)
if err != nil {
@ -644,13 +577,9 @@ func (bot *BotAPI) GetGameHighScores(config GetGameHighScoresConfig) ([]GameHigh
// GetInviteLink get InviteLink for a chat
func (bot *BotAPI) GetInviteLink(config ChatConfig) (string, error) {
v := url.Values{}
v := make(Params)
if config.SuperGroupUsername == "" {
v.Add("chat_id", strconv.FormatInt(config.ChatID, 10))
} else {
v.Add("chat_id", config.SuperGroupUsername)
}
v.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
resp, err := bot.MakeRequest("exportChatInviteLink", v)
if err != nil {
@ -665,7 +594,7 @@ func (bot *BotAPI) GetInviteLink(config ChatConfig) (string, error) {
// GetStickerSet returns a StickerSet.
func (bot *BotAPI) GetStickerSet(config GetStickerSetConfig) (StickerSet, error) {
v, err := config.values()
v, err := config.params()
if err != nil {
return StickerSet{}, nil
}