diff --git a/command.go b/command.go index 1388fa1..c12a3d0 100644 --- a/command.go +++ b/command.go @@ -105,6 +105,15 @@ type ClientAlbumData struct { ReplyID *int64 `json:",omitempty"` } +// ClientEditTextData is the required data for a CmdEditText request +type ClientEditTextData struct { + ChatID int64 + MessageID int64 + InlineID string + Text string + ReplyMarkup interface{} `json:",omitempty"` +} + // ClientEditCaptionData is the required data for a CmdEditCaption request type ClientEditCaptionData struct { ChatID int64 @@ -126,6 +135,7 @@ type ClientEditMediaData struct { // ChatAction is the action name for CmdSendChatAction requests type ChatAction string +// Telegram chat actions const ( ActionTyping ChatAction = "typing" ActionUploadingPhoto ChatAction = "upload_photo" diff --git a/telegram.go b/telegram.go index e538cc4..6eeb36c 100644 --- a/telegram.go +++ b/telegram.go @@ -78,7 +78,7 @@ func (t Telegram) HandleWebhook(bind string, webhook string, handler WebhookHand } // SendTextMessage sends an HTML-styled text message to a specified chat -func (t Telegram) SendTextMessage(data ClientTextMessageData) { +func (t Telegram) SendTextMessage(data ClientTextMessageData) (APIMessage, error) { postdata := url.Values{ "chat_id": {strconv.FormatInt(data.ChatID, 10)}, "text": {data.Text}, @@ -90,23 +90,31 @@ func (t Telegram) SendTextMessage(data ClientTextMessageData) { if data.ReplyMarkup != nil { replyjson, err := json.Marshal(data.ReplyMarkup) if checkerr("SendTextMessage/json.Marshal", err) { - return + return APIMessage{}, err } postdata["reply_markup"] = []string{string(replyjson)} } - _, err := http.PostForm(t.apiURL("sendMessage"), postdata) - checkerr("SendTextMessage/http.PostForm", err) + resp, err := http.PostForm(t.apiURL("sendMessage"), postdata) + if checkerr("SendTextMessage/http.PostForm", err) { + return APIMessage{}, err + } + defer resp.Body.Close() + + var out APIMessage + err = json.NewDecoder(resp.Body).Decode(&out) + checkerr("SendTextMessage/json.Decode", err) + return out, err } // SendPhoto sends a picture to a chat as a photo -func (t Telegram) SendPhoto(data ClientPhotoData) { +func (t Telegram) SendPhoto(data ClientPhotoData) (APIMessage, error) { // Decode photo from b64 photolen := base64.StdEncoding.DecodedLen(len(data.Bytes)) photobytes := make([]byte, photolen) decoded, err := base64.StdEncoding.Decode(photobytes, []byte(data.Bytes)) if checkerr("SendPhoto/base64.Decode", err) { - return + return APIMessage{}, err } // Write file into multipart buffer @@ -114,7 +122,7 @@ func (t Telegram) SendPhoto(data ClientPhotoData) { writer := multipart.NewWriter(body) part, err := writer.CreateFormFile("photo", data.Filename) if checkerr("SendPhoto/multipart.CreateFormFile", err) { - return + return APIMessage{}, err } part.Write(photobytes[0:decoded]) @@ -131,27 +139,36 @@ func (t Telegram) SendPhoto(data ClientPhotoData) { err = writer.Close() if checkerr("SendPhoto/writer.Close", err) { - return + return APIMessage{}, err } // Create HTTP client and execute request client := &http.Client{} req, err := http.NewRequest("POST", t.apiURL("sendPhoto"), body) if checkerr("SendPhoto/http.NewRequest", err) { - return + return APIMessage{}, err } req.Header.Add("Content-Type", writer.FormDataContentType()) - _, err = client.Do(req) - checkerr("SendPhoto/http.Do", err) + resp, err := client.Do(req) + if checkerr("SendPhoto/http.Do", err) { + return APIMessage{}, err + } + defer resp.Body.Close() + + var out APIMessage + err = json.NewDecoder(resp.Body).Decode(&out) + checkerr("SendPhoto/json.Decode", err) + return out, err } // SendAlbum sends an album of photos or videos -func (t Telegram) SendAlbum(data ClientAlbumData) { +func (t Telegram) SendAlbum(data ClientAlbumData) ([]APIMessage, error) { jsonmedia, err := json.Marshal(data.Media) if err != nil { checkerr("SendAlbum/json.Marshal", err) + return nil, err } postdata := url.Values{ "chat_id": {strconv.FormatInt(data.ChatID, 10)}, @@ -164,20 +181,36 @@ func (t Telegram) SendAlbum(data ClientAlbumData) { postdata.Set("reply_to_message_id", strconv.FormatInt(*(data.ReplyID), 10)) } - _, err = http.PostForm(t.apiURL("sendMediaGroup"), postdata) - checkerr("SendAlbum/http.PostForm", err) + resp, err := http.PostForm(t.apiURL("sendMediaGroup"), postdata) + if checkerr("SendAlbum/http.PostForm", err) { + return nil, err + } + defer resp.Body.Close() + + var out []APIMessage + err = json.NewDecoder(resp.Body).Decode(&out) + checkerr("SendAlbum/json.Decode", err) + return out, err } // ForwardMessage forwards an existing message to a chat -func (t Telegram) ForwardMessage(data ClientForwardMessageData) { +func (t Telegram) ForwardMessage(data ClientForwardMessageData) (APIMessage, error) { postdata := url.Values{ "chat_id": {strconv.FormatInt(data.ChatID, 10)}, "from_chat_id": {strconv.FormatInt(data.FromChatID, 10)}, "message_id": {strconv.FormatInt(data.MessageID, 10)}, } - _, err := http.PostForm(t.apiURL("forwardMessage"), postdata) - checkerr("ForwardMessage/http.PostForm", err) + resp, err := http.PostForm(t.apiURL("forwardMessage"), postdata) + if checkerr("ForwardMessage/http.PostForm", err) { + return APIMessage{}, err + } + defer resp.Body.Close() + + var out APIMessage + err = json.NewDecoder(resp.Body).Decode(&out) + checkerr("ForwardMessage/json.Decode", err) + return out, err } // SendChatAction sends a 5 second long action (X is writing, sending a photo ecc.) @@ -213,6 +246,32 @@ func (t Telegram) AnswerCallback(data ClientCallbackQueryData) { checkerr("AnswerCallback/http.PostForm", err) } +// EditText modifies a text message +func (t Telegram) EditText(data ClientEditTextData) error { + postdata := url.Values{ + "text": {data.Text}, + "parse_mode": {"HTML"}, + } + if data.InlineID != "" { + postdata.Set("inline_message_id", data.InlineID) + } else { + postdata.Set("chat_id", strconv.FormatInt(data.ChatID, 10)) + postdata.Set("message_id", strconv.FormatInt(data.MessageID, 10)) + } + if data.ReplyMarkup != nil { + replyjson, err := json.Marshal(data.ReplyMarkup) + if checkerr("EditText/json.Marshal", err) { + return ErrMalformed + } + postdata["reply_markup"] = []string{string(replyjson)} + } + + _, err := http.PostForm(t.apiURL("editMessageText"), postdata) + checkerr("EditText/http.PostForm", err) + + return nil +} + // EditCaption modifies the caption of a photo/document/etc message func (t Telegram) EditCaption(data ClientEditCaptionData) error { postdata := url.Values{