diff --git a/api.go b/api.go index c772d4a..b8d37c2 100644 --- a/api.go +++ b/api.go @@ -165,15 +165,34 @@ type APIInlineQuery struct { // APIInlineQueryResultPhoto is an image result for an inline query type APIInlineQueryResultPhoto struct { - Type string `json:"type"` - ResultID string `json:"id"` - PhotoURL string `json:"photo_url"` - ThumbURL string `json:"thumb_url"` - Width int `json:"photo_width,omitempty"` - Height int `json:"photo_height,omitempty"` - Title string `json:"title,omitempty"` - Description string `json:"description,omitempty"` - Caption string `json:"caption,omitempty"` - ParseMode string `json:"parse_mode,omitempty"` - //TODO replyMarkup / inputMessageContent + Type string `json:"type"` + ResultID string `json:"id"` + PhotoURL string `json:"photo_url"` + ThumbURL string `json:"thumb_url"` + Width int `json:"photo_width,omitempty"` + Height int `json:"photo_height,omitempty"` + Title string `json:"title,omitempty"` + Description string `json:"description,omitempty"` + Caption string `json:"caption,omitempty"` + ParseMode string `json:"parse_mode,omitempty"` + ReplyMarkup *APIInlineKeyboardMarkup `json:"reply_markup,omitempty"` + //TODO inputMessageContent +} + +type APIInlineKeyboardMarkup struct { + InlineKeyboard interface{} `json:"inline_keyboard"` +} + +// APIInlineKeyboardButton is an inline message button +type APIInlineKeyboardButton struct { + Text string `json:"text"` + URL string `json:"url,omitempty"` +} + +// APIInputMediaPhoto is a media photo element (already on telegram servers or via HTTP URL) for albums and other cached pictures +type APIInputMediaPhoto struct { + Type string `json:"type"` + Media string `json:"media"` + Caption string `json:"caption,omitempty"` + ParseMode string `json:"parse_mode,omitempty"` } diff --git a/command.go b/command.go index 67809a0..46e7d5a 100644 --- a/command.go +++ b/command.go @@ -44,6 +44,9 @@ const ( // CmdAnswerInlineQuery requests the broker sends results of an inline query CmdAnswerInlineQuery ClientCommandType = "answerInlineQuery" + + // CmdSendAlbum requests the broker sends an album of photos or videos + CmdSendAlbum ClientCommandType = "sendAlbum" ) // ClientTextMessageData is the required data for a CmdSendTextMessage request @@ -75,6 +78,14 @@ type ClientChatActionData struct { Action ChatAction } +// ClientAlbumData is the required data for a CmdSendAlbum request +type ClientAlbumData struct { + ChatID int64 + Media interface{} + Silent bool + ReplyID *int64 `json:",omitempty"` +} + // ChatAction is the action name for CmdSendChatAction requests type ChatAction string diff --git a/telegram.go b/telegram.go index ceaef35..b813866 100644 --- a/telegram.go +++ b/telegram.go @@ -18,6 +18,11 @@ import ( // APIEndpoint is Telegram's current Bot API base url endpoint const APIEndpoint = "https://api.telegram.org/" +var ( + // ErrMalformed represents an error that was encountered while processing the request (json encode/decode error etc) + ErrMalformed = errors.New("Error while handling request") +) + // WebhookHandler is a function that handles updates type WebhookHandler func(APIUpdate) @@ -135,6 +140,27 @@ func (t Telegram) SendPhoto(data ClientPhotoData) { checkerr("SendPhoto/http.Do", err) } +// SendAlbum sends an album of photos or videos +func (t Telegram) SendAlbum(data ClientAlbumData) { + jsonmedia, err := json.Marshal(data.Media) + if err != nil { + checkerr("SendAlbum/json.Marshal", err) + } + postdata := url.Values{ + "chat_id": {strconv.FormatInt(data.ChatID, 10)}, + "media": {string(jsonmedia)}, + } + if data.Silent { + postdata["disable_notification"] = []string{"true"} + } + if data.ReplyID != nil { + postdata["reply_to_message_id"] = []string{strconv.FormatInt(*(data.ReplyID), 10)} + } + + _, err = http.PostForm(t.apiURL("sendMediaGroup"), postdata) + checkerr("SendAlbum/http.PostForm", err) +} + // ForwardMessage forwards an existing message to a chat func (t Telegram) ForwardMessage(data ClientForwardMessageData) { postdata := url.Values{ @@ -159,13 +185,14 @@ func (t Telegram) SendChatAction(data ClientChatActionData) { } // AnswerInlineQuery replies to an inline query -func (t Telegram) AnswerInlineQuery(data InlineQueryResponse) { +func (t Telegram) AnswerInlineQuery(data InlineQueryResponse) error { jsonresults, err := json.Marshal(data.Results) if checkerr("AnswerInlineQuery/json.Marshal", err) { - return + return ErrMalformed } postdata := url.Values{ "inline_query_id": {data.QueryID}, + "parse_mode": {"HTML"}, "results": {string(jsonresults)}, } if data.CacheTime != nil { @@ -184,8 +211,20 @@ func (t Telegram) AnswerInlineQuery(data InlineQueryResponse) { postdata["switch_pm_parameter"] = []string{data.PMParam} } - _, err = http.PostForm(t.apiURL("answerInlineQuery"), postdata) - checkerr("AnswerInlineQuery/http.PostForm", err) + result, err := http.PostForm(t.apiURL("answerInlineQuery"), postdata) + if checkerr("AnswerInlineQuery/http.PostForm", err) { + return ErrMalformed + } + var response APIResponse + err = json.NewDecoder(result.Body).Decode(&response) + result.Body.Close() + if checkerr("AnswerInlineQuery/json.Decode", err) { + return ErrMalformed + } + if !response.Ok && response.Description != nil { + return errors.New(*response.Description) + } + return nil } // GetFile sends a "getFile" API call to Telegram's servers and fetches the file