Merge branch 'develop' into multiple-uploads

bot-api-6.1
Syfaro 2021-03-10 12:33:02 -05:00
commit 05db49c9e3
10 changed files with 3199 additions and 869 deletions

33
.github/workflows/test.yml vendored 100644
View File

@ -0,0 +1,33 @@
name: Test
on:
push:
branches:
- master
- develop
pull_request:
jobs:
build:
name: Test
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v2
with:
go-version: ^1.15
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Build
run: go build -v .
- name: Test
run: go test -coverprofile=coverage.out -covermode=atomic -v .
- name: Upload coverage report
uses: codecov/codecov-action@v1
with:
file: ./coverage.out

View File

@ -1,6 +0,0 @@
language: go
go:
- '1.13'
- '1.14'
- tip

View File

@ -3,7 +3,7 @@
[![GoDoc](https://godoc.org/github.com/go-telegram-bot-api/telegram-bot-api?status.svg)](http://godoc.org/github.com/go-telegram-bot-api/telegram-bot-api) [![GoDoc](https://godoc.org/github.com/go-telegram-bot-api/telegram-bot-api?status.svg)](http://godoc.org/github.com/go-telegram-bot-api/telegram-bot-api)
[![Travis](https://travis-ci.org/go-telegram-bot-api/telegram-bot-api.svg)](https://travis-ci.org/go-telegram-bot-api/telegram-bot-api) [![Travis](https://travis-ci.org/go-telegram-bot-api/telegram-bot-api.svg)](https://travis-ci.org/go-telegram-bot-api/telegram-bot-api)
All methods are fairly self explanatory, and reading the godoc page should All methods are fairly self explanatory, and reading the [godoc](http://godoc.org/github.com/go-telegram-bot-api/telegram-bot-api) page should
explain everything. If something isn't clear, open an issue or submit explain everything. If something isn't clear, open an issue or submit
a pull request. a pull request.

75
bot.go
View File

@ -17,14 +17,20 @@ import (
"time" "time"
) )
// HTTPClient is the type needed for the bot to perform HTTP requests.
type HTTPClient interface {
Do(req *http.Request) (*http.Response, error)
PostForm(url string, data url.Values) (*http.Response, error)
}
// BotAPI allows you to interact with the Telegram Bot API. // BotAPI allows you to interact with the Telegram Bot API.
type BotAPI struct { type BotAPI struct {
Token string `json:"token"` Token string `json:"token"`
Debug bool `json:"debug"` Debug bool `json:"debug"`
Buffer int `json:"buffer"` Buffer int `json:"buffer"`
Self User `json:"-"` Self User `json:"-"`
Client *http.Client `json:"-"` Client HTTPClient `json:"-"`
shutdownChannel chan interface{} shutdownChannel chan interface{}
apiEndpoint string apiEndpoint string
@ -34,21 +40,29 @@ type BotAPI struct {
// //
// It requires a token, provided by @BotFather on Telegram. // It requires a token, provided by @BotFather on Telegram.
func NewBotAPI(token string) (*BotAPI, error) { func NewBotAPI(token string) (*BotAPI, error) {
return NewBotAPIWithClient(token, &http.Client{}) return NewBotAPIWithClient(token, APIEndpoint, &http.Client{})
}
// NewBotAPIWithAPIEndpoint creates a new BotAPI instance
// and allows you to pass API endpoint.
//
// It requires a token, provided by @BotFather on Telegram and API endpoint.
func NewBotAPIWithAPIEndpoint(token, apiEndpoint string) (*BotAPI, error) {
return NewBotAPIWithClient(token, apiEndpoint, &http.Client{})
} }
// NewBotAPIWithClient creates a new BotAPI instance // NewBotAPIWithClient creates a new BotAPI instance
// and allows you to pass a http.Client. // and allows you to pass a http.Client.
// //
// It requires a token, provided by @BotFather on Telegram. // It requires a token, provided by @BotFather on Telegram and API endpoint.
func NewBotAPIWithClient(token string, client *http.Client) (*BotAPI, error) { func NewBotAPIWithClient(token, apiEndpoint string, client HTTPClient) (*BotAPI, error) {
bot := &BotAPI{ bot := &BotAPI{
Token: token, Token: token,
Client: client, Client: client,
Buffer: 100, Buffer: 100,
shutdownChannel: make(chan interface{}), shutdownChannel: make(chan interface{}),
apiEndpoint: APIEndpoint, apiEndpoint: apiEndpoint,
} }
self, err := bot.GetMe() self, err := bot.GetMe()
@ -411,7 +425,7 @@ func (bot *BotAPI) GetFile(config FileConfig) (File, error) {
// GetUpdates fetches updates. // GetUpdates fetches updates.
// If a WebHook is set, this will not return any data! // If a WebHook is set, this will not return any data!
// //
// Offset, Limit, and Timeout are optional. // Offset, Limit, Timeout, and AllowedUpdates are optional.
// To avoid stale items, set Offset to one higher than the previous item. // To avoid stale items, set Offset to one higher than the previous item.
// Set Timeout to a large number to reduce requests so you can get updates // Set Timeout to a large number to reduce requests so you can get updates
// instantly instead of having to wait between requests. // instantly instead of having to wait between requests.
@ -449,6 +463,7 @@ func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) UpdatesChannel {
for { for {
select { select {
case <-bot.shutdownChannel: case <-bot.shutdownChannel:
close(ch)
return return
default: default:
} }
@ -487,21 +502,35 @@ func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
ch := make(chan Update, bot.Buffer) ch := make(chan Update, bot.Buffer)
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) { 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 return ch
} }
// HandleUpdate parses and returns update received via webhook // HandleUpdate parses and returns update received via webhook
func (bot *BotAPI) HandleUpdate(res http.ResponseWriter, req *http.Request) Update { func (bot *BotAPI) HandleUpdate(r *http.Request) (*Update, error) {
bytes, _ := ioutil.ReadAll(req.Body) if r.Method != http.MethodPost {
req.Body.Close() err := errors.New("wrong HTTP method required POST")
return nil, err
}
var update Update var update Update
json.Unmarshal(bytes, &update) err := json.NewDecoder(r.Body).Decode(&update)
if err != nil {
return nil, err
}
return update return &update, nil
} }
// WriteToHTTPResponse writes the request to the HTTP ResponseWriter. // WriteToHTTPResponse writes the request to the HTTP ResponseWriter.
@ -651,3 +680,23 @@ func (bot *BotAPI) GetMyCommands() ([]BotCommand, error) {
return commands, err return commands, err
} }
// CopyMessage copy messages of any kind. The method is analogous to the method
// forwardMessage, but the copied message doesn't have a link to the original
// message. Returns the MessageID of the sent message on success.
func (bot *BotAPI) CopyMessage(config CopyMessageConfig) (MessageID, error) {
params, err := config.params()
if err != nil {
return MessageID{}, err
}
resp, err := bot.MakeRequest(config.method(), params)
if err != nil {
return MessageID{}, err
}
var messageID MessageID
err = json.Unmarshal(resp.Result, &messageID)
return messageID, err
}

View File

@ -23,10 +23,25 @@ const (
ExistingStickerFileID = "BQADAgADcwADjMcoCbdl-6eB--YPAg" ExistingStickerFileID = "BQADAgADcwADjMcoCbdl-6eB--YPAg"
) )
type testLogger struct {
t *testing.T
}
func (t testLogger) Println(v ...interface{}) {
t.t.Log(v...)
}
func (t testLogger) Printf(format string, v ...interface{}) {
t.t.Logf(format, v...)
}
func getBot(t *testing.T) (*BotAPI, error) { func getBot(t *testing.T) (*BotAPI, error) {
bot, err := NewBotAPI(TestToken) bot, err := NewBotAPI(TestToken)
bot.Debug = true bot.Debug = true
logger := testLogger{t}
SetLogger(logger)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -58,7 +73,7 @@ func TestSendWithMessage(t *testing.T) {
bot, _ := getBot(t) bot, _ := getBot(t)
msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api") msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api")
msg.ParseMode = "markdown" msg.ParseMode = ModeMarkdown
_, err := bot.Send(msg) _, err := bot.Send(msg)
if err != nil { if err != nil {
@ -89,6 +104,26 @@ func TestSendWithMessageForward(t *testing.T) {
} }
} }
func TestCopyMessage(t *testing.T) {
bot, _ := getBot(t)
msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api")
message, err := bot.Send(msg)
if err != nil {
t.Error(err)
}
copyMessageConfig := NewCopyMessage(SupergroupChatID, message.Chat.ID, message.MessageID)
messageID, err := bot.CopyMessage(copyMessageConfig)
if err != nil {
t.Error(err)
}
if messageID.MessageID == message.MessageID {
t.Error("copied message ID was the same as original message")
}
}
func TestSendWithNewPhoto(t *testing.T) { func TestSendWithNewPhoto(t *testing.T) {
bot, _ := getBot(t) bot, _ := getBot(t)
@ -427,6 +462,32 @@ func TestSendWithExistingStickerAndKeyboardHide(t *testing.T) {
} }
} }
func TestSendWithDice(t *testing.T) {
bot, _ := getBot(t)
msg := NewDice(ChatID)
_, err := bot.Send(msg)
if err != nil {
t.Error(err)
t.Fail()
}
}
func TestSendWithDiceWithEmoji(t *testing.T) {
bot, _ := getBot(t)
msg := NewDiceWithEmoji(ChatID, "🏀")
_, err := bot.Send(msg)
if err != nil {
t.Error(err)
t.Fail()
}
}
func TestGetFile(t *testing.T) { func TestGetFile(t *testing.T) {
bot, _ := getBot(t) bot, _ := getBot(t)
@ -487,7 +548,7 @@ func TestSetWebhookWithCert(t *testing.T) {
time.Sleep(time.Second * 2) time.Sleep(time.Second * 2)
bot.Request(RemoveWebhookConfig{}) bot.Request(DeleteWebhookConfig{})
wh := NewWebhookWithCert("https://example.com/tgbotapi-test/"+bot.Token, "tests/cert.pem") wh := NewWebhookWithCert("https://example.com/tgbotapi-test/"+bot.Token, "tests/cert.pem")
_, err := bot.Request(wh) _, err := bot.Request(wh)
@ -501,7 +562,7 @@ func TestSetWebhookWithCert(t *testing.T) {
t.Error(err) t.Error(err)
} }
bot.Request(RemoveWebhookConfig{}) bot.Request(DeleteWebhookConfig{})
} }
func TestSetWebhookWithoutCert(t *testing.T) { func TestSetWebhookWithoutCert(t *testing.T) {
@ -509,7 +570,7 @@ func TestSetWebhookWithoutCert(t *testing.T) {
time.Sleep(time.Second * 2) time.Sleep(time.Second * 2)
bot.Request(RemoveWebhookConfig{}) bot.Request(DeleteWebhookConfig{})
wh := NewWebhook("https://example.com/tgbotapi-test/" + bot.Token) wh := NewWebhook("https://example.com/tgbotapi-test/" + bot.Token)
_, err := bot.Request(wh) _, err := bot.Request(wh)
@ -529,14 +590,14 @@ func TestSetWebhookWithoutCert(t *testing.T) {
t.Errorf("failed to set webhook: %s", info.LastErrorMessage) t.Errorf("failed to set webhook: %s", info.LastErrorMessage)
} }
bot.Request(RemoveWebhookConfig{}) bot.Request(DeleteWebhookConfig{})
} }
func TestSendWithMediaGroupPhotoVideo(t *testing.T) { func TestSendWithMediaGroupPhotoVideo(t *testing.T) {
bot, _ := getBot(t) bot, _ := getBot(t)
cfg := NewMediaGroup(ChatID, []interface{}{ cfg := NewMediaGroup(ChatID, []interface{}{
NewInputMediaPhoto(FileURL("https://i.imgur.com/unQLJIb.jpg")), NewInputMediaPhoto(FileURL("https://github.com/go-telegram-bot-api/telegram-bot-api/raw/0a3a1c8716c4cd8d26a262af9f12dcbab7f3f28c/tests/image.jpg")),
NewInputMediaPhoto("tests/image.jpg"), NewInputMediaPhoto("tests/image.jpg"),
NewInputMediaVideo("tests/video.mp4"), NewInputMediaVideo("tests/video.mp4"),
}) })
@ -689,7 +750,12 @@ func ExampleWebhookHandler() {
} }
http.HandleFunc("/"+bot.Token, func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/"+bot.Token, func(w http.ResponseWriter, r *http.Request) {
log.Printf("%+v\n", bot.HandleUpdate(w, r)) 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) go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil)
@ -733,7 +799,7 @@ func TestDeleteMessage(t *testing.T) {
bot, _ := getBot(t) bot, _ := getBot(t)
msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api") msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api")
msg.ParseMode = "markdown" msg.ParseMode = ModeMarkdown
message, _ := bot.Send(msg) message, _ := bot.Send(msg)
deleteMessageConfig := DeleteMessageConfig{ deleteMessageConfig := DeleteMessageConfig{
@ -751,7 +817,7 @@ func TestPinChatMessage(t *testing.T) {
bot, _ := getBot(t) bot, _ := getBot(t)
msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api")
msg.ParseMode = "markdown" msg.ParseMode = ModeMarkdown
message, _ := bot.Send(msg) message, _ := bot.Send(msg)
pinChatMessageConfig := PinChatMessageConfig{ pinChatMessageConfig := PinChatMessageConfig{
@ -770,7 +836,7 @@ func TestUnpinChatMessage(t *testing.T) {
bot, _ := getBot(t) bot, _ := getBot(t)
msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api") msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api")
msg.ParseMode = "markdown" msg.ParseMode = ModeMarkdown
message, _ := bot.Send(msg) message, _ := bot.Send(msg)
// We need pin message to unpin something // We need pin message to unpin something
@ -785,7 +851,8 @@ func TestUnpinChatMessage(t *testing.T) {
} }
unpinChatMessageConfig := UnpinChatMessageConfig{ unpinChatMessageConfig := UnpinChatMessageConfig{
ChatID: message.Chat.ID, ChatID: message.Chat.ID,
MessageID: message.MessageID,
} }
if _, err := bot.Request(unpinChatMessageConfig); err != nil { if _, err := bot.Request(unpinChatMessageConfig); err != nil {
@ -793,6 +860,32 @@ func TestUnpinChatMessage(t *testing.T) {
} }
} }
func TestUnpinAllChatMessages(t *testing.T) {
bot, _ := getBot(t)
msg := NewMessage(SupergroupChatID, "A test message from the test library in telegram-bot-api")
msg.ParseMode = ModeMarkdown
message, _ := bot.Send(msg)
pinChatMessageConfig := PinChatMessageConfig{
ChatID: message.Chat.ID,
MessageID: message.MessageID,
DisableNotification: true,
}
if _, err := bot.Request(pinChatMessageConfig); err != nil {
t.Error(err)
}
unpinAllChatMessagesConfig := UnpinAllChatMessagesConfig{
ChatID: message.Chat.ID,
}
if _, err := bot.Request(unpinAllChatMessagesConfig); err != nil {
t.Error(err)
}
}
func TestPolls(t *testing.T) { func TestPolls(t *testing.T) {
bot, _ := getBot(t) bot, _ := getBot(t)

View File

@ -43,6 +43,54 @@ const (
ModeHTML = "HTML" ModeHTML = "HTML"
) )
// Constant values for update types
const (
// New incoming message of any kind — text, photo, sticker, etc.
UpdateTypeMessage = "message"
// New version of a message that is known to the bot and was edited
UpdateTypeEditedMessage = "edited_message"
// New incoming channel post of any kind — text, photo, sticker, etc.
UpdateTypeChannelPost = "channel_post"
// New version of a channel post that is known to the bot and was edited
UpdateTypeEditedChannelPost = "edited_channel_post"
// New incoming inline query
UpdateTypeInlineQuery = "inline_query"
// The result of an inline query that was chosen by a user and sent to their
// chat partner. Please see the documentation on the feedback collecting for
// details on how to enable these updates for your bot.
UpdateTypeChosenInlineResult = "chosen_inline_result"
// New incoming callback query
UpdateTypeCallbackQuery = "callback_query"
// New incoming shipping query. Only for invoices with flexible price
UpdateTypeShippingQuery = "shipping_query"
// New incoming pre-checkout query. Contains full information about checkout
UpdateTypePreCheckoutQuery = "pre_checkout_query"
// New poll state. Bots receive only updates about stopped polls and polls
// which are sent by the bot
UpdateTypePoll = "poll"
// A user changed their answer in a non-anonymous poll. Bots receive new votes
// only in polls that were sent by the bot itself.
UpdateTypePollAnswer = "poll_answer"
// The bot's chat member status was updated in a chat. For private chats, this
// update is received only when the bot is blocked or unblocked by the user.
UpdateTypeMyChatMember = "my_chat_member"
// The bot must be an administrator in the chat and must explicitly specify
// this update in the list of allowed_updates to receive these updates.
UpdateTypeChatMember = "chat_member"
)
// Library errors // Library errors
const ( const (
// ErrBadFileType happens when you pass an unknown type // ErrBadFileType happens when you pass an unknown type
@ -71,13 +119,41 @@ type Fileable interface {
files() []RequestFile files() []RequestFile
} }
// LogOutConfig is a request to log out of the cloud Bot API server.
//
// Note that you may not log back in for at least 10 minutes.
type LogOutConfig struct{}
func (LogOutConfig) method() string {
return "logOut"
}
func (LogOutConfig) params() (Params, error) {
return nil, nil
}
// CloseConfig is a request to close the bot instance on a local server.
//
// Note that you may not close an instance for the first 10 minutes after the
// bot has started.
type CloseConfig struct{}
func (CloseConfig) method() string {
return "close"
}
func (CloseConfig) params() (Params, error) {
return nil, nil
}
// BaseChat is base type for all chat config types. // BaseChat is base type for all chat config types.
type BaseChat struct { type BaseChat struct {
ChatID int64 // required ChatID int64 // required
ChannelUsername string ChannelUsername string
ReplyToMessageID int ReplyToMessageID int
ReplyMarkup interface{} ReplyMarkup interface{}
DisableNotification bool DisableNotification bool
AllowSendingWithoutReply bool
} }
func (chat *BaseChat) params() (Params, error) { func (chat *BaseChat) params() (Params, error) {
@ -86,6 +162,7 @@ func (chat *BaseChat) params() (Params, error) {
params.AddFirstValid("chat_id", chat.ChatID, chat.ChannelUsername) params.AddFirstValid("chat_id", chat.ChatID, chat.ChannelUsername)
params.AddNonZero("reply_to_message_id", chat.ReplyToMessageID) params.AddNonZero("reply_to_message_id", chat.ReplyToMessageID)
params.AddBool("disable_notification", chat.DisableNotification) params.AddBool("disable_notification", chat.DisableNotification)
params.AddBool("allow_sending_without_reply", chat.AllowSendingWithoutReply)
err := params.AddInterface("reply_markup", chat.ReplyMarkup) err := params.AddInterface("reply_markup", chat.ReplyMarkup)
@ -131,6 +208,7 @@ type MessageConfig struct {
BaseChat BaseChat
Text string Text string
ParseMode string ParseMode string
Entities []MessageEntity
DisableWebPagePreview bool DisableWebPagePreview bool
} }
@ -143,8 +221,9 @@ func (config MessageConfig) params() (Params, error) {
params.AddNonEmpty("text", config.Text) params.AddNonEmpty("text", config.Text)
params.AddBool("disable_web_page_preview", config.DisableWebPagePreview) params.AddBool("disable_web_page_preview", config.DisableWebPagePreview)
params.AddNonEmpty("parse_mode", config.ParseMode) params.AddNonEmpty("parse_mode", config.ParseMode)
err = params.AddInterface("entities", config.Entities)
return params, nil return params, err
} }
func (config MessageConfig) method() string { func (config MessageConfig) method() string {
@ -175,19 +254,54 @@ func (config ForwardConfig) method() string {
return "forwardMessage" return "forwardMessage"
} }
// CopyMessageConfig contains information about a copyMessage request.
type CopyMessageConfig struct {
BaseChat
FromChatID int64
FromChannelUsername string
MessageID int
Caption string
ParseMode string
CaptionEntities []MessageEntity
}
func (config CopyMessageConfig) params() (Params, error) {
params, err := config.BaseChat.params()
if err != nil {
return params, err
}
params.AddFirstValid("from_chat_id", config.FromChatID, config.FromChannelUsername)
params.AddNonZero("message_id", config.MessageID)
params.AddNonEmpty("caption", config.Caption)
params.AddNonEmpty("parse_mode", config.ParseMode)
err = params.AddInterface("caption_entities", config.CaptionEntities)
return params, err
}
func (config CopyMessageConfig) method() string {
return "copyMessage"
}
// PhotoConfig contains information about a SendPhoto request. // PhotoConfig contains information about a SendPhoto request.
type PhotoConfig struct { type PhotoConfig struct {
BaseFile BaseFile
Thumb interface{} Thumb interface{}
Caption string Caption string
ParseMode string ParseMode string
CaptionEntities []MessageEntity
} }
func (config PhotoConfig) params() (Params, error) { func (config PhotoConfig) params() (Params, error) {
params, err := config.BaseFile.params() params, err := config.BaseFile.params()
if err != nil {
return params, err
}
params.AddNonEmpty("caption", config.Caption) params.AddNonEmpty("caption", config.Caption)
params.AddNonEmpty("parse_mode", config.ParseMode) params.AddNonEmpty("parse_mode", config.ParseMode)
err = params.AddInterface("caption_entities", config.CaptionEntities)
return params, err return params, err
} }
@ -215,12 +329,13 @@ func (config PhotoConfig) files() []RequestFile {
// AudioConfig contains information about a SendAudio request. // AudioConfig contains information about a SendAudio request.
type AudioConfig struct { type AudioConfig struct {
BaseFile BaseFile
Thumb interface{} Thumb interface{}
Caption string Caption string
ParseMode string ParseMode string
Duration int CaptionEntities []MessageEntity
Performer string Duration int
Title string Performer string
Title string
} }
func (config AudioConfig) params() (Params, error) { func (config AudioConfig) params() (Params, error) {
@ -234,8 +349,9 @@ func (config AudioConfig) params() (Params, error) {
params.AddNonEmpty("title", config.Title) params.AddNonEmpty("title", config.Title)
params.AddNonEmpty("caption", config.Caption) params.AddNonEmpty("caption", config.Caption)
params.AddNonEmpty("parse_mode", config.ParseMode) params.AddNonEmpty("parse_mode", config.ParseMode)
err = params.AddInterface("caption_entities", config.CaptionEntities)
return params, nil return params, err
} }
func (config AudioConfig) method() string { func (config AudioConfig) method() string {
@ -261,9 +377,11 @@ func (config AudioConfig) files() []RequestFile {
// DocumentConfig contains information about a SendDocument request. // DocumentConfig contains information about a SendDocument request.
type DocumentConfig struct { type DocumentConfig struct {
BaseFile BaseFile
Thumb interface{} Thumb interface{}
Caption string Caption string
ParseMode string ParseMode string
CaptionEntities []MessageEntity
DisableContentTypeDetection bool
} }
func (config DocumentConfig) params() (Params, error) { func (config DocumentConfig) params() (Params, error) {
@ -271,6 +389,7 @@ func (config DocumentConfig) params() (Params, error) {
params.AddNonEmpty("caption", config.Caption) params.AddNonEmpty("caption", config.Caption)
params.AddNonEmpty("parse_mode", config.ParseMode) params.AddNonEmpty("parse_mode", config.ParseMode)
params.AddBool("disable_content_type_detection", config.DisableContentTypeDetection)
return params, err return params, err
} }
@ -322,16 +441,21 @@ type VideoConfig struct {
Duration int Duration int
Caption string Caption string
ParseMode string ParseMode string
CaptionEntities []MessageEntity
SupportsStreaming bool SupportsStreaming bool
} }
func (config VideoConfig) params() (Params, error) { func (config VideoConfig) params() (Params, error) {
params, err := config.BaseChat.params() params, err := config.BaseChat.params()
if err != nil {
return params, err
}
params.AddNonZero("duration", config.Duration) params.AddNonZero("duration", config.Duration)
params.AddNonEmpty("caption", config.Caption) params.AddNonEmpty("caption", config.Caption)
params.AddNonEmpty("parse_mode", config.ParseMode) params.AddNonEmpty("parse_mode", config.ParseMode)
params.AddBool("supports_streaming", config.SupportsStreaming) params.AddBool("supports_streaming", config.SupportsStreaming)
err = params.AddInterface("caption_entities", config.CaptionEntities)
return params, err return params, err
} }
@ -359,18 +483,23 @@ func (config VideoConfig) files() []RequestFile {
// AnimationConfig contains information about a SendAnimation request. // AnimationConfig contains information about a SendAnimation request.
type AnimationConfig struct { type AnimationConfig struct {
BaseFile BaseFile
Duration int Duration int
Thumb interface{} Thumb interface{}
Caption string Caption string
ParseMode string ParseMode string
CaptionEntities []MessageEntity
} }
func (config AnimationConfig) params() (Params, error) { func (config AnimationConfig) params() (Params, error) {
params, err := config.BaseChat.params() params, err := config.BaseChat.params()
if err != nil {
return params, err
}
params.AddNonZero("duration", config.Duration) params.AddNonZero("duration", config.Duration)
params.AddNonEmpty("caption", config.Caption) params.AddNonEmpty("caption", config.Caption)
params.AddNonEmpty("parse_mode", config.ParseMode) params.AddNonEmpty("parse_mode", config.ParseMode)
err = params.AddInterface("caption_entities", config.CaptionEntities)
return params, err return params, err
} }
@ -435,18 +564,23 @@ func (config VideoNoteConfig) files() []RequestFile {
// VoiceConfig contains information about a SendVoice request. // VoiceConfig contains information about a SendVoice request.
type VoiceConfig struct { type VoiceConfig struct {
BaseFile BaseFile
Thumb interface{} Thumb interface{}
Caption string Caption string
ParseMode string ParseMode string
Duration int CaptionEntities []MessageEntity
Duration int
} }
func (config VoiceConfig) params() (Params, error) { func (config VoiceConfig) params() (Params, error) {
params, err := config.BaseChat.params() params, err := config.BaseChat.params()
if err != nil {
return params, err
}
params.AddNonZero("duration", config.Duration) params.AddNonZero("duration", config.Duration)
params.AddNonEmpty("caption", config.Caption) params.AddNonEmpty("caption", config.Caption)
params.AddNonEmpty("parse_mode", config.ParseMode) params.AddNonEmpty("parse_mode", config.ParseMode)
err = params.AddInterface("caption_entities", config.CaptionEntities)
return params, err return params, err
} }
@ -474,9 +608,12 @@ func (config VoiceConfig) files() []RequestFile {
// LocationConfig contains information about a SendLocation request. // LocationConfig contains information about a SendLocation request.
type LocationConfig struct { type LocationConfig struct {
BaseChat BaseChat
Latitude float64 // required Latitude float64 // required
Longitude float64 // required Longitude float64 // required
LivePeriod int // optional HorizontalAccuracy float64 // optional
LivePeriod int // optional
Heading int // optional
ProximityAlertRadius int // optional
} }
func (config LocationConfig) params() (Params, error) { func (config LocationConfig) params() (Params, error) {
@ -484,7 +621,10 @@ func (config LocationConfig) params() (Params, error) {
params.AddNonZeroFloat("latitude", config.Latitude) params.AddNonZeroFloat("latitude", config.Latitude)
params.AddNonZeroFloat("longitude", config.Longitude) params.AddNonZeroFloat("longitude", config.Longitude)
params.AddNonZeroFloat("horizontal_accuracy", config.HorizontalAccuracy)
params.AddNonZero("live_period", config.LivePeriod) params.AddNonZero("live_period", config.LivePeriod)
params.AddNonZero("heading", config.Heading)
params.AddNonZero("proximity_alert_radius", config.ProximityAlertRadius)
return params, err return params, err
} }
@ -496,8 +636,11 @@ func (config LocationConfig) method() string {
// EditMessageLiveLocationConfig allows you to update a live location. // EditMessageLiveLocationConfig allows you to update a live location.
type EditMessageLiveLocationConfig struct { type EditMessageLiveLocationConfig struct {
BaseEdit BaseEdit
Latitude float64 // required Latitude float64 // required
Longitude float64 // required Longitude float64 // required
HorizontalAccuracy float64 // optional
Heading int // optional
ProximityAlertRadius int // optional
} }
func (config EditMessageLiveLocationConfig) params() (Params, error) { func (config EditMessageLiveLocationConfig) params() (Params, error) {
@ -505,6 +648,9 @@ func (config EditMessageLiveLocationConfig) params() (Params, error) {
params.AddNonZeroFloat("latitude", config.Latitude) params.AddNonZeroFloat("latitude", config.Latitude)
params.AddNonZeroFloat("longitude", config.Longitude) params.AddNonZeroFloat("longitude", config.Longitude)
params.AddNonZeroFloat("horizontal_accuracy", config.HorizontalAccuracy)
params.AddNonZero("heading", config.Heading)
params.AddNonZero("proximity_alert_radius", config.ProximityAlertRadius)
return params, err return params, err
} }
@ -529,11 +675,14 @@ func (config StopMessageLiveLocationConfig) method() string {
// VenueConfig contains information about a SendVenue request. // VenueConfig contains information about a SendVenue request.
type VenueConfig struct { type VenueConfig struct {
BaseChat BaseChat
Latitude float64 // required Latitude float64 // required
Longitude float64 // required Longitude float64 // required
Title string // required Title string // required
Address string // required Address string // required
FoursquareID string FoursquareID string
FoursquareType string
GooglePlaceID string
GooglePlaceType string
} }
func (config VenueConfig) params() (Params, error) { func (config VenueConfig) params() (Params, error) {
@ -544,6 +693,9 @@ func (config VenueConfig) params() (Params, error) {
params["title"] = config.Title params["title"] = config.Title
params["address"] = config.Address params["address"] = config.Address
params.AddNonEmpty("foursquare_id", config.FoursquareID) params.AddNonEmpty("foursquare_id", config.FoursquareID)
params.AddNonEmpty("foursquare_type", config.FoursquareType)
params.AddNonEmpty("google_place_id", config.GooglePlaceID)
params.AddNonEmpty("google_place_type", config.GooglePlaceType)
return params, err return params, err
} }
@ -588,6 +740,7 @@ type SendPollConfig struct {
CorrectOptionID int64 CorrectOptionID int64
Explanation string Explanation string
ExplanationParseMode string ExplanationParseMode string
ExplanationEntities []MessageEntity
OpenPeriod int OpenPeriod int
CloseDate int CloseDate int
IsClosed bool IsClosed bool
@ -600,7 +753,9 @@ func (config SendPollConfig) params() (Params, error) {
} }
params["question"] = config.Question params["question"] = config.Question
err = params.AddInterface("options", config.Options) if err = params.AddInterface("options", config.Options); err != nil {
return params, err
}
params["is_anonymous"] = strconv.FormatBool(config.IsAnonymous) params["is_anonymous"] = strconv.FormatBool(config.IsAnonymous)
params.AddNonEmpty("type", config.Type) params.AddNonEmpty("type", config.Type)
params["allows_multiple_answers"] = strconv.FormatBool(config.AllowsMultipleAnswers) params["allows_multiple_answers"] = strconv.FormatBool(config.AllowsMultipleAnswers)
@ -610,6 +765,7 @@ func (config SendPollConfig) params() (Params, error) {
params.AddNonEmpty("explanation_parse_mode", config.ExplanationParseMode) params.AddNonEmpty("explanation_parse_mode", config.ExplanationParseMode)
params.AddNonZero("open_period", config.OpenPeriod) params.AddNonZero("open_period", config.OpenPeriod)
params.AddNonZero("close_date", config.CloseDate) params.AddNonZero("close_date", config.CloseDate)
err = params.AddInterface("explanation_entities", config.ExplanationEntities)
return params, err return params, err
} }
@ -720,15 +876,20 @@ type EditMessageTextConfig struct {
BaseEdit BaseEdit
Text string Text string
ParseMode string ParseMode string
Entities []MessageEntity
DisableWebPagePreview bool DisableWebPagePreview bool
} }
func (config EditMessageTextConfig) params() (Params, error) { func (config EditMessageTextConfig) params() (Params, error) {
params, err := config.BaseEdit.params() params, err := config.BaseEdit.params()
if err != nil {
return params, err
}
params["text"] = config.Text params["text"] = config.Text
params.AddNonEmpty("parse_mode", config.ParseMode) params.AddNonEmpty("parse_mode", config.ParseMode)
params.AddBool("disable_web_page_preview", config.DisableWebPagePreview) params.AddBool("disable_web_page_preview", config.DisableWebPagePreview)
err = params.AddInterface("entities", config.Entities)
return params, err return params, err
} }
@ -740,15 +901,20 @@ func (config EditMessageTextConfig) method() string {
// EditMessageCaptionConfig allows you to modify the caption of a message. // EditMessageCaptionConfig allows you to modify the caption of a message.
type EditMessageCaptionConfig struct { type EditMessageCaptionConfig struct {
BaseEdit BaseEdit
Caption string Caption string
ParseMode string ParseMode string
CaptionEntities []MessageEntity
} }
func (config EditMessageCaptionConfig) params() (Params, error) { func (config EditMessageCaptionConfig) params() (Params, error) {
params, err := config.BaseEdit.params() params, err := config.BaseEdit.params()
if err != nil {
return params, err
}
params["caption"] = config.Caption params["caption"] = config.Caption
params.AddNonEmpty("parse_mode", config.ParseMode) params.AddNonEmpty("parse_mode", config.ParseMode)
err = params.AddInterface("caption_entities", config.CaptionEntities)
return params, err return params, err
} }
@ -851,9 +1017,10 @@ func (config FileConfig) params() (Params, error) {
// UpdateConfig contains information about a GetUpdates request. // UpdateConfig contains information about a GetUpdates request.
type UpdateConfig struct { type UpdateConfig struct {
Offset int Offset int
Limit int Limit int
Timeout int Timeout int
AllowedUpdates []string
} }
func (UpdateConfig) method() string { func (UpdateConfig) method() string {
@ -866,16 +1033,19 @@ func (config UpdateConfig) params() (Params, error) {
params.AddNonZero("offset", config.Offset) params.AddNonZero("offset", config.Offset)
params.AddNonZero("limit", config.Limit) params.AddNonZero("limit", config.Limit)
params.AddNonZero("timeout", config.Timeout) params.AddNonZero("timeout", config.Timeout)
params.AddInterface("allowed_updates", config.AllowedUpdates)
return params, nil return params, nil
} }
// WebhookConfig contains information about a SetWebhook request. // WebhookConfig contains information about a SetWebhook request.
type WebhookConfig struct { type WebhookConfig struct {
URL *url.URL URL *url.URL
Certificate interface{} Certificate interface{}
MaxConnections int IPAddress string
AllowedUpdates []string MaxConnections int
AllowedUpdates []string
DropPendingUpdates bool
} }
func (config WebhookConfig) method() string { func (config WebhookConfig) method() string {
@ -889,8 +1059,10 @@ func (config WebhookConfig) params() (Params, error) {
params["url"] = config.URL.String() params["url"] = config.URL.String()
} }
params.AddNonEmpty("ip_address", config.IPAddress)
params.AddNonZero("max_connections", config.MaxConnections) params.AddNonZero("max_connections", config.MaxConnections)
err := params.AddInterface("allowed_updates", config.AllowedUpdates) err := params.AddInterface("allowed_updates", config.AllowedUpdates)
params.AddBool("drop_pending_updates", config.DropPendingUpdates)
return params, err return params, err
} }
@ -906,16 +1078,21 @@ func (config WebhookConfig) files() []RequestFile {
return nil return nil
} }
// RemoveWebhookConfig is a helper to remove a webhook. // DeleteWebhookConfig is a helper to delete a webhook.
type RemoveWebhookConfig struct { type DeleteWebhookConfig struct {
DropPendingUpdates bool
} }
func (config RemoveWebhookConfig) method() string { func (config DeleteWebhookConfig) method() string {
return "setWebhook" return "deleteWebhook"
} }
func (config RemoveWebhookConfig) params() (Params, error) { func (config DeleteWebhookConfig) params() (Params, error) {
return nil, nil params := make(Params)
params.AddBool("drop_pending_updates", config.DropPendingUpdates)
return params, nil
} }
// FileBytes contains information about a set of bytes to upload // FileBytes contains information about a set of bytes to upload
@ -961,12 +1138,9 @@ func (config InlineConfig) params() (Params, error) {
params.AddNonEmpty("next_offset", config.NextOffset) params.AddNonEmpty("next_offset", config.NextOffset)
params.AddNonEmpty("switch_pm_text", config.SwitchPMText) params.AddNonEmpty("switch_pm_text", config.SwitchPMText)
params.AddNonEmpty("switch_pm_parameter", config.SwitchPMParameter) params.AddNonEmpty("switch_pm_parameter", config.SwitchPMParameter)
err := params.AddInterface("results", config.Results)
if err := params.AddInterface("results", config.Results); err != nil { return params, err
return params, err
}
return params, nil
} }
// CallbackConfig contains information on making a CallbackQuery response. // CallbackConfig contains information on making a CallbackQuery response.
@ -1006,6 +1180,7 @@ type ChatMemberConfig struct {
// UnbanChatMemberConfig allows you to unban a user. // UnbanChatMemberConfig allows you to unban a user.
type UnbanChatMemberConfig struct { type UnbanChatMemberConfig struct {
ChatMemberConfig ChatMemberConfig
OnlyIfBanned bool
} }
func (config UnbanChatMemberConfig) method() string { func (config UnbanChatMemberConfig) method() string {
@ -1017,6 +1192,7 @@ func (config UnbanChatMemberConfig) params() (Params, error) {
params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
params.AddNonZero("user_id", config.UserID) params.AddNonZero("user_id", config.UserID)
params.AddBool("only_if_banned", config.OnlyIfBanned)
return params, nil return params, nil
} }
@ -1024,7 +1200,8 @@ func (config UnbanChatMemberConfig) params() (Params, error) {
// KickChatMemberConfig contains extra fields to kick user // KickChatMemberConfig contains extra fields to kick user
type KickChatMemberConfig struct { type KickChatMemberConfig struct {
ChatMemberConfig ChatMemberConfig
UntilDate int64 UntilDate int64
RevokeMessages bool
} }
func (config KickChatMemberConfig) method() string { func (config KickChatMemberConfig) method() string {
@ -1037,6 +1214,7 @@ func (config KickChatMemberConfig) params() (Params, error) {
params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
params.AddNonZero("user_id", config.UserID) params.AddNonZero("user_id", config.UserID)
params.AddNonZero64("until_date", config.UntilDate) params.AddNonZero64("until_date", config.UntilDate)
params.AddBool("revoke_messages", config.RevokeMessages)
return params, nil return params, nil
} }
@ -1058,25 +1236,26 @@ func (config RestrictChatMemberConfig) params() (Params, error) {
params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
params.AddNonZero("user_id", config.UserID) params.AddNonZero("user_id", config.UserID)
if err := params.AddInterface("permissions", config.Permissions); err != nil { err := params.AddInterface("permissions", config.Permissions)
return params, err
}
params.AddNonZero64("until_date", config.UntilDate) params.AddNonZero64("until_date", config.UntilDate)
return params, nil return params, err
} }
// PromoteChatMemberConfig contains fields to promote members of chat // PromoteChatMemberConfig contains fields to promote members of chat
type PromoteChatMemberConfig struct { type PromoteChatMemberConfig struct {
ChatMemberConfig ChatMemberConfig
CanChangeInfo bool IsAnonymous bool
CanPostMessages bool CanManageChat bool
CanEditMessages bool CanChangeInfo bool
CanDeleteMessages bool CanPostMessages bool
CanInviteUsers bool CanEditMessages bool
CanRestrictMembers bool CanDeleteMessages bool
CanPinMessages bool CanManageVoiceChats bool
CanPromoteMembers bool CanInviteUsers bool
CanRestrictMembers bool
CanPinMessages bool
CanPromoteMembers bool
} }
func (config PromoteChatMemberConfig) method() string { func (config PromoteChatMemberConfig) method() string {
@ -1089,10 +1268,13 @@ func (config PromoteChatMemberConfig) params() (Params, error) {
params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername) params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
params.AddNonZero("user_id", config.UserID) params.AddNonZero("user_id", config.UserID)
params.AddBool("is_anonymous", config.IsAnonymous)
params.AddBool("can_manage_chat", config.CanManageChat)
params.AddBool("can_change_info", config.CanChangeInfo) params.AddBool("can_change_info", config.CanChangeInfo)
params.AddBool("can_post_messages", config.CanPostMessages) params.AddBool("can_post_messages", config.CanPostMessages)
params.AddBool("can_edit_messages", config.CanEditMessages) params.AddBool("can_edit_messages", config.CanEditMessages)
params.AddBool("can_delete_messages", config.CanDeleteMessages) params.AddBool("can_delete_messages", config.CanDeleteMessages)
params.AddBool("can_manage_voice_chats", config.CanManageVoiceChats)
params.AddBool("can_invite_users", config.CanInviteUsers) params.AddBool("can_invite_users", config.CanInviteUsers)
params.AddBool("can_restrict_members", config.CanRestrictMembers) params.AddBool("can_restrict_members", config.CanRestrictMembers)
params.AddBool("can_pin_messages", config.CanPinMessages) params.AddBool("can_pin_messages", config.CanPinMessages)
@ -1203,6 +1385,77 @@ func (config ChatInviteLinkConfig) params() (Params, error) {
return params, nil return params, nil
} }
// CreateChatInviteLinkConfig allows you to create an additional invite link for
// a chat. The bot must be an administrator in the chat for this to work and
// must have the appropriate admin rights. The link can be revoked using the
// RevokeChatInviteLinkConfig.
type CreateChatInviteLinkConfig struct {
ChatConfig
ExpireDate int
MemberLimit int
}
func (CreateChatInviteLinkConfig) method() string {
return "createChatInviteLink"
}
func (config CreateChatInviteLinkConfig) params() (Params, error) {
params := make(Params)
params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
params.AddNonZero("expire_date", config.ExpireDate)
params.AddNonZero("member_limit", config.MemberLimit)
return params, nil
}
// EditChatInviteLinkConfig allows you to edit a non-primary invite link created
// by the bot. The bot must be an administrator in the chat for this to work and
// must have the appropriate admin rights.
type EditChatInviteLinkConfig struct {
ChatConfig
InviteLink string
ExpireDate int
MemberLimit int
}
func (EditChatInviteLinkConfig) method() string {
return "editChatInviteLink"
}
func (config EditChatInviteLinkConfig) params() (Params, error) {
params := make(Params)
params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
params["invite_link"] = config.InviteLink
params.AddNonZero("expire_date", config.ExpireDate)
params.AddNonZero("member_limit", config.MemberLimit)
return params, nil
}
// RevokeChatInviteLinkConfig allows you to revoke an invite link created by the
// bot. If the primary link is revoked, a new link is automatically generated.
// The bot must be an administrator in the chat for this to work and must have
// the appropriate admin rights.
type RevokeChatInviteLinkConfig struct {
ChatConfig
InviteLink string
}
func (RevokeChatInviteLinkConfig) method() string {
return "revokeChatInviteLink"
}
func (config RevokeChatInviteLinkConfig) params() (Params, error) {
params := make(Params)
params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername)
params["invite_link"] = config.InviteLink
return params, nil
}
// LeaveChatConfig allows you to leave a chat. // LeaveChatConfig allows you to leave a chat.
type LeaveChatConfig struct { type LeaveChatConfig struct {
ChatID int64 ChatID int64
@ -1283,10 +1536,7 @@ func (config InvoiceConfig) params() (Params, error) {
params["start_parameter"] = config.StartParameter params["start_parameter"] = config.StartParameter
params["currency"] = config.Currency params["currency"] = config.Currency
if err = params.AddInterface("prices", config.Prices); err != nil { err = params.AddInterface("prices", config.Prices)
return params, err
}
params.AddNonEmpty("provider_data", config.ProviderData) params.AddNonEmpty("provider_data", config.ProviderData)
params.AddNonEmpty("photo_url", config.PhotoURL) params.AddNonEmpty("photo_url", config.PhotoURL)
params.AddNonZero("photo_size", config.PhotoSize) params.AddNonZero("photo_size", config.PhotoSize)
@ -1300,7 +1550,7 @@ func (config InvoiceConfig) params() (Params, error) {
params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider) params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider)
params.AddBool("send_email_to_provider", config.SendEmailToProvider) params.AddBool("send_email_to_provider", config.SendEmailToProvider)
return params, nil return params, err
} }
func (config InvoiceConfig) method() string { func (config InvoiceConfig) method() string {
@ -1315,6 +1565,21 @@ type ShippingConfig struct {
ErrorMessage string ErrorMessage string
} }
func (config ShippingConfig) method() string {
return "answerShippingQuery"
}
func (config ShippingConfig) params() (Params, error) {
params := make(Params)
params["shipping_query_id"] = config.ShippingQueryID
params.AddBool("ok", config.OK)
err := params.AddInterface("shipping_options", config.ShippingOptions)
params.AddNonEmpty("error_message", config.ErrorMessage)
return params, err
}
// PreCheckoutConfig conatins information for answerPreCheckoutQuery request. // PreCheckoutConfig conatins information for answerPreCheckoutQuery request.
type PreCheckoutConfig struct { type PreCheckoutConfig struct {
PreCheckoutQueryID string // required PreCheckoutQueryID string // required
@ -1322,6 +1587,20 @@ type PreCheckoutConfig struct {
ErrorMessage string ErrorMessage string
} }
func (config PreCheckoutConfig) method() string {
return "answerPreCheckoutQuery"
}
func (config PreCheckoutConfig) params() (Params, error) {
params := make(Params)
params["pre_checkout_query_id"] = config.PreCheckoutQueryID
params.AddBool("ok", config.OK)
params.AddNonEmpty("error_message", config.ErrorMessage)
return params, nil
}
// DeleteMessageConfig contains information of a message in a chat to delete. // DeleteMessageConfig contains information of a message in a chat to delete.
type DeleteMessageConfig struct { type DeleteMessageConfig struct {
ChannelUsername string ChannelUsername string
@ -1364,10 +1643,13 @@ func (config PinChatMessageConfig) params() (Params, error) {
return params, nil return params, nil
} }
// UnpinChatMessageConfig contains information of chat to unpin. // UnpinChatMessageConfig contains information of a chat message to unpin.
//
// If MessageID is not specified, it will unpin the most recent pin.
type UnpinChatMessageConfig struct { type UnpinChatMessageConfig struct {
ChatID int64 ChatID int64
ChannelUsername string ChannelUsername string
MessageID int
} }
func (config UnpinChatMessageConfig) method() string { func (config UnpinChatMessageConfig) method() string {
@ -1377,6 +1659,26 @@ func (config UnpinChatMessageConfig) method() string {
func (config UnpinChatMessageConfig) params() (Params, error) { func (config UnpinChatMessageConfig) params() (Params, error) {
params := make(Params) params := make(Params)
params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
params.AddNonZero("message_id", config.MessageID)
return params, nil
}
// UnpinAllChatMessagesConfig contains information of all messages to unpin in
// a chat.
type UnpinAllChatMessagesConfig struct {
ChatID int64
ChannelUsername string
}
func (config UnpinAllChatMessagesConfig) method() string {
return "unpinAllChatMessages"
}
func (config UnpinAllChatMessagesConfig) params() (Params, error) {
params := make(Params)
params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername) params.AddFirstValid("chat_id", config.ChatID, config.ChannelUsername)
return params, nil return params, nil
@ -1723,12 +2025,14 @@ func (config MediaGroupConfig) files() []RequestFile {
return prepareInputMediaForFiles(config.Media) return prepareInputMediaForFiles(config.Media)
} }
// DiceConfig allows you to send a random dice roll to Telegram. // DiceConfig contains information about a sendDice request.
//
// Emoji may be one of the following: 🎲 (1-6), 🎯 (1-6), 🏀 (1-5).
type DiceConfig struct { type DiceConfig struct {
BaseChat BaseChat
// Emoji on which the dice throw animation is based.
// Currently, must be one of 🎲, 🎯, 🏀, ⚽, 🎳, or 🎰.
// Dice can have values 1-6 for 🎲, 🎯, and 🎳, values 1-5 for 🏀 and ⚽,
// and values 1-64 for 🎰.
// Defaults to “🎲”
Emoji string Emoji string
} }
@ -1755,7 +2059,7 @@ func (config GetMyCommandsConfig) method() string {
} }
func (config GetMyCommandsConfig) params() (Params, error) { func (config GetMyCommandsConfig) params() (Params, error) {
return make(Params), nil return nil, nil
} }
// SetMyCommandsConfig sets a list of commands the bot understands. // SetMyCommandsConfig sets a list of commands the bot understands.

View File

@ -29,7 +29,8 @@ func NewDeleteMessage(chatID int64, messageID int) DeleteMessageConfig {
// NewMessageToChannel creates a new Message that is sent to a channel // NewMessageToChannel creates a new Message that is sent to a channel
// by username. // by username.
// //
// username is the username of the channel, text is the message text. // username is the username of the channel, text is the message text,
// and the username should be in the form of `@username`.
func NewMessageToChannel(username string, text string) MessageConfig { func NewMessageToChannel(username string, text string) MessageConfig {
return MessageConfig{ return MessageConfig{
BaseChat: BaseChat{ BaseChat: BaseChat{
@ -51,8 +52,23 @@ func NewForward(chatID int64, fromChatID int64, messageID int) ForwardConfig {
} }
} }
// NewCopyMessage creates a new copy message.
//
// chatID is where to send it, fromChatID is the source chat,
// and messageID is the ID of the original message.
func NewCopyMessage(chatID int64, fromChatID int64, messageID int) CopyMessageConfig {
return CopyMessageConfig{
BaseChat: BaseChat{ChatID: chatID},
FromChatID: fromChatID,
MessageID: messageID,
}
}
// NewPhoto creates a new sendPhoto request. // NewPhoto creates a new sendPhoto request.
// //
// chatID is where to send it, file is a string path to the file,
// FileReader, or FileBytes.
//
// Note that you must send animated GIFs as a document. // Note that you must send animated GIFs as a document.
func NewPhoto(chatID int64, file interface{}) PhotoConfig { func NewPhoto(chatID int64, file interface{}) PhotoConfig {
return PhotoConfig{ return PhotoConfig{
@ -370,7 +386,7 @@ func NewInlineQueryResultCachedGIF(id, gifID string) InlineQueryResultCachedGIF
return InlineQueryResultCachedGIF{ return InlineQueryResultCachedGIF{
Type: "gif", Type: "gif",
ID: id, ID: id,
GifID: gifID, GIFID: gifID,
} }
} }
@ -383,12 +399,12 @@ func NewInlineQueryResultMPEG4GIF(id, url string) InlineQueryResultMPEG4GIF {
} }
} }
// NewInlineQueryResultCachedMPEG4GIF create a new inline query with cached photo. // NewInlineQueryResultCachedMPEG4GIF create a new inline query with cached MPEG4 GIF.
func NewInlineQueryResultCachedMPEG4GIF(id, MPEG4GifID string) InlineQueryResultCachedMpeg4Gif { func NewInlineQueryResultCachedMPEG4GIF(id, MPEG4GIFID string) InlineQueryResultCachedMPEG4GIF {
return InlineQueryResultCachedMpeg4Gif{ return InlineQueryResultCachedMPEG4GIF{
Type: "mpeg4_gif", Type: "mpeg4_gif",
ID: id, ID: id,
MGifID: MPEG4GifID, MPEG4FileID: MPEG4GIFID,
} }
} }
@ -543,6 +559,18 @@ func NewEditMessageText(chatID int64, messageID int, text string) EditMessageTex
} }
} }
// NewEditMessageTextAndMarkup allows you to edit the text and replymarkup of a message.
func NewEditMessageTextAndMarkup(chatID int64, messageID int, text string, replyMarkup InlineKeyboardMarkup) EditMessageTextConfig {
return EditMessageTextConfig{
BaseEdit: BaseEdit{
ChatID: chatID,
MessageID: messageID,
ReplyMarkup: &replyMarkup,
},
Text: text,
}
}
// NewEditMessageCaption allows you to edit the caption of a message. // NewEditMessageCaption allows you to edit the caption of a message.
func NewEditMessageCaption(chatID int64, messageID int, caption string) EditMessageCaptionConfig { func NewEditMessageCaption(chatID int64, messageID int, caption string) EditMessageCaptionConfig {
return EditMessageCaptionConfig{ return EditMessageCaptionConfig{
@ -566,17 +594,6 @@ func NewEditMessageReplyMarkup(chatID int64, messageID int, replyMarkup InlineKe
} }
} }
// NewHideKeyboard hides the keyboard, with the option for being selective
// or hiding for everyone.
func NewHideKeyboard(selective bool) ReplyKeyboardHide {
log.Println("NewHideKeyboard is deprecated, please use NewRemoveKeyboard")
return ReplyKeyboardHide{
HideKeyboard: true,
Selective: selective,
}
}
// NewRemoveKeyboard hides the keyboard, with the option for being selective // NewRemoveKeyboard hides the keyboard, with the option for being selective
// or hiding for everyone. // or hiding for everyone.
func NewRemoveKeyboard(selective bool) ReplyKeyboardRemove { func NewRemoveKeyboard(selective bool) ReplyKeyboardRemove {

View File

@ -174,3 +174,21 @@ func TestNewEditMessageReplyMarkup(t *testing.T) {
} }
} }
func TestNewDice(t *testing.T) {
dice := NewDice(42)
if dice.ChatID != 42 ||
dice.Emoji != "" {
t.Fail()
}
}
func TestNewDiceWithEmoji(t *testing.T) {
dice := NewDiceWithEmoji(42, "🏀")
if dice.ChatID != 42 ||
dice.Emoji != "🏀" {
t.Fail()
}
}

3282
types.go

File diff suppressed because it is too large Load Diff

View File

@ -282,15 +282,20 @@ var (
_ Chattable = AnimationConfig{} _ Chattable = AnimationConfig{}
_ Chattable = AudioConfig{} _ Chattable = AudioConfig{}
_ Chattable = CallbackConfig{} _ Chattable = CallbackConfig{}
_ Chattable = ChatAdministratorsConfig{}
_ Chattable = ChatActionConfig{} _ Chattable = ChatActionConfig{}
_ Chattable = ChatAdministratorsConfig{}
_ Chattable = ChatInfoConfig{} _ Chattable = ChatInfoConfig{}
_ Chattable = ChatInviteLinkConfig{} _ Chattable = ChatInviteLinkConfig{}
_ Chattable = CloseConfig{}
_ Chattable = ContactConfig{} _ Chattable = ContactConfig{}
_ Chattable = CopyMessageConfig{}
_ Chattable = CreateChatInviteLinkConfig{}
_ Chattable = DeleteChatPhotoConfig{} _ Chattable = DeleteChatPhotoConfig{}
_ Chattable = DeleteChatStickerSetConfig{} _ Chattable = DeleteChatStickerSetConfig{}
_ Chattable = DeleteMessageConfig{} _ Chattable = DeleteMessageConfig{}
_ Chattable = DeleteWebhookConfig{}
_ Chattable = DocumentConfig{} _ Chattable = DocumentConfig{}
_ Chattable = EditChatInviteLinkConfig{}
_ Chattable = EditMessageCaptionConfig{} _ Chattable = EditMessageCaptionConfig{}
_ Chattable = EditMessageLiveLocationConfig{} _ Chattable = EditMessageLiveLocationConfig{}
_ Chattable = EditMessageMediaConfig{} _ Chattable = EditMessageMediaConfig{}
@ -306,21 +311,24 @@ var (
_ Chattable = KickChatMemberConfig{} _ Chattable = KickChatMemberConfig{}
_ Chattable = LeaveChatConfig{} _ Chattable = LeaveChatConfig{}
_ Chattable = LocationConfig{} _ Chattable = LocationConfig{}
_ Chattable = LogOutConfig{}
_ Chattable = MediaGroupConfig{} _ Chattable = MediaGroupConfig{}
_ Chattable = MessageConfig{} _ Chattable = MessageConfig{}
_ Chattable = PhotoConfig{} _ Chattable = PhotoConfig{}
_ Chattable = PinChatMessageConfig{} _ Chattable = PinChatMessageConfig{}
_ Chattable = PreCheckoutConfig{}
_ Chattable = PromoteChatMemberConfig{} _ Chattable = PromoteChatMemberConfig{}
_ Chattable = RemoveWebhookConfig{}
_ Chattable = RestrictChatMemberConfig{} _ Chattable = RestrictChatMemberConfig{}
_ Chattable = RevokeChatInviteLinkConfig{}
_ Chattable = SendPollConfig{} _ Chattable = SendPollConfig{}
_ Chattable = SetChatDescriptionConfig{} _ Chattable = SetChatDescriptionConfig{}
_ Chattable = SetChatPhotoConfig{} _ Chattable = SetChatPhotoConfig{}
_ Chattable = SetChatTitleConfig{} _ Chattable = SetChatTitleConfig{}
_ Chattable = SetGameScoreConfig{} _ Chattable = SetGameScoreConfig{}
_ Chattable = ShippingConfig{}
_ Chattable = StickerConfig{} _ Chattable = StickerConfig{}
_ Chattable = StopPollConfig{}
_ Chattable = StopMessageLiveLocationConfig{} _ Chattable = StopMessageLiveLocationConfig{}
_ Chattable = StopPollConfig{}
_ Chattable = UnbanChatMemberConfig{} _ Chattable = UnbanChatMemberConfig{}
_ Chattable = UnpinChatMessageConfig{} _ Chattable = UnpinChatMessageConfig{}
_ Chattable = UpdateConfig{} _ Chattable = UpdateConfig{}