diff --git a/bot.go b/bot.go index f0b35a4..e8e1a7c 100644 --- a/bot.go +++ b/bot.go @@ -557,21 +557,35 @@ func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel { ch := make(chan Update, bot.Buffer) http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { - ch <- bot.HandleUpdate(w, r) + update, err := bot.HandleUpdate(r) + if err != nil { + errMsg, _ := json.Marshal(map[string]string{"error": err.Error()}) + w.WriteHeader(http.StatusBadRequest) + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write(errMsg) + return + } + + ch <- *update }) return ch } // HandleUpdate parses and returns update received via webhook -func (bot *BotAPI) HandleUpdate(res http.ResponseWriter, req *http.Request) Update { - bytes, _ := ioutil.ReadAll(req.Body) - req.Body.Close() +func (bot *BotAPI) HandleUpdate(r *http.Request) (*Update, error) { + if r.Method != http.MethodPost { + err := errors.New("wrong HTTP method required POST") + return nil, err + } - var update Update - json.Unmarshal(bytes, &update) + var update Update + err := json.NewDecoder(r.Body).Decode(&update) + if err != nil { + return nil, err + } - return update + return &update, nil } // AnswerInlineQuery sends a response to an inline query. diff --git a/bot_test.go b/bot_test.go index 4ef8303..1118a08 100644 --- a/bot_test.go +++ b/bot_test.go @@ -644,8 +644,13 @@ func ExampleWebhookHandler() { log.Printf("[Telegram callback failed]%s", info.LastErrorMessage) } - http.HandleFunc("/" + bot.Token, func(w http.ResponseWriter, r *http.Request) { - log.Printf("%+v\n", bot.HandleUpdate(w, r)) + http.HandleFunc("/"+bot.Token, func(w http.ResponseWriter, r *http.Request) { + update, err := bot.HandleUpdate(r) + if err != nil { + log.Printf("%+v\n", err.Error()) + } else { + log.Printf("%+v\n", *update) + } }) go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil) diff --git a/helpers.go b/helpers.go index 1ec3ba7..e116224 100644 --- a/helpers.go +++ b/helpers.go @@ -778,9 +778,9 @@ func NewReplyKeyboard(rows ...[]KeyboardButton) ReplyKeyboardMarkup { // NewOneTimeReplyKeyboard creates a new one time keyboard. func NewOneTimeReplyKeyboard(rows ...[]KeyboardButton) ReplyKeyboardMarkup { - markup := NewReplyKeyboard(rows...) - markup.OneTimeKeyboard = true - return markup + markup := NewReplyKeyboard(rows...) + markup.OneTimeKeyboard = true + return markup } // NewInlineKeyboardButtonData creates an inline keyboard button with text