|
|
@ -149,6 +149,11 @@ var (
|
|
|
|
cbackRx = regexp.MustCompile(`^\f(\w+)(\|(.+))?$`)
|
|
|
|
cbackRx = regexp.MustCompile(`^\f(\w+)(\|(.+))?$`)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (b *Bot) handleCommand(m *Message, cmdName, cmdBot string) bool {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Start brings bot into motion by consuming incoming
|
|
|
|
// Start brings bot into motion by consuming incoming
|
|
|
|
// updates (see Bot.Updates channel).
|
|
|
|
// updates (see Bot.Updates channel).
|
|
|
|
func (b *Bot) Start() {
|
|
|
|
func (b *Bot) Start() {
|
|
|
@ -277,7 +282,7 @@ func (b *Bot) incomingUpdate(upd *Update) {
|
|
|
|
defer b.deferDebug()
|
|
|
|
defer b.deferDebug()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
handler(from, to)
|
|
|
|
handler(from, to)
|
|
|
|
}(b, handler, m.Chat.ID, m.MigrateTo)
|
|
|
|
}(b, handler, m.MigrateFrom, m.MigrateTo)
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
panic("telebot: migration handler is bad")
|
|
|
|
panic("telebot: migration handler is bad")
|
|
|
@ -307,13 +312,8 @@ func (b *Bot) incomingUpdate(upd *Update) {
|
|
|
|
|
|
|
|
|
|
|
|
if upd.Callback != nil {
|
|
|
|
if upd.Callback != nil {
|
|
|
|
if upd.Callback.Data != "" {
|
|
|
|
if upd.Callback.Data != "" {
|
|
|
|
if upd.Callback.MessageID != "" {
|
|
|
|
|
|
|
|
upd.Callback.Message = &Message{
|
|
|
|
|
|
|
|
InlineID: upd.Callback.MessageID,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data := upd.Callback.Data
|
|
|
|
data := upd.Callback.Data
|
|
|
|
|
|
|
|
|
|
|
|
if data[0] == '\f' {
|
|
|
|
if data[0] == '\f' {
|
|
|
|
match := cbackRx.FindAllStringSubmatch(data, -1)
|
|
|
|
match := cbackRx.FindAllStringSubmatch(data, -1)
|
|
|
|
|
|
|
|
|
|
|
@ -503,7 +503,7 @@ func (b *Bot) Stop() {
|
|
|
|
// some Sendable (or string!) and optional send options.
|
|
|
|
// some Sendable (or string!) and optional send options.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Note: since most arguments are of type interface{}, but have pointer
|
|
|
|
// Note: since most arguments are of type interface{}, but have pointer
|
|
|
|
// method receivers, make sure to pass them by-pointer, NOT by-value.
|
|
|
|
// method recievers, make sure to pass them by-pointer, NOT by-value.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// What is a send option exactly? It can be one of the following types:
|
|
|
|
// What is a send option exactly? It can be one of the following types:
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -540,15 +540,14 @@ func (b *Bot) SendAlbum(to Recipient, a Album, options ...interface{}) ([]Messag
|
|
|
|
|
|
|
|
|
|
|
|
f := x.MediaFile()
|
|
|
|
f := x.MediaFile()
|
|
|
|
|
|
|
|
|
|
|
|
switch {
|
|
|
|
if f.InCloud() {
|
|
|
|
case f.InCloud():
|
|
|
|
|
|
|
|
mediaRepr = f.FileID
|
|
|
|
mediaRepr = f.FileID
|
|
|
|
case f.FileURL != "":
|
|
|
|
} else if f.FileURL != "" {
|
|
|
|
mediaRepr = f.FileURL
|
|
|
|
mediaRepr = f.FileURL
|
|
|
|
case f.OnDisk() || f.FileReader != nil:
|
|
|
|
} else if f.OnDisk() || f.FileReader != nil {
|
|
|
|
mediaRepr = "attach://" + strconv.Itoa(i)
|
|
|
|
mediaRepr = fmt.Sprintf("attach://%d", i)
|
|
|
|
files[strconv.Itoa(i)] = *f
|
|
|
|
files[strconv.Itoa(i)] = *f
|
|
|
|
default:
|
|
|
|
} else {
|
|
|
|
return nil, errors.Errorf(
|
|
|
|
return nil, errors.Errorf(
|
|
|
|
"telebot: album entry #%d doesn't exist anywhere", i)
|
|
|
|
"telebot: album entry #%d doesn't exist anywhere", i)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -556,15 +555,13 @@ func (b *Bot) SendAlbum(to Recipient, a Album, options ...interface{}) ([]Messag
|
|
|
|
switch y := x.(type) {
|
|
|
|
switch y := x.(type) {
|
|
|
|
case *Photo:
|
|
|
|
case *Photo:
|
|
|
|
jsonRepr, _ = json.Marshal(struct {
|
|
|
|
jsonRepr, _ = json.Marshal(struct {
|
|
|
|
Type string `json:"type"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
Media string `json:"media"`
|
|
|
|
Caption string `json:"caption"`
|
|
|
|
Caption string `json:"caption,omitempty"`
|
|
|
|
Media string `json:"media"`
|
|
|
|
ParseMode ParseMode `json:"parse_mode,omitempty"`
|
|
|
|
|
|
|
|
}{
|
|
|
|
}{
|
|
|
|
"photo",
|
|
|
|
"photo",
|
|
|
|
mediaRepr,
|
|
|
|
|
|
|
|
y.Caption,
|
|
|
|
y.Caption,
|
|
|
|
y.ParseMode,
|
|
|
|
mediaRepr,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
case *Video:
|
|
|
|
case *Video:
|
|
|
|
jsonRepr, _ = json.Marshal(struct {
|
|
|
|
jsonRepr, _ = json.Marshal(struct {
|
|
|
@ -619,7 +616,7 @@ func (b *Bot) SendAlbum(to Recipient, a Album, options ...interface{}) ([]Messag
|
|
|
|
return nil, errors.Errorf("api error: %s", resp.Description)
|
|
|
|
return nil, errors.Errorf("api error: %s", resp.Description)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for attachName := range files {
|
|
|
|
for attachName, _ := range files {
|
|
|
|
i, _ := strconv.Atoi(attachName)
|
|
|
|
i, _ := strconv.Atoi(attachName)
|
|
|
|
|
|
|
|
|
|
|
|
var newID string
|
|
|
|
var newID string
|
|
|
@ -714,39 +711,11 @@ func (b *Bot) Edit(message Editable, what interface{}, options ...interface{}) (
|
|
|
|
return extractMsgResponse(respJSON)
|
|
|
|
return extractMsgResponse(respJSON)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// EditReplyMarkup used to edit reply markup of already sent message.
|
|
|
|
// EditCaption used to edit already sent photo caption with known recepient and message id.
|
|
|
|
//
|
|
|
|
|
|
|
|
// On success, returns edited message object
|
|
|
|
|
|
|
|
func (b *Bot) EditReplyMarkup(message Editable, markup *ReplyMarkup) (*Message, error) {
|
|
|
|
|
|
|
|
messageID, chatID := message.MessageSig()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
params := map[string]string{}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if inline message
|
|
|
|
|
|
|
|
if chatID == 0 {
|
|
|
|
|
|
|
|
params["inline_message_id"] = messageID
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
params["chat_id"] = strconv.FormatInt(chatID, 10)
|
|
|
|
|
|
|
|
params["message_id"] = messageID
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
processButtons(markup.InlineKeyboard)
|
|
|
|
|
|
|
|
jsonMarkup, _ := json.Marshal(markup)
|
|
|
|
|
|
|
|
params["reply_markup"] = string(jsonMarkup)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
respJSON, err := b.Raw("editMessageReplyMarkup", params)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return extractMsgResponse(respJSON)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// EditCaption used to edit already sent photo caption with known recipient and message id.
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// On success, returns edited message object
|
|
|
|
// On success, returns edited message object
|
|
|
|
func (b *Bot) EditCaption(message Editable, caption string, options ...interface{}) (*Message, error) {
|
|
|
|
func (b *Bot) EditCaption(originalMsg Editable, caption string) (*Message, error) {
|
|
|
|
messageID, chatID := message.MessageSig()
|
|
|
|
messageID, chatID := originalMsg.MessageSig()
|
|
|
|
|
|
|
|
|
|
|
|
params := map[string]string{"caption": caption}
|
|
|
|
params := map[string]string{"caption": caption}
|
|
|
|
|
|
|
|
|
|
|
@ -758,9 +727,6 @@ func (b *Bot) EditCaption(message Editable, caption string, options ...interface
|
|
|
|
params["message_id"] = messageID
|
|
|
|
params["message_id"] = messageID
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sendOpts := extractOptions(options)
|
|
|
|
|
|
|
|
embedSendOptions(params, sendOpts)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
respJSON, err := b.Raw("editMessageCaption", params)
|
|
|
|
respJSON, err := b.Raw("editMessageCaption", params)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
return nil, err
|
|
|
@ -769,7 +735,7 @@ func (b *Bot) EditCaption(message Editable, caption string, options ...interface
|
|
|
|
return extractMsgResponse(respJSON)
|
|
|
|
return extractMsgResponse(respJSON)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// EditMedia used to edit already sent media with known recipient and message id.
|
|
|
|
// EditMedia used to edit already sent media with known recepient and message id.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Use cases:
|
|
|
|
// Use cases:
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -784,34 +750,28 @@ func (b *Bot) EditMedia(message Editable, inputMedia InputMedia, options ...inte
|
|
|
|
file := make(map[string]File)
|
|
|
|
file := make(map[string]File)
|
|
|
|
|
|
|
|
|
|
|
|
f := inputMedia.MediaFile()
|
|
|
|
f := inputMedia.MediaFile()
|
|
|
|
thumbAttachName := "thumb"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch {
|
|
|
|
if f.InCloud() {
|
|
|
|
case f.InCloud():
|
|
|
|
|
|
|
|
mediaRepr = f.FileID
|
|
|
|
mediaRepr = f.FileID
|
|
|
|
case f.FileURL != "":
|
|
|
|
} else if f.FileURL != "" {
|
|
|
|
mediaRepr = f.FileURL
|
|
|
|
mediaRepr = f.FileURL
|
|
|
|
case f.OnDisk() || f.FileReader != nil:
|
|
|
|
} else if f.OnDisk() || f.FileReader != nil {
|
|
|
|
s := f.FileLocal
|
|
|
|
s := f.FileLocal
|
|
|
|
if f.FileReader != nil {
|
|
|
|
if f.FileReader != nil {
|
|
|
|
s = "0"
|
|
|
|
s = "0"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if s == thumbAttachName {
|
|
|
|
|
|
|
|
thumbAttachName = "thumb2"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
mediaRepr = "attach://" + s
|
|
|
|
mediaRepr = "attach://" + s
|
|
|
|
file[s] = *f
|
|
|
|
file[s] = *f
|
|
|
|
default:
|
|
|
|
} else {
|
|
|
|
return nil, errors.Errorf(
|
|
|
|
return nil, errors.Errorf(
|
|
|
|
"telebot: can't edit media, it doesn't exist anywhere")
|
|
|
|
"telebot: can't edit media, it doesn't exist anywhere")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type FileJSON struct {
|
|
|
|
type FileJson struct {
|
|
|
|
// All types.
|
|
|
|
// All types.
|
|
|
|
Type string `json:"type"`
|
|
|
|
Type string `json:"type"`
|
|
|
|
Caption string `json:"caption"`
|
|
|
|
Caption string `json:"caption"`
|
|
|
|
Media string `json:"media"`
|
|
|
|
Media string `json:"media"`
|
|
|
|
ParseMode ParseMode `json:"parse_mode,omitempty"`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Video.
|
|
|
|
// Video.
|
|
|
|
Width int `json:"width,omitempty"`
|
|
|
|
Width int `json:"width,omitempty"`
|
|
|
@ -833,12 +793,7 @@ func (b *Bot) EditMedia(message Editable, inputMedia InputMedia, options ...inte
|
|
|
|
Performer string `json:"performer,omitempty"`
|
|
|
|
Performer string `json:"performer,omitempty"`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
resultMedia := &FileJSON{Media: mediaRepr}
|
|
|
|
resultMedia := &FileJson{Media: mediaRepr}
|
|
|
|
|
|
|
|
|
|
|
|
sendOpts := extractOptions(options)
|
|
|
|
|
|
|
|
if sendOpts != nil {
|
|
|
|
|
|
|
|
resultMedia.ParseMode = sendOpts.ParseMode
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch y := inputMedia.(type) {
|
|
|
|
switch y := inputMedia.(type) {
|
|
|
|
case *Photo:
|
|
|
|
case *Photo:
|
|
|
@ -854,7 +809,7 @@ func (b *Bot) EditMedia(message Editable, inputMedia InputMedia, options ...inte
|
|
|
|
resultMedia.MIME = y.MIME
|
|
|
|
resultMedia.MIME = y.MIME
|
|
|
|
thumb = y.Thumbnail
|
|
|
|
thumb = y.Thumbnail
|
|
|
|
if thumb != nil {
|
|
|
|
if thumb != nil {
|
|
|
|
resultMedia.Thumbnail = "attach://" + thumbAttachName
|
|
|
|
resultMedia.Thumbnail = "attach://thumb"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case *Document:
|
|
|
|
case *Document:
|
|
|
|
resultMedia.Type = "document"
|
|
|
|
resultMedia.Type = "document"
|
|
|
@ -863,7 +818,7 @@ func (b *Bot) EditMedia(message Editable, inputMedia InputMedia, options ...inte
|
|
|
|
resultMedia.MIME = y.MIME
|
|
|
|
resultMedia.MIME = y.MIME
|
|
|
|
thumb = y.Thumbnail
|
|
|
|
thumb = y.Thumbnail
|
|
|
|
if thumb != nil {
|
|
|
|
if thumb != nil {
|
|
|
|
resultMedia.Thumbnail = "attach://" + thumbAttachName
|
|
|
|
resultMedia.Thumbnail = "attach://thumb"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case *Audio:
|
|
|
|
case *Audio:
|
|
|
|
resultMedia.Type = "audio"
|
|
|
|
resultMedia.Type = "audio"
|
|
|
@ -872,10 +827,6 @@ func (b *Bot) EditMedia(message Editable, inputMedia InputMedia, options ...inte
|
|
|
|
resultMedia.MIME = y.MIME
|
|
|
|
resultMedia.MIME = y.MIME
|
|
|
|
resultMedia.Title = y.Title
|
|
|
|
resultMedia.Title = y.Title
|
|
|
|
resultMedia.Performer = y.Performer
|
|
|
|
resultMedia.Performer = y.Performer
|
|
|
|
thumb = y.Thumbnail
|
|
|
|
|
|
|
|
if thumb != nil {
|
|
|
|
|
|
|
|
resultMedia.Thumbnail = "attach://" + thumbAttachName
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
return nil, errors.Errorf("telebot: inputMedia entry is not valid")
|
|
|
|
return nil, errors.Errorf("telebot: inputMedia entry is not valid")
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -895,9 +846,10 @@ func (b *Bot) EditMedia(message Editable, inputMedia InputMedia, options ...inte
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if thumb != nil {
|
|
|
|
if thumb != nil {
|
|
|
|
file[thumbAttachName] = *thumb.MediaFile()
|
|
|
|
file["thumb"] = *thumb.MediaFile()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sendOpts := extractOptions(options)
|
|
|
|
embedSendOptions(params, sendOpts)
|
|
|
|
embedSendOptions(params, sendOpts)
|
|
|
|
|
|
|
|
|
|
|
|
respJSON, err := b.sendFiles("editMessageMedia", file, params)
|
|
|
|
respJSON, err := b.sendFiles("editMessageMedia", file, params)
|
|
|
@ -940,7 +892,7 @@ func (b *Bot) Delete(message Editable) error {
|
|
|
|
// Chat action is a status message that recipient would see where
|
|
|
|
// Chat action is a status message that recipient would see where
|
|
|
|
// you typically see "Harry is typing" status message. The only
|
|
|
|
// you typically see "Harry is typing" status message. The only
|
|
|
|
// difference is that bots' chat actions live only for 5 seconds
|
|
|
|
// difference is that bots' chat actions live only for 5 seconds
|
|
|
|
// and die just once the client receives a message from the bot.
|
|
|
|
// and die just once the client recieves a message from the bot.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Currently, Telegram supports only a narrow range of possible
|
|
|
|
// Currently, Telegram supports only a narrow range of possible
|
|
|
|
// actions, these are aligned as constants of this package.
|
|
|
|
// actions, these are aligned as constants of this package.
|
|
|
@ -1088,23 +1040,16 @@ func (b *Bot) GetFile(file *File) (io.ReadCloser, error) {
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// save FilePath
|
|
|
|
|
|
|
|
file.FilePath = f.FilePath
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
req, err := http.NewRequest("GET", b.URL+"/file/bot"+b.Token+"/"+f.FilePath, nil)
|
|
|
|
url := fmt.Sprintf("%s/file/bot%s/%s",
|
|
|
|
if err != nil {
|
|
|
|
b.URL, b.Token, f.FilePath)
|
|
|
|
return nil, wrapSystem(err)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resp, err := b.client.Do(req)
|
|
|
|
resp, err := http.Get(url)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "file http.GET failed")
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
|
|
|
|
|
|
resp.Body.Close()
|
|
|
|
|
|
|
|
return nil, errors.Errorf("api error: expected 200 OK but got %s", resp.Status)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// set FilePath
|
|
|
|
|
|
|
|
*file = f
|
|
|
|
|
|
|
|
|
|
|
|
return resp.Body, nil
|
|
|
|
return resp.Body, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1117,7 +1062,7 @@ func (b *Bot) StopLiveLocation(message Editable, options ...interface{}) (*Messa
|
|
|
|
messageID, chatID := message.MessageSig()
|
|
|
|
messageID, chatID := message.MessageSig()
|
|
|
|
|
|
|
|
|
|
|
|
params := map[string]string{
|
|
|
|
params := map[string]string{
|
|
|
|
"chat_id": strconv.FormatInt(chatID, 10),
|
|
|
|
"chat_id": fmt.Sprintf("%d", chatID),
|
|
|
|
"message_id": messageID,
|
|
|
|
"message_id": messageID,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1161,7 +1106,7 @@ func (b *Bot) GetInviteLink(chat *Chat) (string, error) {
|
|
|
|
return resp.Result, nil
|
|
|
|
return resp.Result, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SetGroupTitle should be used to update group title.
|
|
|
|
// SetChatTitle should be used to update group title.
|
|
|
|
func (b *Bot) SetGroupTitle(chat *Chat, newTitle string) error {
|
|
|
|
func (b *Bot) SetGroupTitle(chat *Chat, newTitle string) error {
|
|
|
|
params := map[string]string{
|
|
|
|
params := map[string]string{
|
|
|
|
"chat_id": chat.Recipient(),
|
|
|
|
"chat_id": chat.Recipient(),
|
|
|
@ -1410,141 +1355,5 @@ func (b *Bot) FileURLByID(fileID string) (string, error) {
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return b.URL + "/file/bot" + b.Token + "/" + f.FilePath, nil
|
|
|
|
return fmt.Sprintf("%s/file/bot%s/%s", b.URL, b.Token, f.FilePath), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// UploadStickerFile returns uploaded File on success.
|
|
|
|
|
|
|
|
func (b *Bot) UploadStickerFile(userID int, pngSticker *File) (*File, error) {
|
|
|
|
|
|
|
|
files := map[string]File{
|
|
|
|
|
|
|
|
"png_sticker": *pngSticker,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
params := map[string]string{
|
|
|
|
|
|
|
|
"user_id": strconv.Itoa(userID),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
respJSON, err := b.sendFiles("uploadStickerFile", files, params)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var resp struct {
|
|
|
|
|
|
|
|
Ok bool
|
|
|
|
|
|
|
|
Result File
|
|
|
|
|
|
|
|
Description string
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = json.Unmarshal(respJSON, &resp)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if !resp.Ok {
|
|
|
|
|
|
|
|
return nil, errors.Errorf("api error: %s", resp.Description)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return &resp.Result, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// GetStickerSet returns StickerSet on success.
|
|
|
|
|
|
|
|
func (b *Bot) GetStickerSet(name string) (*StickerSet, error) {
|
|
|
|
|
|
|
|
respJSON, err := b.Raw("getStickerSet", map[string]string{"name": name})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var resp struct {
|
|
|
|
|
|
|
|
Ok bool
|
|
|
|
|
|
|
|
Description string
|
|
|
|
|
|
|
|
Result *StickerSet
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
err = json.Unmarshal(respJSON, &resp)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if !resp.Ok {
|
|
|
|
|
|
|
|
return nil, errors.Errorf("api error: %s", resp.Description)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return resp.Result, nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// CreateNewStickerSet creates new sticker set.
|
|
|
|
|
|
|
|
func (b *Bot) CreateNewStickerSet(sp StickerSetParams, containsMasks bool, maskPosition MaskPosition) error {
|
|
|
|
|
|
|
|
files := map[string]File{
|
|
|
|
|
|
|
|
"png_sticker": *sp.PngSticker,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
params := map[string]string{
|
|
|
|
|
|
|
|
"user_id": strconv.Itoa(sp.UserID),
|
|
|
|
|
|
|
|
"name": sp.Name,
|
|
|
|
|
|
|
|
"title": sp.Title,
|
|
|
|
|
|
|
|
"emojis": sp.Emojis,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if containsMasks {
|
|
|
|
|
|
|
|
mp, err := json.Marshal(&maskPosition)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
params["mask_position"] = string(mp)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
respJSON, err := b.sendFiles("createNewStickerSet", files, params)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return extractOkResponse(respJSON)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// AddStickerToSet adds new sticker to existing sticker set.
|
|
|
|
|
|
|
|
func (b *Bot) AddStickerToSet(sp StickerSetParams, maskPosition MaskPosition) error {
|
|
|
|
|
|
|
|
files := map[string]File{
|
|
|
|
|
|
|
|
"png_sticker": *sp.PngSticker,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
params := map[string]string{
|
|
|
|
|
|
|
|
"user_id": strconv.Itoa(sp.UserID),
|
|
|
|
|
|
|
|
"name": sp.Name,
|
|
|
|
|
|
|
|
"title": sp.Title,
|
|
|
|
|
|
|
|
"emojis": sp.Emojis,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if maskPosition != (MaskPosition{}) {
|
|
|
|
|
|
|
|
mp, err := json.Marshal(&maskPosition)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
params["mask_position"] = string(mp)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
respJSON, err := b.sendFiles("addStickerToSet", files, params)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return extractOkResponse(respJSON)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// SetStickerPositionInSet moves a sticker in set to a specific position.
|
|
|
|
|
|
|
|
func (b *Bot) SetStickerPositionInSet(sticker string, position int) error {
|
|
|
|
|
|
|
|
params := map[string]string{
|
|
|
|
|
|
|
|
"sticker": sticker,
|
|
|
|
|
|
|
|
"position": strconv.Itoa(position),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
respJSON, err := b.Raw("setStickerPositionInSet", params)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return extractOkResponse(respJSON)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return extractOkResponse(respJSON)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|