Refactor unexported code

pull/269/head
unknown 4 years ago
parent 4cab32f46e
commit e5789a08bb

@ -62,12 +62,12 @@ func (b *Bot) Ban(chat *Chat, member *ChatMember) error {
"until_date": strconv.FormatInt(member.RestrictedUntil, 10),
}
respJSON, err := b.Raw("kickChatMember", params)
data, err := b.Raw("kickChatMember", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// Unban will unban user from chat, who would have thought eh?
@ -77,12 +77,12 @@ func (b *Bot) Unban(chat *Chat, user *User) error {
"user_id": user.Recipient(),
}
respJSON, err := b.Raw("unbanChatMember", params)
data, err := b.Raw("unbanChatMember", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// Restrict let's you restrict a subset of member's rights until
@ -104,12 +104,12 @@ func (b *Bot) Restrict(chat *Chat, member *ChatMember) error {
embedRights(params, prv)
respJSON, err := b.Raw("restrictChatMember", params)
data, err := b.Raw("restrictChatMember", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// Promote lets you update member's admin rights, such as:
@ -133,12 +133,12 @@ func (b *Bot) Promote(chat *Chat, member *ChatMember) error {
embedRights(params, prv)
respJSON, err := b.Raw("promoteChatMember", params)
data, err := b.Raw("promoteChatMember", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// AdminsOf return a member list of chat admins.
@ -152,7 +152,7 @@ func (b *Bot) AdminsOf(chat *Chat) ([]ChatMember, error) {
"chat_id": chat.Recipient(),
}
respJSON, err := b.Raw("getChatAdministrators", params)
data, err := b.Raw("getChatAdministrators", params)
if err != nil {
return nil, err
}
@ -163,7 +163,7 @@ func (b *Bot) AdminsOf(chat *Chat) ([]ChatMember, error) {
Description string `json:"description"`
}
err = json.Unmarshal(respJSON, &resp)
err = json.Unmarshal(data, &resp)
if err != nil {
return nil, errors.Wrap(err, "bad response json")
}
@ -181,7 +181,7 @@ func (b *Bot) Len(chat *Chat) (int, error) {
"chat_id": chat.Recipient(),
}
respJSON, err := b.Raw("getChatMembersCount", params)
data, err := b.Raw("getChatMembersCount", params)
if err != nil {
return 0, err
}
@ -192,7 +192,7 @@ func (b *Bot) Len(chat *Chat) (int, error) {
Description string `json:"description"`
}
err = json.Unmarshal(respJSON, &resp)
err = json.Unmarshal(data, &resp)
if err != nil {
return 0, errors.Wrap(err, "bad response json")
}

156
api.go

@ -3,7 +3,6 @@ package telebot
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
@ -17,71 +16,34 @@ import (
)
// Raw lets you call any method of Bot API manually.
// It also handles API errors, so you only need to unwrap
// result field from json data.
func (b *Bot) Raw(method string, payload interface{}) ([]byte, error) {
url := b.URL + "/bot" + b.Token + "/" + method
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(payload); err != nil {
return []byte{}, err
return nil, err
}
resp, err := b.client.Post(url, "application/json", &buf)
if err != nil {
return []byte{}, errors.Wrap(err, "http.Post failed")
return nil, errors.Wrap(err, "http.Post failed")
}
resp.Close = true
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return []byte{}, wrapError(err)
}
match := errorRx.FindStringSubmatch(string(data))
if match == nil || len(match) < 3 {
return data, nil
}
desc := match[2]
if err = ErrByDescription(desc); err == nil {
code, _ := strconv.Atoi(match[1])
err = fmt.Errorf("telegram: %s (%d)", desc, code)
}
return data, err
}
func addFileToWriter(writer *multipart.Writer,
filename, field string, file interface{}) error {
var reader io.Reader
if r, ok := file.(io.Reader); ok {
reader = r
} else if path, ok := file.(string); ok {
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
reader = f
} else {
return errors.Errorf("File for field `%v` should be an io.ReadCloser or string", field)
}
part, err := writer.CreateFormFile(field, filename)
if err != nil {
return err
return nil, wrapError(err)
}
_, err = io.Copy(part, reader)
return err
// returning data as well
return data, extractOk(data)
}
func (b *Bot) sendFiles(method string, files map[string]File,
params map[string]string) ([]byte, error) {
body := &bytes.Buffer{}
func (b *Bot) sendFiles(method string, files map[string]File, params map[string]string) ([]byte, error) {
rawFiles := map[string]interface{}{}
for name, f := range files {
switch {
case f.InCloud():
@ -93,7 +55,7 @@ func (b *Bot) sendFiles(method string, files map[string]File,
case f.FileReader != nil:
rawFiles[name] = f.FileReader
default:
return nil, errors.Errorf("sendFiles: File for field %s doesn't exist", name)
return nil, errors.Errorf("telebot: File for field %s doesn't exist", name)
}
}
@ -101,40 +63,34 @@ func (b *Bot) sendFiles(method string, files map[string]File,
return b.Raw(method, params)
}
writer := multipart.NewWriter(body)
var buf bytes.Buffer
writer := multipart.NewWriter(&buf)
for field, file := range rawFiles {
if err := addFileToWriter(writer, params["file_name"], field, file); err != nil {
return nil, wrapError(err)
}
}
for field, value := range params {
if err := writer.WriteField(field, value); err != nil {
return nil, wrapError(err)
}
}
if err := writer.Close(); err != nil {
return nil, wrapError(err)
}
url := b.URL + "/bot" + b.Token + "/" + method
req, err := http.NewRequest("POST", url, body)
if err != nil {
return nil, wrapError(err)
}
req.Header.Add("Content-Type", writer.FormDataContentType())
resp, err := b.client.Do(req)
resp, err := b.client.Post(url, writer.FormDataContentType(), &buf)
if err != nil {
return nil, errors.Wrap(err, "http.Post failed")
}
resp.Close = true
defer resp.Body.Close()
if resp.StatusCode == http.StatusInternalServerError {
return nil, errors.New("api error: internal server error")
return nil, ErrInternal
}
data, err := ioutil.ReadAll(resp.Body)
@ -142,7 +98,46 @@ func (b *Bot) sendFiles(method string, files map[string]File,
return nil, wrapError(err)
}
return data, nil
return data, extractOk(data)
}
func addFileToWriter(writer *multipart.Writer, filename, field string, file interface{}) error {
var reader io.Reader
if r, ok := file.(io.Reader); ok {
reader = r
} else if path, ok := file.(string); ok {
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
reader = f
} else {
return errors.Errorf("telebot: File for field %v should be an io.ReadCloser or string", field)
}
part, err := writer.CreateFormFile(field, filename)
if err != nil {
return err
}
_, err = io.Copy(part, reader)
return err
}
func (b *Bot) sendText(to Recipient, text string, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
"text": text,
}
embedSendOptions(params, opt)
data, err := b.Raw("sendMessage", params)
if err != nil {
return nil, err
}
return extractMessage(data)
}
func (b *Bot) sendObject(f *File, what string, params map[string]string, files map[string]File) (*Message, error) {
@ -157,60 +152,45 @@ func (b *Bot) sendObject(f *File, what string, params map[string]string, files m
sendFiles[k] = v
}
respJSON, err := b.sendFiles(sendWhat, sendFiles, params)
data, err := b.sendFiles(sendWhat, sendFiles, params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
return extractMessage(data)
}
func (b *Bot) getMe() (*User, error) {
me, err := b.Raw("getMe", nil)
data, err := b.Raw("getMe", nil)
if err != nil {
return nil, err
}
var resp struct {
// Raw already handles error.
// So we need only single result field.
Result *User `json:"result"`
Result *User
}
if err := json.Unmarshal(me, &resp); err != nil {
if err := json.Unmarshal(data, &resp); err != nil {
return nil, wrapError(err)
}
return resp.Result, nil
}
func (b *Bot) getUpdates(offset int, timeout time.Duration) (upd []Update, err error) {
func (b *Bot) getUpdates(offset int, timeout time.Duration) ([]Update, error) {
params := map[string]string{
"offset": strconv.Itoa(offset),
"timeout": strconv.Itoa(int(timeout / time.Second)),
}
updatesJSON, errCommand := b.Raw("getUpdates", params)
if errCommand != nil {
err = errCommand
return
}
var updatesReceived struct {
Ok bool
Result []Update
Description string
}
err = json.Unmarshal(updatesJSON, &updatesReceived)
data, err := b.Raw("getUpdates", params)
if err != nil {
err = errors.Wrap(err, "bad response json")
return
return nil, err
}
if !updatesReceived.Ok {
err = errors.Errorf("api error: %s", updatesReceived.Description)
return
var resp struct {
Result []Update
}
return updatesReceived.Result, nil
if err := json.Unmarshal(data, &resp); err != nil {
return nil, wrapError(err)
}
return resp.Result, nil
}

@ -60,5 +60,5 @@ func TestRaw(t *testing.T) {
assert.EqualError(t, err, "telebot: "+io.ErrUnexpectedEOF.Error())
_, err = b.Raw("testUnknownError", nil)
assert.EqualError(t, err, "telegram: unknown error (400)")
assert.EqualError(t, err, "telegram unknown: unknown error (400)")
}

139
bot.go

@ -106,12 +106,11 @@ type Update struct {
// ChosenInlineResult represents a result of an inline query that was chosen
// by the user and sent to their chat partner.
type ChosenInlineResult struct {
From User `json:"from"`
Location *Location `json:"location,omitempty"`
ResultID string `json:"result_id"`
Query string `json:"query"`
// Inline messages only!
MessageID string `json:"inline_message_id"`
From User `json:"from"`
Location *Location `json:"location,omitempty"`
ResultID string `json:"result_id"`
Query string `json:"query"`
MessageID string `json:"inline_message_id"` // inline messages only!
}
type PreCheckoutQuery struct {
@ -646,7 +645,7 @@ func (b *Bot) SendAlbum(to Recipient, a Album, options ...interface{}) ([]Messag
sendOpts := extractOptions(options)
embedSendOptions(params, sendOpts)
respJSON, err := b.sendFiles("sendMediaGroup", files, params)
data, err := b.sendFiles("sendMediaGroup", files, params)
if err != nil {
return nil, err
}
@ -657,7 +656,7 @@ func (b *Bot) SendAlbum(to Recipient, a Album, options ...interface{}) ([]Messag
Description string
}
err = json.Unmarshal(respJSON, &resp)
err = json.Unmarshal(data, &resp)
if err != nil {
return nil, errors.Wrap(err, "bad response json")
}
@ -709,12 +708,12 @@ func (b *Bot) Forward(to Recipient, what *Message, options ...interface{}) (*Mes
sendOpts := extractOptions(options)
embedSendOptions(params, sendOpts)
respJSON, err := b.Raw("forwardMessage", params)
data, err := b.Raw("forwardMessage", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
return extractMessage(data)
}
// Edit is magic, it lets you change already sent message.
@ -753,12 +752,12 @@ func (b *Bot) Edit(message Editable, what interface{}, options ...interface{}) (
sendOpts := extractOptions(options)
embedSendOptions(params, sendOpts)
respJSON, err := b.Raw("editMessageText", params)
data, err := b.Raw("editMessageText", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
return extractMessage(data)
}
// EditReplyMarkup used to edit reply markup of already sent message.
@ -781,12 +780,12 @@ func (b *Bot) EditReplyMarkup(message Editable, markup *ReplyMarkup) (*Message,
jsonMarkup, _ := json.Marshal(markup)
params["reply_markup"] = string(jsonMarkup)
respJSON, err := b.Raw("editMessageReplyMarkup", params)
data, err := b.Raw("editMessageReplyMarkup", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
return extractMessage(data)
}
// EditCaption used to edit already sent photo caption with known recipient and message id.
@ -808,12 +807,12 @@ func (b *Bot) EditCaption(message Editable, caption string, options ...interface
sendOpts := extractOptions(options)
embedSendOptions(params, sendOpts)
respJSON, err := b.Raw("editMessageCaption", params)
data, err := b.Raw("editMessageCaption", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
return extractMessage(data)
}
// EditMedia used to edit already sent media with known recipient and message id.
@ -947,12 +946,12 @@ func (b *Bot) EditMedia(message Editable, inputMedia InputMedia, options ...inte
embedSendOptions(params, sendOpts)
respJSON, err := b.sendFiles("editMessageMedia", file, params)
data, err := b.sendFiles("editMessageMedia", file, params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
return extractMessage(data)
}
// Delete removes the message, including service messages,
@ -974,12 +973,12 @@ func (b *Bot) Delete(message Editable) error {
"message_id": messageID,
}
respJSON, err := b.Raw("deleteMessage", params)
data, err := b.Raw("deleteMessage", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// Notify updates the chat action for recipient.
@ -997,12 +996,12 @@ func (b *Bot) Notify(recipient Recipient, action ChatAction) error {
"action": string(action),
}
respJSON, err := b.Raw("sendChatAction", params)
data, err := b.Raw("sendChatAction", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// Accept finalizes the deal.
@ -1018,12 +1017,12 @@ func (b *Bot) Accept(query *PreCheckoutQuery, errorMessage ...string) error {
params["error_message"] = errorMessage[0]
}
respJSON, err := b.Raw("answerPreCheckoutQuery", params)
data, err := b.Raw("answerPreCheckoutQuery", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// Answer sends a response for a given inline query. A query can only
@ -1036,12 +1035,12 @@ func (b *Bot) Answer(query *Query, response *QueryResponse) error {
result.Process()
}
respJSON, err := b.Raw("answerInlineQuery", response)
data, err := b.Raw("answerInlineQuery", response)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// Respond sends a response for a given callback query. A callback can
@ -1062,12 +1061,12 @@ func (b *Bot) Respond(callback *Callback, responseOptional ...*CallbackResponse)
}
response.CallbackID = callback.ID
respJSON, err := b.Raw("answerCallbackQuery", response)
data, err := b.Raw("answerCallbackQuery", response)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// FileByID returns full file object including File.FilePath, allowing you to
@ -1080,7 +1079,7 @@ func (b *Bot) FileByID(fileID string) (File, error) {
"file_id": fileID,
}
respJSON, err := b.Raw("getFile", params)
data, err := b.Raw("getFile", params)
if err != nil {
return File{}, err
}
@ -1091,7 +1090,7 @@ func (b *Bot) FileByID(fileID string) (File, error) {
Result File
}
err = json.Unmarshal(respJSON, &resp)
err = json.Unmarshal(data, &resp)
if err != nil {
return File{}, errors.Wrap(err, "bad response json")
}
@ -1171,12 +1170,12 @@ func (b *Bot) StopLiveLocation(message Editable, options ...interface{}) (*Messa
sendOpts := extractOptions(options)
embedSendOptions(params, sendOpts)
respJSON, err := b.Raw("stopMessageLiveLocation", params)
data, err := b.Raw("stopMessageLiveLocation", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
return extractMessage(data)
}
// GetInviteLink should be used to export chat's invite link.
@ -1185,7 +1184,7 @@ func (b *Bot) GetInviteLink(chat *Chat) (string, error) {
"chat_id": chat.Recipient(),
}
respJSON, err := b.Raw("exportChatInviteLink", params)
data, err := b.Raw("exportChatInviteLink", params)
if err != nil {
return "", err
}
@ -1196,7 +1195,7 @@ func (b *Bot) GetInviteLink(chat *Chat) (string, error) {
Result string
}
err = json.Unmarshal(respJSON, &resp)
err = json.Unmarshal(data, &resp)
if err != nil {
return "", errors.Wrap(err, "bad response json")
}
@ -1215,12 +1214,12 @@ func (b *Bot) SetGroupTitle(chat *Chat, newTitle string) error {
"title": newTitle,
}
respJSON, err := b.Raw("setChatTitle", params)
data, err := b.Raw("setChatTitle", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// SetGroupDescription should be used to update group title.
@ -1230,12 +1229,12 @@ func (b *Bot) SetGroupDescription(chat *Chat, description string) error {
"description": description,
}
respJSON, err := b.Raw("setChatDescription", params)
data, err := b.Raw("setChatDescription", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// SetGroupPhoto should be used to update group photo.
@ -1244,12 +1243,12 @@ func (b *Bot) SetGroupPhoto(chat *Chat, p *Photo) error {
"chat_id": chat.Recipient(),
}
respJSON, err := b.sendFiles("setChatPhoto", map[string]File{"photo": p.File}, params)
data, err := b.sendFiles("setChatPhoto", map[string]File{"photo": p.File}, params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// SetGroupStickerSet should be used to update group's group sticker set.
@ -1259,12 +1258,12 @@ func (b *Bot) SetGroupStickerSet(chat *Chat, setName string) error {
"sticker_set_name": setName,
}
respJSON, err := b.Raw("setChatStickerSet", params)
data, err := b.Raw("setChatStickerSet", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// DeleteGroupPhoto should be used to just remove group photo.
@ -1273,12 +1272,12 @@ func (b *Bot) DeleteGroupPhoto(chat *Chat) error {
"chat_id": chat.Recipient(),
}
respJSON, err := b.Raw("deleteGroupPhoto", params)
data, err := b.Raw("deleteGroupPhoto", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// DeleteGroupStickerSet should be used to just remove group sticker set.
@ -1287,12 +1286,12 @@ func (b *Bot) DeleteGroupStickerSet(chat *Chat) error {
"chat_id": chat.Recipient(),
}
respJSON, err := b.Raw("deleteChatStickerSet", params)
data, err := b.Raw("deleteChatStickerSet", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// Leave makes bot leave a group, supergroup or channel.
@ -1301,12 +1300,12 @@ func (b *Bot) Leave(chat *Chat) error {
"chat_id": chat.Recipient(),
}
respJSON, err := b.Raw("leaveChat", params)
data, err := b.Raw("leaveChat", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// Use this method to pin a message in a supergroup or a channel.
@ -1323,12 +1322,12 @@ func (b *Bot) Pin(message Editable, options ...interface{}) error {
sendOpts := extractOptions(options)
embedSendOptions(params, sendOpts)
respJSON, err := b.Raw("pinChatMessage", params)
data, err := b.Raw("pinChatMessage", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// Use this method to unpin a message in a supergroup or a channel.
@ -1339,12 +1338,12 @@ func (b *Bot) Unpin(chat *Chat) error {
"chat_id": chat.Recipient(),
}
respJSON, err := b.Raw("unpinChatMessage", params)
data, err := b.Raw("unpinChatMessage", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// ChatByID fetches chat info of its ID.
@ -1358,7 +1357,7 @@ func (b *Bot) ChatByID(id string) (*Chat, error) {
"chat_id": id,
}
respJSON, err := b.Raw("getChat", params)
data, err := b.Raw("getChat", params)
if err != nil {
return nil, err
}
@ -1369,7 +1368,7 @@ func (b *Bot) ChatByID(id string) (*Chat, error) {
Result *Chat
}
err = json.Unmarshal(respJSON, &resp)
err = json.Unmarshal(data, &resp)
if err != nil {
return nil, errors.Wrap(err, "bad response json")
}
@ -1392,7 +1391,7 @@ func (b *Bot) ProfilePhotosOf(user *User) ([]Photo, error) {
"user_id": user.Recipient(),
}
respJSON, err := b.Raw("getUserProfilePhotos", params)
data, err := b.Raw("getUserProfilePhotos", params)
if err != nil {
return nil, err
}
@ -1407,7 +1406,7 @@ func (b *Bot) ProfilePhotosOf(user *User) ([]Photo, error) {
Description string `json:"description"`
}
err = json.Unmarshal(respJSON, &resp)
err = json.Unmarshal(data, &resp)
if err != nil {
return nil, errors.Wrap(err, "bad response json")
}
@ -1428,7 +1427,7 @@ func (b *Bot) ChatMemberOf(chat *Chat, user *User) (*ChatMember, error) {
"user_id": user.Recipient(),
}
respJSON, err := b.Raw("getChatMember", params)
data, err := b.Raw("getChatMember", params)
if err != nil {
return nil, err
}
@ -1439,7 +1438,7 @@ func (b *Bot) ChatMemberOf(chat *Chat, user *User) (*ChatMember, error) {
Description string `json:"description"`
}
err = json.Unmarshal(respJSON, &resp)
err = json.Unmarshal(data, &resp)
if err != nil {
return nil, errors.Wrap(err, "bad response json")
}
@ -1469,7 +1468,7 @@ func (b *Bot) UploadStickerFile(userID int, pngSticker *File) (*File, error) {
"user_id": strconv.Itoa(userID),
}
respJSON, err := b.sendFiles("uploadStickerFile", files, params)
data, err := b.sendFiles("uploadStickerFile", files, params)
if err != nil {
return nil, err
}
@ -1480,7 +1479,7 @@ func (b *Bot) UploadStickerFile(userID int, pngSticker *File) (*File, error) {
Description string
}
err = json.Unmarshal(respJSON, &resp)
err = json.Unmarshal(data, &resp)
if err != nil {
return nil, err
}
@ -1494,7 +1493,7 @@ func (b *Bot) UploadStickerFile(userID int, pngSticker *File) (*File, error) {
// GetStickerSet returns StickerSet on success.
func (b *Bot) GetStickerSet(name string) (*StickerSet, error) {
respJSON, err := b.Raw("getStickerSet", map[string]string{"name": name})
data, err := b.Raw("getStickerSet", map[string]string{"name": name})
if err != nil {
return nil, err
}
@ -1504,7 +1503,7 @@ func (b *Bot) GetStickerSet(name string) (*StickerSet, error) {
Description string
Result *StickerSet
}
err = json.Unmarshal(respJSON, &resp)
err = json.Unmarshal(data, &resp)
if err != nil {
return nil, err
}
@ -1536,12 +1535,12 @@ func (b *Bot) CreateNewStickerSet(sp StickerSetParams, containsMasks bool, maskP
params["mask_position"] = string(mp)
}
respJSON, err := b.sendFiles("createNewStickerSet", files, params)
data, err := b.sendFiles("createNewStickerSet", files, params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// AddStickerToSet adds new sticker to existing sticker set.
@ -1564,12 +1563,12 @@ func (b *Bot) AddStickerToSet(sp StickerSetParams, maskPosition MaskPosition) er
params["mask_position"] = string(mp)
}
respJSON, err := b.sendFiles("addStickerToSet", files, params)
data, err := b.sendFiles("addStickerToSet", files, params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// SetStickerPositionInSet moves a sticker in set to a specific position.
@ -1578,20 +1577,20 @@ func (b *Bot) SetStickerPositionInSet(sticker string, position int) error {
"sticker": sticker,
"position": strconv.Itoa(position),
}
respJSON, err := b.Raw("setStickerPositionInSet", params)
data, err := b.Raw("setStickerPositionInSet", params)
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}
// DeleteStickerFromSet deletes sticker from set created by the bot.
func (b *Bot) DeleteStickerFromSet(sticker string) error {
respJSON, err := b.Raw("deleteStickerFromSet", map[string]string{"sticker": sticker})
data, err := b.Raw("deleteStickerFromSet", map[string]string{"sticker": sticker})
if err != nil {
return err
}
return extractOkResponse(respJSON)
return extractOk(data)
}

@ -53,6 +53,7 @@ var (
ErrBlockedByUser = NewAPIError(401, "Forbidden: bot was blocked by the user")
ErrUserIsDeactivated = NewAPIError(401, "Forbidden: user is deactivated")
ErrNotFound = NewAPIError(404, "Not Found")
ErrInternal = NewAPIError(500, "Internal Server Error ")
// Bad request errors
ErrTooLarge = NewAPIError(400, "Request Entity Too Large")

@ -264,12 +264,12 @@ func (x *Location) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error
}
embedSendOptions(params, opt)
respJSON, err := b.Raw("sendLocation", params)
data, err := b.Raw("sendLocation", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
return extractMessage(data)
}
// Send delivers media through bot b to recipient.
@ -285,12 +285,12 @@ func (v *Venue) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
}
embedSendOptions(params, opt)
respJSON, err := b.Raw("sendVenue", params)
data, err := b.Raw("sendVenue", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
return extractMessage(data)
}
// Send delivers media through bot b to recipient.
@ -309,12 +309,12 @@ func (i *Invoice) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error)
}
embedSendOptions(params, opt)
respJSON, err := b.Raw("sendInvoice", params)
data, err := b.Raw("sendInvoice", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
return extractMessage(data)
}
func (p *Poll) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
@ -336,10 +336,10 @@ func (p *Poll) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
opts, _ := json.Marshal(options)
params["options"] = string(opts)
respJSON, err := b.Raw("sendPoll", params)
data, err := b.Raw("sendPoll", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
return extractMessage(data)
}

@ -2,6 +2,7 @@ package telebot
import (
"encoding/json"
"fmt"
"log"
"strconv"
@ -10,7 +11,6 @@ import (
func (b *Bot) debug(err error) {
err = errors.WithStack(err)
if b.reporter != nil {
b.reporter(err)
} else {
@ -28,84 +28,39 @@ func (b *Bot) deferDebug() {
}
}
func (b *Bot) sendText(to Recipient, text string, opt *SendOptions) (*Message, error) {
params := map[string]string{
"chat_id": to.Recipient(),
"text": text,
}
embedSendOptions(params, opt)
respJSON, err := b.Raw("sendMessage", params)
if err != nil {
return nil, err
}
return extractMsgResponse(respJSON)
}
// wrapError returns new wrapped telebot-related error.
func wrapError(err error) error {
return errors.Wrap(err, "telebot")
}
func isUserInList(user *User, list []User) bool {
for _, user2 := range list {
if user.ID == user2.ID {
return true
}
}
return false
}
func extractMsgResponse(respJSON []byte) (*Message, error) {
var resp struct {
Ok bool
Result *Message
Description string
}
err := json.Unmarshal(respJSON, &resp)
if err != nil {
var resp struct {
Ok bool
Result bool
Description string
}
err := json.Unmarshal(respJSON, &resp)
if err != nil {
return nil, errors.Wrap(err, "bad response json")
}
if !resp.Ok {
return nil, errors.Errorf("api error: %s", resp.Description)
}
// extractOk checks given result for error. If result is ok returns nil.
// In other cases it extracts API error. If error is not presented
// in errors.go, it will be prefixed with `unknown` keyword.
func extractOk(data []byte) error {
match := errorRx.FindStringSubmatch(string(data))
if match == nil || len(match) < 3 {
return nil
}
if !resp.Ok {
return nil, errors.Errorf("api error: %s", resp.Description)
desc := match[2]
err := ErrByDescription(desc)
if err == nil {
code, _ := strconv.Atoi(match[1])
err = fmt.Errorf("telegram unknown: %s (%d)", desc, code)
}
return resp.Result, nil
return err
}
func extractOkResponse(respJSON []byte) error {
// extractMessage extracts common Message result from given data.
// Should be called after extractOk or b.Raw to handle possible errors.
func extractMessage(data []byte) (*Message, error) {
var resp struct {
Ok bool
Description string
}
err := json.Unmarshal(respJSON, &resp)
if err != nil {
return errors.Wrap(err, "bad response json")
Result *Message
}
if !resp.Ok {
return errors.Errorf("api error: %s", resp.Description)
if err := json.Unmarshal(data, &resp); err != nil {
return nil, wrapError(err)
}
return nil
return resp.Result, nil
}
func extractOptions(how []interface{}) *SendOptions {
@ -115,13 +70,11 @@ func extractOptions(how []interface{}) *SendOptions {
switch opt := prop.(type) {
case *SendOptions:
opts = opt.copy()
case *ReplyMarkup:
if opts == nil {
opts = &SendOptions{}
}
opts.ReplyMarkup = opt.copy()
case Option:
if opts == nil {
opts = &SendOptions{}
@ -145,13 +98,11 @@ func extractOptions(how []interface{}) *SendOptions {
default:
panic("telebot: unsupported flag-option")
}
case ParseMode:
if opts == nil {
opts = &SendOptions{}
}
opts.ParseMode = opt
default:
panic("telebot: unsupported send-option")
}
@ -209,9 +160,9 @@ func processButtons(keys [][]InlineButton) {
}
}
func embedRights(p map[string]string, prv Rights) {
jsonRepr, _ := json.Marshal(prv)
_ = json.Unmarshal(jsonRepr, &p)
func embedRights(p map[string]string, rights Rights) {
data, _ := json.Marshal(rights)
_ = json.Unmarshal(data, &p)
}
func thumbnailToFilemap(thumb *Photo) map[string]File {
@ -220,3 +171,12 @@ func thumbnailToFilemap(thumb *Photo) map[string]File {
}
return nil
}
func isUserInList(user *User, list []User) bool {
for _, user2 := range list {
if user.ID == user2.ID {
return true
}
}
return false
}

Loading…
Cancel
Save