diff --git a/bot.go b/bot.go index bba77fa..115435a 100644 --- a/bot.go +++ b/bot.go @@ -271,11 +271,11 @@ func (b *Bot) NewLongPollingChannel(params *GetUpdates) UpdatesChannel { } for _, update := range updates { - if update.UpdateID < params.Offset { + if update.ID < params.Offset { continue } - params.Offset = update.UpdateID + 1 + params.Offset = update.ID + 1 b.Updates <- update } } diff --git a/const.go b/const.go index c3dcb2e..819eed8 100644 --- a/const.go +++ b/const.go @@ -1,9 +1,7 @@ package telegram -import "github.com/Masterminds/semver" - // Version represents current version of Telegram API supported by this package -var Version = semver.MustParse("4.9.0") //nolint: gochecknoglobals +const Version = "5.0.0" // Action represents available and supported status actions of bot const ( @@ -27,7 +25,8 @@ const ( ChatSuperGroup string = "supergroup" ) -// Command represents global commands which should be supported by any bot. You can user IsCommandEqual method of Message for checking. +// Command represents global commands which should be supported by any bot. You can user IsCommandEqual method of +// Message for checking. // // See: https://core.telegram.org/bots#global-commands const ( @@ -62,6 +61,8 @@ const ( MethodAnswerInlineQuery string = "answerInlineQuery" MethodAnswerPreCheckoutQuery string = "answerPreCheckoutQuery" MethodAnswerShippingQuery string = "answerShippingQuery" + MethodClose string = "close" + MethodCopyMessage string = "copyMessage" MethodCreateNewStickerSet string = "createNewStickerSet" MethodDeleteChatPhoto string = "deleteChatPhoto" MethodDeleteChatStickerSet string = "deleteChatStickerSet" @@ -89,6 +90,7 @@ const ( MethodGetWebhookInfo string = "getWebhookInfo" MethodKickChatMember string = "kickChatMember" MethodLeaveChat string = "leaveChat" + MethodLogOut string = "logOut" MethodPinChatMessage string = "pinChatMessage" MethodPromoteChatMember string = "promoteChatMember" MethodRestrictChatMember string = "restrictChatMember" @@ -125,6 +127,7 @@ const ( MethodStopMessageLiveLocation string = "stopMessageLiveLocation" MethodStopPoll string = "stopPoll" MethodUnbanChatMember string = "unbanChatMember" + MethodUnpinAllChatMessages string = "unpinAllChatMessages" MethodUnpinChatMessage string = "unpinChatMessage" MethodUploadStickerFile string = "uploadStickerFile" ) @@ -228,7 +231,16 @@ const ( // Emoji represents emoji supported by SendDice method const ( - EmojiGameDie string = "🎲" - EmojiDart string = "🎯" - EmojiBasketball string = "🏀" + EmojiBasketball string = "🏀" // 1-5 + EmojiDart string = "🎯" // 1-6 + EmojiGameDie string = "🎲" // 1-6 + EmojiSlotMachine string = "🎰" // 1-64 + EmojiSoccer string = "⚽" // 1-5 +) + +const ( + // FromAnonymous is a User ID for messages from anonymous group administrators. + FromAnonymous int = 1087968824 // @GroupAnonymousBot + // FromForwarder is a User ID for messages automatically forwarded to the discussion group. + FromForwarder int = 777000 ) diff --git a/games.go b/games.go index dbb1689..3c6b3c7 100644 --- a/games.go +++ b/games.go @@ -1,7 +1,8 @@ package telegram type ( - // Game represents a game. Use BotFather to create and edit games, their short names will act as unique identifiers. + // Game represents a game. Use BotFather to create and edit games, their short names will act as unique + // identifiers. Game struct { // Title of the game Title string `json:"title"` @@ -9,7 +10,9 @@ type ( // Description of the game Description string `json:"description"` - // Brief description of the game or high scores included in the game message. Can be automatically edited to include current high scores for the game when the bot calls setGameScore, or manually edited using editMessageText. 0-4096 characters. + // Brief description of the game or high scores included in the game message. Can be automatically + // edited to include current high scores for the game when the bot calls setGameScore, or manually + // edited using editMessageText. 0-4096 characters. Text string `json:"text,omitempty"` // Photo that will be displayed in the game message in chats. @@ -42,7 +45,8 @@ type ( // Unique identifier for the target chat ChatID int64 `json:"chat_id"` - // Short name of the game, serves as the unique identifier for the game. Set up your games via Botfather. + // Short name of the game, serves as the unique identifier for the game. Set up your games via + // BotFather. GameShortName string `json:"game_short_name"` // Sends the message silently. Users will receive a notification with no sound. @@ -51,7 +55,11 @@ type ( // If the message is a reply, ID of the original message. ReplyToMessageID int `json:"reply_to_message_id,omitempty"` - // A JSON-serialized object for an inline keyboard. If empty, one ‘Play game_title’ button will be shown. If not empty, the first button must launch the game. + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + + // A JSON-serialized object for an inline keyboard. If empty, one ‘Play game_title’ button will be + // shown. If not empty, the first button must launch the game. ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` } @@ -66,7 +74,8 @@ type ( // Required if inline_message_id is not specified. Identifier of the sent message MessageID int `json:"message_id,omitempty"` - // Pass True, if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters + // Pass True, if the high score is allowed to decrease. This can be useful when fixing mistakes or + // banning cheaters Force bool `json:"force,omitempty"` // Pass True, if the game message should not be automatically edited to include the current scoreboard @@ -124,7 +133,9 @@ func NewGameScore(userID int, score int) SetGameScore { } } -// SetGameScore set the score of the specified user in a game. On success, if the message was sent by the bot, returns the edited Message, otherwise returns True. Returns an error, if the new score is not greater than the user's current score in the chat and force is False. +// SetGameScore set the score of the specified user in a game. On success, if the message was sent by the bot, returns +// the edited Message, otherwise returns True. Returns an error, if the new score is not greater than the user's +// current score in the chat and force is False. func (b Bot) SetGameScore(p SetGameScore) (*Message, error) { src, err := b.Do(MethodSetGameScore, p) if err != nil { @@ -139,7 +150,8 @@ func (b Bot) SetGameScore(p SetGameScore) (*Message, error) { return result, nil } -// GetGameHighScores get data for high score tables. Will return the score of the specified user and several of his neighbors in a game. On success, returns an Array of GameHighScore objects. +// GetGameHighScores get data for high score tables. Will return the score of the specified user and several of his +// neighbors in a game. On success, returns an Array of GameHighScore objects. func (b Bot) GetGameHighScores(p GetGameHighScores) ([]*GameHighScore, error) { src, err := b.Do(MethodGetGameHighScores, p) if err != nil { diff --git a/go.mod b/go.mod index b2d026b..b6ea3aa 100644 --- a/go.mod +++ b/go.mod @@ -3,15 +3,16 @@ module gitlab.com/toby3d/telegram go 1.12 require ( - github.com/Masterminds/semver v1.5.0 + github.com/andybalholm/brotli v1.0.1 // indirect github.com/fasthttp/router v1.3.2 - github.com/json-iterator/go v1.1.9 + github.com/json-iterator/go v1.1.10 github.com/kirillDanshin/dlog v0.0.0-20170728000807-97d876b12bf9 github.com/kirillDanshin/myutils v0.0.0-20160713214838-182269b1fbcc // indirect + github.com/klauspost/compress v1.11.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.1 // indirect github.com/stretchr/testify v1.3.0 - github.com/valyala/fasthttp v1.16.0 - golang.org/x/text v0.3.2 - golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 + github.com/valyala/fasthttp v1.17.0 + golang.org/x/text v0.3.4 + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ) diff --git a/go.sum b/go.sum index fe9d54d..b630dec 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= +github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -9,14 +9,16 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/fasthttp/router v1.3.2 h1:n9r5QNuJi5z5Sp2vp/0SrawogTjGfYFqTOyP/R8ehNI= github.com/fasthttp/router v1.3.2/go.mod h1:athTSKMdel0Qhh3W4nB8qn+EPYuyj6YZMUo6ZcXWTgc= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/kirillDanshin/dlog v0.0.0-20170728000807-97d876b12bf9 h1:mA7k8E2Vrmyj5CW/D1XZBFmohVNi7jf757vibGwzRbo= github.com/kirillDanshin/dlog v0.0.0-20170728000807-97d876b12bf9/go.mod h1:l8CN7iyX1k2xlsTYVTpCtwBPcxThf/jLWDGVcF6T/bM= github.com/kirillDanshin/myutils v0.0.0-20160713214838-182269b1fbcc h1:OkOhOn3WBUmfATC1NsA3rBlgHGkjk0KGnR5akl/8uXc= github.com/kirillDanshin/myutils v0.0.0-20160713214838-182269b1fbcc/go.mod h1:Bt95qRxLvpdmASW9s2tTxGdQ5ma4o4n8QFhCvzCew/M= github.com/klauspost/compress v1.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqybrAg= github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ= +github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -34,15 +36,24 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.16.0 h1:9zAqOYLl8Tuy3E5R6ckzGDJ1g8+pw15oQp2iL9Jl6gQ= github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= +github.com/valyala/fasthttp v1.17.0 h1:P8/koH4aSnJ4xbd0cUUFEGQs3jQqIxoDDyRQrUiAkqg= +github.com/valyala/fasthttp v1.17.0/go.mod h1:jjraHZVbKOXftJfsOYoAjaeygpj5hr8ermTRJNroD7A= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/inline.go b/inline.go index 1ff0d42..141ca76 100644 --- a/inline.go +++ b/inline.go @@ -1,7 +1,8 @@ package telegram type ( - // InlineQuery represents an incoming inline query. When the user sends an empty query, your bot could return some default or trending results. + // InlineQuery represents an incoming inline query. When the user sends an empty query, your bot could return + // some default or trending results. InlineQuery struct { // Unique identifier for this query ID string `json:"id"` @@ -60,7 +61,9 @@ type ( ThumbHeight int `json:"thumb_height,omitempty"` } - // InlineQueryResultPhoto represents a link to a photo. By default, this photo will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the photo. + // InlineQueryResultPhoto represents a link to a photo. By default, this photo will be sent by the user with + // optional caption. Alternatively, you can use input_message_content to send a message with the specified + // content instead of the photo. InlineQueryResultPhoto struct { // Type of the result, must be photo Type string `json:"type"` @@ -74,6 +77,12 @@ type ( // URL of the thumbnail for the photo ThumbURL string `json:"thumb_url"` + // Width of the photo + PhotoWidth int `json:"photo_width,omitempty"` + + // Height of the photo + PhotoHeight int `json:"photo_height,omitempty"` + // Title for the result Title string `json:"title,omitempty"` @@ -83,14 +92,12 @@ type ( // Caption of the photo to be sent, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` - // Width of the photo - PhotoWidth int `json:"photo_width,omitempty"` - - // Height of the photo - PhotoHeight int `json:"photo_height,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` @@ -99,7 +106,9 @@ type ( InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultGif represents a link to an animated GIF file. By default, this animated GIF file will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation. + // InlineQueryResultGif represents a link to an animated GIF file. By default, this animated GIF file will be + // sent by the user with optional caption. Alternatively, you can use input_message_content to send a message + // with the specified content instead of the animation. InlineQueryResultGif struct { // Type of the result, must be gif Type string `json:"type"` @@ -110,6 +119,15 @@ type ( // A valid URL for the GIF file. File size must not exceed 1MB GifURL string `json:"gif_url"` + // Width of the GIF + GifWidth int `json:"gif_width,omitempty"` + + // Height of the GIF + GifHeight int `json:"gif_height,omitempty"` + + // Duration of the GIF + GifDuration int `json:"gif_duration,omitempty"` + // URL of the static thumbnail for the result (jpeg or gif) ThumbURL string `json:"thumb_url"` @@ -123,17 +141,12 @@ type ( // Caption of the GIF file to be sent, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` - // Width of the GIF - GifWidth int `json:"gif_width,omitempty"` - - // Height of the GIF - GifHeight int `json:"gif_height,omitempty"` - - // Duration of the GIF - GifDuration int `json:"gif_duration,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` @@ -142,7 +155,9 @@ type ( InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultMpeg4Gif represents a link to a video animation (H.264/MPEG-4 AVC video without sound). By default, this animated MPEG-4 file will be sent by the user with optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation. + // InlineQueryResultMpeg4Gif represents a link to a video animation (H.264/MPEG-4 AVC video without sound). By + // default, this animated MPEG-4 file will be sent by the user with optional caption. Alternatively, you can + // use input_message_content to send a message with the specified content instead of the animation. InlineQueryResultMpeg4Gif struct { // Type of the result, must be mpeg4_gif Type string `json:"type"` @@ -153,6 +168,15 @@ type ( // A valid URL for the MP4 file. File size must not exceed 1MB Mpeg4URL string `json:"mpeg4_url"` + // Video width + Mpeg4Width int `json:"mpeg4_width,omitempty"` + + // Video height + Mpeg4Height int `json:"mpeg4_height,omitempty"` + + // Video duration + Mpeg4Duration int `json:"mpeg4_duration,omitempty"` + // URL of the static thumbnail (jpeg or gif) for the result ThumbURL string `json:"thumb_url"` @@ -166,18 +190,12 @@ type ( // Caption of the MPEG-4 file to be sent, 0-200 characters Caption string `json:"caption,omitempty"` - // Video width - Mpeg4Width int `json:"mpeg4_width,omitempty"` - - // Video height - Mpeg4Height int `json:"mpeg4_height,omitempty"` - - // Video duration - Mpeg4Duration int `json:"mpeg4_duration,omitempty"` - // Mode for parsing entities in the caption. See formatting options for more details. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` @@ -185,9 +203,12 @@ type ( InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultVideo represents a link to a page containing an embedded video player or a video file. By default, this video file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the video. + // InlineQueryResultVideo represents a link to a page containing an embedded video player or a video file. + // By default, this video file will be sent by the user with an optional caption. Alternatively, you can use + // input_message_content to send a message with the specified content instead of the video. // - // If an InlineQueryResultVideo message contains an embedded video (e.g., YouTube), you must replace its content using input_message_content. + // If an InlineQueryResultVideo message contains an embedded video (e.g., YouTube), you must replace its + // content using input_message_content. InlineQueryResultVideo struct { // Type of the result, must be video Type string `json:"type"` @@ -210,11 +231,12 @@ type ( // Caption of the video to be sent, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` - // Short description of the result - Description string `json:"description,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` // Video width VideoWidth int `json:"video_width,omitempty"` @@ -225,14 +247,20 @@ type ( // Video duration in seconds VideoDuration int `json:"video_duration,omitempty"` + // Short description of the result + Description string `json:"description,omitempty"` + // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` - // Content of the message to be sent instead of the video. This field is required if InlineQueryResultVideo is used to send an HTML-page as a result (e.g., a YouTube video). + // Content of the message to be sent instead of the video. This field is required if + // InlineQueryResultVideo is used to send an HTML-page as a result (e.g., a YouTube video). InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultAudio represents a link to an mp3 audio file. By default, this audio file will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the audio. + // InlineQueryResultAudio represents a link to an mp3 audio file. By default, this audio file will be sent by + // the user. Alternatively, you can use input_message_content to send a message with the specified content + // instead of the audio. InlineQueryResultAudio struct { // Type of the result, must be audio Type string `json:"type"` @@ -249,9 +277,13 @@ type ( // Caption, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Performer Performer string `json:"performer,omitempty"` @@ -265,7 +297,9 @@ type ( InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultVoice represents a link to a voice recording in an .ogg container encoded with OPUS. By default, this voice recording will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the the voice message. + // InlineQueryResultVoice represents a link to a voice recording in an .ogg container encoded with OPUS. + // By default, this voice recording will be sent by the user. Alternatively, you can use input_message_content + // to send a message with the specified content instead of the the voice message. InlineQueryResultVoice struct { // Type of the result, must be voice Type string `json:"type"` @@ -282,9 +316,13 @@ type ( // Caption, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Recording duration in seconds VoiceDuration int `json:"voice_duration,omitempty"` @@ -295,7 +333,9 @@ type ( InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultDocument represents a link to a file. By default, this file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the file. Currently, only .PDF and .ZIP files can be sent using this method. + // InlineQueryResultDocument represents a link to a file. By default, this file will be sent by the user with + // an optional caption. Alternatively, you can use input_message_content to send a message with the specified + // content instead of the file. Currently, only .PDF and .ZIP files can be sent using this method. InlineQueryResultDocument struct { // Type of the result, must be document Type string `json:"type"` @@ -309,9 +349,13 @@ type ( // Caption of the document to be sent, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // A valid URL for the file DocumentURL string `json:"document_url"` @@ -337,7 +381,9 @@ type ( ThumbHeight int `json:"thumb_height,omitempty"` } - // InlineQueryResultLocation represents a location on a map. By default, the location will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the location. + // InlineQueryResultLocation represents a location on a map. By default, the location will be sent by the + // user. Alternatively, you can use input_message_content to send a message with the specified content instead + // of the location. InlineQueryResultLocation struct { // Type of the result, must be location Type string `json:"type"` @@ -345,24 +391,38 @@ type ( // Unique identifier for this result, 1-64 Bytes ID string `json:"id"` - // Location title - Title string `json:"title"` - - // Url of the thumbnail for the result - ThumbURL string `json:"thumb_url,omitempty"` - // Location latitude in degrees Latitude float32 `json:"latitude"` // Location longitude in degrees Longitude float32 `json:"longitude"` + // Location title + Title string `json:"title"` + + // The radius of uncertainty for the location, measured in meters; 0-1500 + HorizontalAccuracy float32 `json:"horizontal_accuracy,omitempty"` + + // Period in seconds for which the location can be updated, should be between 60 and 86400. + LivePeriod int `json:"live_period,omitempty"` + + // For live locations, a direction in which the user is moving, in degrees. Must be between 1 and 360 + // if specified. + Heading int `json:"heading,omitempty"` + + // For live locations, a maximum distance for proximity alerts about approaching another chat member, + // in meters. Must be between 1 and 100000 if specified. + ProximityAlertRadius int `json:"proximity_alert_radius,omitempty"` + // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` // Content of the message to be sent instead of the location InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` + // Url of the thumbnail for the result + ThumbURL string `json:"thumb_url,omitempty"` + // Thumbnail width ThumbWidth int `json:"thumb_width,omitempty"` @@ -370,7 +430,8 @@ type ( ThumbHeight int `json:"thumb_height,omitempty"` } - // InlineQueryResultVenue represents a venue. By default, the venue will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the venue. + // InlineQueryResultVenue represents a venue. By default, the venue will be sent by the user. Alternatively, + // you can use input_message_content to send a message with the specified content instead of the venue. InlineQueryResultVenue struct { // Type of the result, must be venue Type string `json:"type"` @@ -378,6 +439,12 @@ type ( // Unique identifier for this result, 1-64 Bytes ID string `json:"id"` + // Latitude of the venue location in degrees + Latitude float32 `json:"latitude"` + + // Longitude of the venue location in degrees + Longitude float32 `json:"longitude"` + // Title of the venue Title string `json:"title"` @@ -387,17 +454,15 @@ type ( // Foursquare identifier of the venue if known FoursquareID string `json:"foursquare_id,omitempty"` - // Foursquare type of the venue, if known. (For example, "arts_entertainment/default", "arts_entertainment/aquarium" or "food/icecream".) + // Foursquare type of the venue, if known. (For example, "arts_entertainment/default", + // "arts_entertainment/aquarium" or "food/icecream".) FoursquareType string `json:"foursquare_type,omitempty"` - // Url of the thumbnail for the result - ThumbURL string `json:"thumb_url,omitempty"` + // Google Places identifier of the venue + GooglePlaceID string `json:"google_place_id,omitempty"` - // Latitude of the venue location in degrees - Latitude float32 `json:"latitude"` - - // Longitude of the venue location in degrees - Longitude float32 `json:"longitude"` + // Google Places type of the venue. + GooglePlaceType string `json:"google_place_type,omitempty"` // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` @@ -405,6 +470,9 @@ type ( // Content of the message to be sent instead of the venue InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` + // Url of the thumbnail for the result + ThumbURL string `json:"thumb_url,omitempty"` + // Thumbnail width ThumbWidth int `json:"thumb_width,omitempty"` @@ -412,7 +480,9 @@ type ( ThumbHeight int `json:"thumb_height,omitempty"` } - // InlineQueryResultContact represents a contact with a phone number. By default, this contact will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the contact. + // InlineQueryResultContact represents a contact with a phone number. By default, this contact will be sent by + // the user. Alternatively, you can use input_message_content to send a message with the specified content + // instead of the contact. InlineQueryResultContact struct { // Type of the result, must be contact Type string `json:"type"` @@ -463,7 +533,9 @@ type ( ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` } - // InlineQueryResultCachedPhoto represents a link to a photo stored on the Telegram servers. By default, this photo will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the photo. + // InlineQueryResultCachedPhoto represents a link to a photo stored on the Telegram servers. By default, this + // photo will be sent by the user with an optional caption. Alternatively, you can use input_message_content + // to send a message with the specified content instead of the photo. InlineQueryResultCachedPhoto struct { // Type of the result, must be photo Type string `json:"type"` @@ -483,9 +555,13 @@ type ( // Caption of the photo to be sent, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` @@ -493,7 +569,9 @@ type ( InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultCachedGif represents a link to an animated GIF file stored on the Telegram servers. By default, this animated GIF file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with specified content instead of the animation. + // InlineQueryResultCachedGif represents a link to an animated GIF file stored on the Telegram servers. + // By default, this animated GIF file will be sent by the user with an optional caption. Alternatively, you + // can use input_message_content to send a message with specified content instead of the animation. InlineQueryResultCachedGif struct { // Type of the result, must be gif Type string `json:"type"` @@ -510,9 +588,13 @@ type ( // Caption of the GIF file to be sent, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` @@ -520,7 +602,10 @@ type ( InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultCachedMpeg4Gif represents a link to a video animation (H.264/MPEG-4 AVC video without sound) stored on the Telegram servers. By default, this animated MPEG-4 file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the animation. + // InlineQueryResultCachedMpeg4Gif represents a link to a video animation (H.264/MPEG-4 AVC video without + // sound) stored on the Telegram servers. By default, this animated MPEG-4 file will be sent by the user with + // an optional caption. Alternatively, you can use input_message_content to send a message with the specified + // content instead of the animation. InlineQueryResultCachedMpeg4Gif struct { // Type of the result, must be mpeg4_gif Type string `json:"type"` @@ -537,9 +622,13 @@ type ( // Caption of the MPEG-4 file to be sent, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` @@ -547,7 +636,9 @@ type ( InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultCachedSticker represents a link to a sticker stored on the Telegram servers. By default, this sticker will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the sticker. + // InlineQueryResultCachedSticker represents a link to a sticker stored on the Telegram servers. By default, + // this sticker will be sent by the user. Alternatively, you can use input_message_content to send a message + // with the specified content instead of the sticker. InlineQueryResultCachedSticker struct { // Type of the result, must be sticker Type string `json:"type"` @@ -565,7 +656,9 @@ type ( InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultCachedDocument represents a link to a file stored on the Telegram servers. By default, this file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the file. + // InlineQueryResultCachedDocument represents a link to a file stored on the Telegram servers. By default, + // this file will be sent by the user with an optional caption. Alternatively, you can use + // input_message_content to send a message with the specified content instead of the file. InlineQueryResultCachedDocument struct { // Type of the result, must be document Type string `json:"type"` @@ -585,9 +678,13 @@ type ( // Caption of the document to be sent, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` @@ -595,7 +692,9 @@ type ( InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultCachedVideo represents a link to a video file stored on the Telegram servers. By default, this video file will be sent by the user with an optional caption. Alternatively, you can use input_message_content to send a message with the specified content instead of the video. + // InlineQueryResultCachedVideo represents a link to a video file stored on the Telegram servers. By default, + // this video file will be sent by the user with an optional caption. Alternatively, you can use + // input_message_content to send a message with the specified content instead of the video. InlineQueryResultCachedVideo struct { // Type of the result, must be video Type string `json:"type"` @@ -615,9 +714,13 @@ type ( // Caption of the video to be sent, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` @@ -625,7 +728,9 @@ type ( InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultCachedVoice represents a link to a voice message stored on the Telegram servers. By default, this voice message will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the voice message. + // InlineQueryResultCachedVoice represents a link to a voice message stored on the Telegram servers. By + // default, this voice message will be sent by the user. Alternatively, you can use input_message_content to + // send a message with the specified content instead of the voice message. InlineQueryResultCachedVoice struct { // Type of the result, must be voice Type string `json:"type"` @@ -642,9 +747,13 @@ type ( // Caption, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` @@ -652,7 +761,9 @@ type ( InputMessageContent InputMessageContent `json:"input_message_content,omitempty"` } - // InlineQueryResultCachedAudio represents a link to an mp3 audio file stored on the Telegram servers. By default, this audio file will be sent by the user. Alternatively, you can use input_message_content to send a message with the specified content instead of the audio. + // InlineQueryResultCachedAudio represents a link to an mp3 audio file stored on the Telegram servers. By + // default, this audio file will be sent by the user. Alternatively, you can use input_message_content to send + // a message with the specified content instead of the audio. InlineQueryResultCachedAudio struct { // Type of the result, must be audio Type string `json:"type"` @@ -666,9 +777,13 @@ type ( // Caption, 0-200 characters Caption string `json:"caption,omitempty"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Inline keyboard attached to the message ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` @@ -681,19 +796,25 @@ type ( isInputMessageContent() } - // InputTextMessageContent represents the content of a text message to be sent as the result of an inline query. + // InputTextMessageContent represents the content of a text message to be sent as the result of an inline + // query. InputTextMessageContent struct { // Text of the message to be sent, 1-4096 characters MessageText string `json:"message_text"` - // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. + // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline + // URLs in your bot's message. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Disables link previews for links in the sent message DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"` } - // InputLocationMessageContent represents the content of a location message to be sent as the result of an inline query. + // InputLocationMessageContent represents the content of a location message to be sent as the result of an + // inline query. InputLocationMessageContent struct { // Latitude of the location in degrees Latitude float32 `json:"latitude"` @@ -701,11 +822,23 @@ type ( // Longitude of the location in degrees Longitude float32 `json:"longitude"` + // The radius of uncertainty for the location, measured in meters; 0-1500 + HorizontalAccuracy float32 `json:"horizontal_accuracy,omitempty"` + // Period in seconds for which the location can be updated, should be between 60 and 86400. LivePeriod int `json:"live_period,omitempty"` + + // For live locations, a direction in which the user is moving, in degrees. Must be between 1 and 360 + // if specified. + Heading int `json:"heading,omitempty"` + + // For live locations, a maximum distance for proximity alerts about approaching another chat member, + // in meters. Must be between 1 and 100000 if specified. + ProximityAlertRadius int `json:"proximity_alert_radius,omitempty"` } - // InputVenueMessageContent represents the content of a venue message to be sent as the result of an inline query. + // InputVenueMessageContent represents the content of a venue message to be sent as the result of an inline + // query. InputVenueMessageContent struct { // Latitude of the location in degrees Latitude float32 `json:"latitude"` @@ -722,11 +855,19 @@ type ( // Foursquare identifier of the venue, if known FoursquareID string `json:"foursquare_id,omitempty"` - // Foursquare type of the venue, if known. (For example, "arts_entertainment/default", "arts_entertainment/aquarium" or "food/icecream".) + // Foursquare type of the venue, if known. (For example, "arts_entertainment/default", + // "arts_entertainment/aquarium" or "food/icecream".) FoursquareType string `json:"foursquare_type,omitempty"` + + // Google Places identifier of the venue + GooglePlaceId string `json:"google_place_id,omitempty"` + + // Google Places type of the venue. + GooglePlaceType string `json:"google_place_type,omitempty"` } - // InputContactMessageContent represents the content of a contact message to be sent as the result of an inline query. + // InputContactMessageContent represents the content of a contact message to be sent as the result of an + // inline query. InputContactMessageContent struct { // Contact's phone number PhoneNumber string `json:"phone_number"` @@ -741,12 +882,14 @@ type ( VCard string `json:"vcard,omitempty"` } - // ChosenInlineResult represents a result of an inline query that was chosen by the user and sent to their chat partner. + // ChosenInlineResult represents a result of an inline query that was chosen by the user and sent to their + // chat partner. ChosenInlineResult struct { // The unique identifier for the result that was chosen ResultID string `json:"result_id"` - // Identifier of the sent inline message. Available only if there is an inline keyboard attached to the message. Will be also received in callback queries and can be used to edit the message. + // Identifier of the sent inline message. Available only if there is an inline keyboard attached to + // the message. Will be also received in callback queries and can be used to edit the message. InlineMessageID string `json:"inline_message_id,omitempty"` // The query that was used to obtain the result @@ -764,22 +907,28 @@ type ( // Unique identifier for the answered query InlineQueryID string `json:"inline_query_id"` - // Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are no more results or if you don‘t support pagination. Offset length can’t exceed 64 bytes. + // Pass the offset that a client should send in the next query with the same text to receive more + // results. Pass an empty string if there are no more results or if you don‘t support pagination. + // Offset length can’t exceed 64 bytes. NextOffset string `json:"next_offset,omitempty"` - // If passed, clients will display a button with specified text that switches the user to a private chat with the bot and sends the bot a start message with the parameter switch_pm_parameter + // If passed, clients will display a button with specified text that switches the user to a private + // chat with the bot and sends the bot a start message with the parameter switch_pm_parameter SwitchPrivateMessageText string `json:"switch_pm_text,omitempty"` - // Deep-linking parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed. + // Deep-linking parameter for the /start message sent to the bot when user presses the switch button. + // 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed. SwitchPrivateMessageParameter string `json:"switch_pm_parameter,omitempty"` // A JSON-serialized array of results for the inline query Results []InlineQueryResult `json:"results"` - // The maximum amount of time in seconds that the result of the inline query may be cached on the server. Defaults to 300. + // The maximum amount of time in seconds that the result of the inline query may be cached on the + // server. Defaults to 300. CacheTime int `json:"cache_time,omitempty"` - // Pass True, if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query + // Pass True, if results may be cached on the server side only for the user that sent the query. By + // default, results may be returned to any user who sends the same query IsPersonal bool `json:"is_personal,omitempty"` } diff --git a/methods.go b/methods.go index 3f647b1..772ecf9 100644 --- a/methods.go +++ b/methods.go @@ -8,8 +8,7 @@ import ( type ( // SendMessage represents data for SendMessage method. SendMessage struct { - // Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Text of the message to be sent Text string `json:"text"` @@ -17,6 +16,9 @@ type ( // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + Entities []*MessageEntity `json:"entities,omitempty"` + // Disables link previews for links in this message DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"` @@ -26,17 +28,19 @@ type ( // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } // ForwardMessage represents data for ForwardMessage method. ForwardMessage struct { - // Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Unique identifier for the chat where the original message was sent (or channel username in the format @channelusername) - FromChatID int64 `json:"from_chat_id"` + FromChatID ChatID `json:"from_chat_id"` // Sends the message silently. Users will receive a notification with no sound. DisableNotification bool `json:"disable_notification,omitempty"` @@ -45,10 +49,44 @@ type ( MessageID int `json:"message_id"` } + // CopyMessage represents data for CopyMessage method. + CopyMessage struct { + ChatID ChatID `json:"chat_id"` + + // Unique identifier for the chat where the original message was sent + FromChatID ChatID `json:"from_chat_id"` + + // Message identifier in the chat specified in from_chat_id + MessageID int `json:"message_id"` + + // New caption for media, 0-1024 characters after entities parsing. If not specified, the original + // caption is kept + Caption string `json:"caption,omitempty"` + + // Mode for parsing entities in the new caption. See formatting options for more details. + ParseMode string `json:"parse_mode,omitempty"` + + // List of special entities that appear in the new caption, which can be specified instead of + // parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + + // Sends the message silently. Users will receive a notification with no sound. + DisableNotification bool `json:"disable_notification,omitempty"` + + // If the message is a reply, ID of the original message + ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + + // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply + // keyboard, instructions to remove reply keyboard or to force a reply from the user. + ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` + } + // SendPhoto represents data for SendPhoto method. SendPhoto struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Photo to send. Pass a file_id as String to send a photo that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a photo from the Internet, or upload a new photo using multipart/form-data. Photo *InputFile `json:"photo"` @@ -59,8 +97,8 @@ type ( // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` - // Disables link previews for links in this message - DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` // Sends the message silently. Users will receive a notification with no sound. DisableNotification bool `json:"disable_notification,omitempty"` @@ -68,14 +106,16 @@ type ( // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } - // SendAudio represents data for SendVenue method. + // SendAudio represents data for SendAudio method. SendAudio struct { - // Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Audio file to send. Pass a file_id as String to send an audio file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get an audio file from the Internet, or upload a new one using multipart/form-data. Audio *InputFile `json:"audio"` @@ -86,6 +126,9 @@ type ( // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Duration of the audio in seconds Duration int `json:"duration,omitempty"` @@ -104,38 +147,56 @@ type ( // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } // SendDocument represents data for SendDocument method. SendDocument struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // File to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. Document *InputFile `json:"document"` + // Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported + // server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's + // width and height should not exceed 320. Ignored if the file is not uploaded using + // multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can + // pass “attach://” if the thumbnail was uploaded using multipart/form-data under + // . + Thumb *InputFile `json:"thumb,omitempty"` + // Document caption (may also be used when resending documents by file_id), 0-200 characters Caption string `json:"caption,omitempty"` // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + + // Disables automatic server-side content type detection for files uploaded using multipart/form-data + DisableContentTypeDetection bool `json:"disable_content_type_detection,omitempty"` + // Sends the message silently. Users will receive a notification with no sound. DisableNotification bool `json:"disable_notification,omitempty"` // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } // SendDocument represents data for SendVideo method. SendVideo struct { - // Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Video to send. Pass a file_id as String to send a video that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a video from the Internet, or upload a new video using multipart/form-data. Video *InputFile `json:"video"` @@ -158,6 +219,9 @@ type ( // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Pass True, if the uploaded video is suitable for streaming SupportsStreaming bool `json:"supports_streaming,omitempty"` @@ -167,14 +231,16 @@ type ( // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } // SendAnimation represents data for SendAnimation method. SendAnimation struct { - // Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Animation to send. Pass a file_id as String to send an animation that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get an animation from the Internet, or upload a new animation using multipart/form-data. Animation *InputFile `json:"animation"` @@ -197,20 +263,25 @@ type ( // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Sends the message silently. Users will receive a notification with no sound. DisableNotification bool `json:"disable_notification,omitempty"` // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } // SendVoice represents data for SendVoice method. SendVoice struct { - // Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Audio file to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. Voice *InputFile `json:"voice"` @@ -221,6 +292,9 @@ type ( // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Duration of the voice message in seconds Duration int `json:"duration,omitempty"` @@ -230,14 +304,16 @@ type ( // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } // SendVideoNote represents data for SendVideoNote method. SendVideoNote struct { - // Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Video note to send. Pass a file_id as String to send a video note that exists on the Telegram servers (recommended) or upload a new video using multipart/form-data.. Sending video notes by a URL is currently unsupported VideoNote *InputFile `json:"video_note"` @@ -257,14 +333,16 @@ type ( // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } // SendMediaGroup represents data for SendMediaGroup method. SendMediaGroup struct { - // Unique identifier for the target chat. - ChatID int64 `json:"chat_id" form:"chat_id"` + ChatID ChatID `json:"chat_id" form:"chat_id"` // A JSON-serialized array describing photos and videos to be sent, must include 2–10 items Media []AlbumMedia `json:"media" form:"media"` @@ -274,12 +352,14 @@ type ( // If the messages are a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty" form:"reply_to_message_id"` + + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty" form:"reply_to_message_id"` } // SendLocation represents data for SendLocation method. SendLocation struct { - // Unique identifier for the target private chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Latitude of the location Latitude float32 `json:"latitude"` @@ -287,23 +367,38 @@ type ( // Longitude of the location Longitude float32 `json:"longitude"` - // Period in seconds for which the location will be updated (see Live Locations), should be between 60 and 86400. + // The radius of uncertainty for the location, measured in meters; 0-1500 + HorizontalAccuracy float32 `json:"horizontal_accuracy,omitempty"` + + // Period in seconds for which the location will be updated (see Live Locations), should be between 60 + // and 86400. LivePeriod int `json:"live_period,omitempty"` - // If the message is a reply, ID of the original message - ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // For live locations, a direction in which the user is moving, in degrees. Must be between 1 and 360 + // if specified. + Heading int `json:"heading,omitempty"` + + // For live locations, a maximum distance for proximity alerts about approaching another chat member, + // in meters. Must be between 1 and 100000 if specified. + ProximityAlertRadius int `json:"proximity_alert_radius,omitempty"` // Sends the message silently. Users will receive a notification with no sound. DisableNotification bool `json:"disable_notification,omitempty"` - // A JSON-serialized object for an inline keyboard. If empty, one 'Pay total price' button will be shown. If not empty, the first button must be a Pay button. + // If the message is a reply, ID of the original message + ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + + // A JSON-serialized object for an inline keyboard. If empty, one 'Pay total price' button will be + // shown. If not empty, the first button must be a Pay button. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } // EditMessageLiveLocation represents data for EditMessageLiveLocation method. EditMessageLiveLocation struct { - // Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id,omitempty"` + ChatID ChatID `json:"chat_id,omitempty"` // Required if inline_message_id is not specified. Identifier of the sent message MessageID int `json:"message_id,omitempty"` @@ -317,14 +412,23 @@ type ( // Longitude of new location Longitude float32 `json:"longitude"` + // The radius of uncertainty for the location, measured in meters; 0-1500 + HorizontalAccuracy float32 `json:"horizontal_accuracy,omitempty"` + + // Direction in which the user is moving, in degrees. Must be between 1 and 360 if specified. + Heading int `json:"heading,omitempty"` + + // Maximum distance for proximity alerts about approaching another chat member, in meters. Must be + // between 1 and 100000 if specified. + ProximityAlertRadius int `json:"proximity_alert_radius,omitempty"` + // A JSON-serialized object for a new inline keyboard. - ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` + ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` } // StopMessageLiveLocation represents data for StopMessageLiveLocation method. StopMessageLiveLocation struct { - // Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id,omitempty"` + ChatID ChatID `json:"chat_id,omitempty"` // Required if inline_message_id is not specified. Identifier of the message with live location to stop MessageID int `json:"message_id,omitempty"` @@ -338,8 +442,7 @@ type ( // SendVenue represents data for SendVenue method. SendVenue struct { - // Unique identifier for the target private chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Latitude of the venue Latitude float32 `json:"latitude"` @@ -356,23 +459,32 @@ type ( // Foursquare identifier of the venue FoursquareID string `json:"foursquare_id,omitempty"` - // Foursquare type of the venue, if known. (For example, "arts_entertainment/default", "arts_entertainment/aquarium" or "food/icecream".) + // Foursquare type of the venue, if known. (For example, "arts_entertainment/default", + // "arts_entertainment/aquarium" or "food/icecream".) FoursquareType string `json:"foursquare_type,omitempty"` + // Google Places identifier of the venue + GooglePlaceID string `json:"google_place_id,omitempty"` + + // Google Places type of the venue. + GooglePlaceType string `json:"google_place_type,omitempty"` + // Sends the message silently. Users will receive a notification with no sound. DisableNotification bool `json:"disable_notification,omitempty"` // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // A JSON-serialized object for an inline keyboard. If empty, one 'Pay total price' button will be shown. If not empty, the first button must be a Pay button. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } // SendContact represents data for SendContact method. SendContact struct { - // Unique identifier for the target private chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Contact's phone number PhoneNumber string `json:"phone_number"` @@ -392,16 +504,18 @@ type ( // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // A JSON-serialized object for an inline keyboard. If empty, one 'Pay total price' button will be shown. If not empty, the first button must be a Pay button. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } // SendPoll represents data for SendPoll method. SendPoll struct { - // Unique identifier for the target chat. A native poll can't be sent to a private chat. - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` - // Poll question, 1-255 characters + // Poll question, 1-300 characters Question string `json:"question"` // List of answer options, 2-10 strings 1-100 characters each @@ -426,6 +540,9 @@ type ( // Mode for parsing entities in the explanation. See formatting options for more details. ExplanationParseMode string `json:"explanation_parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + ExplanationEntities []*MessageEntity `json:"explanation_entities,omitempty"` + // Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with close_date. OpenPeriod int `json:"open_period,omitempty"` @@ -441,17 +558,20 @@ type ( // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } // SendDice represents data for SendDice method. SendDice struct { - // Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` - // Emoji on which the dice throw animation is based. Currently, must be one of “🎲” or “🎯”. Defauts to - // “🎲” + // 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 `json:"emoji,omitempty"` // Sends the message silently. Users will receive a notification with no sound. @@ -460,14 +580,16 @@ type ( // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } // SendChatAction represents data for SendChat method. SendChatAction struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Type of action to broadcast Action string `json:"action"` @@ -493,8 +615,7 @@ type ( // KickChatMember represents data for KickChatMember method. KickChatMember struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Unique identifier of the target user UserID int `json:"user_id"` @@ -505,16 +626,18 @@ type ( // UnbanChatMember represents data for UnbanChatMember method. UnbanChatMember struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` + // Unique identifier of the target user UserID int `json:"user_id"` + + // Do nothing if the user is not banned + OnlyIfBanned bool `json:"only_if_banned,omitempty"` } // RestrictChatMember represents data for RestrictChatMember method. RestrictChatMember struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Unique identifier of the target user UserID int `json:"user_id"` @@ -528,12 +651,14 @@ type ( // PromoteChatMember represents data for PromoteChatMember method. PromoteChatMember struct { - // Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Unique identifier of the target user UserID int `json:"user_id"` + // Pass True, if the administrator's presence in the chat is hidden + IsAnonymous bool `json:"is_anonymous,omitempty"` + // Pass True, if the administrator can change chat title, photo and other settings CanChangeInfo bool `json:"can_change_info,omitempty"` @@ -555,14 +680,15 @@ type ( // Pass True, if the administrator can pin messages, supergroups only CanPinMessages bool `json:"can_pin_messages,omitempty"` - // Pass True, if the administrator can add new administrators with a subset of his own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him) + // Pass True, if the administrator can add new administrators with a subset of his own privileges or + // demote administrators that he has promoted, directly or indirectly (promoted by administrators that + // were appointed by him) CanPromoteMembers bool `json:"can_promote_members,omitempty"` } // SetChatAdministratorCustomTitle represents data for SetChatAdministratorCustomTitle method. SetChatAdministratorCustomTitle struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Unique identifier of the target user UserID int `json:"user_id"` @@ -573,8 +699,7 @@ type ( // SetChatPermissions represents data for SetChatPermissions method. SetChatPermissions struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // New default chat permissions Permissions ChatPermissions `json:"permissions"` @@ -582,14 +707,12 @@ type ( // ExportChatInviteLink represents data for ExportChatInviteLink method. ExportChatInviteLink struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` } // SetChatPhoto represents data for SetChatPhoto method. SetChatPhoto struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // New chat photo, uploaded using multipart/form-data ChatPhoto InputFile `json:"chat_photo"` @@ -597,14 +720,12 @@ type ( // DeleteChatPhoto represents data for DeleteChatPhoto method. DeleteChatPhoto struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` } // SetChatTitle represents data for SetChatTitle method. SetChatTitle struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // New chat title, 1-255 characters Title string `json:"title"` @@ -612,8 +733,7 @@ type ( // SetChatDescription represents data for SetChatDescription method. SetChatDescription struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // New chat description, 0-255 characters Description string `json:"description"` @@ -621,8 +741,7 @@ type ( // PinChatMessage represents data for PinChatMessage method. PinChatMessage struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Identifier of a message to pin MessageID int `json:"message_id"` @@ -633,38 +752,41 @@ type ( // UnpinChatMessage represents data for UnpinChatMessage method. UnpinChatMessage struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` + + // Identifier of a message to unpin. If not specified, the most recent pinned message (by sending + // date) will be unpinned. + MessageID int `json:"messge_id,omitempty"` + } + + // UnpinAllChatMessages represents data for UnpinAllChatMessages method. + UnpinAllChatMessages struct { + ChatID ChatID `json:"chat_id"` } // LeaveChat represents data for LeaveChat method. LeaveChat struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` } // GetChat represents data for GetChat method. GetChat struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` } // GetChatAdministrators represents data for GetChatAdministrators method. GetChatAdministrators struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` } // GetChatMembersCount represents data for GetChatMembersCount method. GetChatMembersCount struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` } // GetChatMember represents data for GetChatMember method. GetChatMember struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Unique identifier of the target user UserID int `json:"user_id"` @@ -672,8 +794,7 @@ type ( // SetChatStickerSet represents data for SetChatStickerSet method. SetChatStickerSet struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Name of the sticker set to be set as the group sticker set StickerSetName string `json:"sticker_set_name"` @@ -681,8 +802,7 @@ type ( // DeleteChatStickerSet represents data for DeleteChatStickerSet method. DeleteChatStickerSet struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` } // AnswerCallbackQuery represents data for AnswerCallbackQuery method. @@ -728,7 +848,51 @@ func (b Bot) GetMe() (*User, error) { return result, nil } -func NewMessage(chatID int64, text string) SendMessage { +// LogOut method to log out from the cloud Bot API server before launching the bot locally. You must log out the bot +// before running it locally, otherwise there is no guarantee that the bot will receive updates. After a successful +// call, you will not be able to log in again using the same token for 10 minutes. Returns True on success. Requires +// no parameters. +func (b Bot) LogOut() (ok bool, err error) { + src, err := b.Do(MethodLogOut, nil) + if err != nil { + return false, err + } + + resp := new(Response) + if err = b.marshler.Unmarshal(src, resp); err != nil { + return + } + + if err = b.marshler.Unmarshal(resp.Result, &ok); err != nil { + return + } + + return +} + +// Close method to close the bot instance before moving it from one local server to another. You need to delete the +// webhook before calling this method to ensure that the bot isn't launched again after server restart. The method +// will return error 429 in the first 10 minutes after the bot is launched. Returns True on success. Requires no +// parameters. +func (b Bot) Close() (ok bool, err error) { + src, err := b.Do(MethodClose, nil) + if err != nil { + return false, err + } + + resp := new(Response) + if err = b.marshler.Unmarshal(src, resp); err != nil { + return + } + + if err = b.marshler.Unmarshal(resp.Result, &ok); err != nil { + return + } + + return +} + +func NewMessage(chatID ChatID, text string) SendMessage { return SendMessage{ ChatID: chatID, Text: text, @@ -750,7 +914,7 @@ func (b Bot) SendMessage(p SendMessage) (*Message, error) { return result, nil } -func NewForward(fromChatID, toChatID int64, messageID int) ForwardMessage { +func NewForward(fromChatID, toChatID ChatID, messageID int) ForwardMessage { return ForwardMessage{ FromChatID: fromChatID, ChatID: toChatID, @@ -773,7 +937,23 @@ func (b Bot) ForwardMessage(p ForwardMessage) (*Message, error) { return result, err } -func NewPhoto(chatID int64, photo *InputFile) SendPhoto { +// CopyMessage copy messages of any kind. The method is analogous to the method forwardMessages, but the copied +// message doesn't have a link to the original message. Returns the MessageId of the sent message on success. +func (b Bot) CopyMessage(p CopyMessage) (*MessageID, error) { + src, err := b.Do(MethodCopyMessage, p) + if err != nil { + return nil, err + } + + result := new(MessageID) + if err = parseResponseError(b.marshler, src, result); err != nil { + return nil, err + } + + return result, err +} + +func NewPhoto(chatID ChatID, photo *InputFile) SendPhoto { return SendPhoto{ ChatID: chatID, Photo: photo, @@ -783,10 +963,10 @@ func NewPhoto(chatID int64, photo *InputFile) SendPhoto { // SendPhoto send photos. On success, the sent Message is returned. func (b Bot) SendPhoto(p SendPhoto) (*Message, error) { params := make(map[string]string) - params["chat_id"] = strconv.FormatInt(p.ChatID, 10) + params["chat_id"] = p.ChatID.String() params["caption"] = p.Caption params["parse_mode"] = p.ParseMode - params["disable_web_page_preview"] = strconv.FormatBool(p.DisableWebPagePreview) + params["allow_sending_without_reply"] = strconv.FormatBool(p.AllowSendingWithoutReply) params["disable_notification"] = strconv.FormatBool(p.DisableNotification) params["reply_to_message_id"] = strconv.Itoa(p.ReplyToMessageID) @@ -817,7 +997,7 @@ func (b Bot) SendPhoto(p SendPhoto) (*Message, error) { return result, nil } -func NewAudio(chatID int64, audio *InputFile) SendAudio { +func NewAudio(chatID ChatID, audio *InputFile) SendAudio { return SendAudio{ ChatID: chatID, Audio: audio, @@ -829,7 +1009,7 @@ func NewAudio(chatID int64, audio *InputFile) SendAudio { // For sending voice messages, use the sendVoice method instead. func (b Bot) SendAudio(p SendAudio) (*Message, error) { params := make(map[string]string) - params["chat_id"] = strconv.FormatInt(p.ChatID, 10) + params["chat_id"] = p.ChatID.String() params["caption"] = p.Caption params["parse_mode"] = p.ParseMode params["duration"] = strconv.Itoa(p.Duration) @@ -873,7 +1053,7 @@ func (b Bot) SendAudio(p SendAudio) (*Message, error) { return result, nil } -func NewDocument(chatID int64, document *InputFile) SendDocument { +func NewDocument(chatID ChatID, document *InputFile) SendDocument { return SendDocument{ ChatID: chatID, Document: document, @@ -883,7 +1063,7 @@ func NewDocument(chatID int64, document *InputFile) SendDocument { // SendDocument send general files. On success, the sent Message is returned. Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future. func (b Bot) SendDocument(p SendDocument) (*Message, error) { params := make(map[string]string) - params["chat_id"] = strconv.FormatInt(p.ChatID, 10) + params["chat_id"] = p.ChatID.String() params["caption"] = p.Caption params["parse_mode"] = p.ParseMode params["disable_notification"] = strconv.FormatBool(p.DisableNotification) @@ -916,7 +1096,7 @@ func (b Bot) SendDocument(p SendDocument) (*Message, error) { return result, nil } -func NewVideo(chatID int64, video *InputFile) SendVideo { +func NewVideo(chatID ChatID, video *InputFile) SendVideo { return SendVideo{ ChatID: chatID, Video: video, @@ -926,7 +1106,7 @@ func NewVideo(chatID int64, video *InputFile) SendVideo { // SendVideo send video files, Telegram clients support mp4 videos (other formats may be sent as Document). On success, the sent Message is returned. Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future. func (b Bot) SendVideo(p SendVideo) (*Message, error) { params := make(map[string]string) - params["chat_id"] = strconv.FormatInt(p.ChatID, 10) + params["chat_id"] = p.ChatID.String() params["duration"] = strconv.Itoa(p.Duration) params["width"] = strconv.Itoa(p.Width) params["height"] = strconv.Itoa(p.Height) @@ -971,7 +1151,7 @@ func (b Bot) SendVideo(p SendVideo) (*Message, error) { return result, nil } -func NewAnimation(chatID int64, animation *InputFile) SendAnimation { +func NewAnimation(chatID ChatID, animation *InputFile) SendAnimation { return SendAnimation{ ChatID: chatID, Animation: animation, @@ -981,7 +1161,7 @@ func NewAnimation(chatID int64, animation *InputFile) SendAnimation { // SendAnimation send animation files (GIF or H.264/MPEG-4 AVC video without sound). On success, the sent Message is returned. Bots can currently send animation files of up to 50 MB in size, this limit may be changed in the future. func (b Bot) SendAnimation(p SendAnimation) (*Message, error) { params := make(map[string]string) - params["chat_id"] = strconv.FormatInt(p.ChatID, 10) + params["chat_id"] = p.ChatID.String() params["duration"] = strconv.Itoa(p.Duration) params["width"] = strconv.Itoa(p.Width) params["height"] = strconv.Itoa(p.Height) @@ -1025,7 +1205,7 @@ func (b Bot) SendAnimation(p SendAnimation) (*Message, error) { return result, nil } -func NewVoice(chatID int64, voice *InputFile) SendVoice { +func NewVoice(chatID ChatID, voice *InputFile) SendVoice { return SendVoice{ ChatID: chatID, Voice: voice, @@ -1035,7 +1215,7 @@ func NewVoice(chatID int64, voice *InputFile) SendVoice { // SendVoice send audio files, if you want Telegram clients to display the file as a playable voice message. For this to work, your audio must be in an .ogg file encoded with OPUS (other formats may be sent as Audio or Document). On success, the sent Message is returned. Bots can currently send voice messages of up to 50 MB in size, this limit may be changed in the future. func (b Bot) SendVoice(p SendVoice) (*Message, error) { params := make(map[string]string) - params["chat_id"] = strconv.FormatInt(p.ChatID, 10) + params["chat_id"] = p.ChatID.String() params["duration"] = strconv.Itoa(p.Duration) params["caption"] = p.Caption params["parse_mode"] = p.ParseMode @@ -1069,7 +1249,7 @@ func (b Bot) SendVoice(p SendVoice) (*Message, error) { return result, nil } -func NewVideoNote(chatID int64, videoNote *InputFile) SendVideoNote { +func NewVideoNote(chatID ChatID, videoNote *InputFile) SendVideoNote { return SendVideoNote{ ChatID: chatID, VideoNote: videoNote, @@ -1079,7 +1259,7 @@ func NewVideoNote(chatID int64, videoNote *InputFile) SendVideoNote { // SendVideoNote send video messages. On success, the sent Message is returned. func (b Bot) SendVideoNote(p SendVideoNote) (*Message, error) { params := make(map[string]string) - params["chat_id"] = strconv.FormatInt(p.ChatID, 10) + params["chat_id"] = p.ChatID.String() params["duration"] = strconv.Itoa(p.Duration) params["length"] = strconv.Itoa(p.Length) params["disable_notification"] = strconv.FormatBool(p.DisableNotification) @@ -1120,7 +1300,7 @@ func (b Bot) SendVideoNote(p SendVideoNote) (*Message, error) { return result, nil } -func NewMediaGroup(chatID int64, media ...AlbumMedia) SendMediaGroup { +func NewMediaGroup(chatID ChatID, media ...AlbumMedia) SendMediaGroup { return SendMediaGroup{ ChatID: chatID, Media: media, @@ -1148,7 +1328,7 @@ func (b Bot) SendMediaGroup(p SendMediaGroup) ([]*Message, error) { } params := make(map[string]string) - params["chat_id"] = strconv.FormatInt(p.ChatID, 10) + params["chat_id"] = p.ChatID.String() params["disable_notification"] = strconv.FormatBool(p.DisableNotification) params["reply_to_message_id"] = strconv.Itoa(p.ReplyToMessageID) params["media"] = "[" + strings.Join(media, ",") + "]" @@ -1166,7 +1346,7 @@ func (b Bot) SendMediaGroup(p SendMediaGroup) ([]*Message, error) { return result, nil } -func NewLocation(chatID int64, latitude, longitude float32) SendLocation { +func NewLocation(chatID ChatID, latitude, longitude float32) SendLocation { return SendLocation{ ChatID: chatID, Latitude: latitude, @@ -1226,7 +1406,7 @@ func (b Bot) StopMessageLiveLocation(p StopMessageLiveLocation) (*Message, error return result, nil } -func NewVenue(chatID int64, latitude, longitude float32, title, address string) SendVenue { +func NewVenue(chatID ChatID, latitude, longitude float32, title, address string) SendVenue { return SendVenue{ ChatID: chatID, Latitude: latitude, @@ -1251,7 +1431,7 @@ func (b Bot) SendVenue(p SendVenue) (*Message, error) { return result, nil } -func NewContact(chatID int64, phoneNumber, firstName string) SendContact { +func NewContact(chatID ChatID, phoneNumber, firstName string) SendContact { return SendContact{ ChatID: chatID, PhoneNumber: phoneNumber, @@ -1274,7 +1454,7 @@ func (b Bot) SendContact(p SendContact) (*Message, error) { return result, nil } -func NewPoll(chatID int64, question string, options ...string) SendPoll { +func NewPoll(chatID ChatID, question string, options ...string) SendPoll { return SendPoll{ ChatID: chatID, Question: question, @@ -1317,8 +1497,8 @@ func (b Bot) SendDice(p SendDice) (*Message, error) { // SendChatAction tell the user that something is happening on the bot's side. The status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear its typing status). Returns True on success. // // We only recommend using this method when a response from the bot will take a noticeable amount of time to arrive. -func (b Bot) SendChatAction(cid int64, action string) (ok bool, err error) { - src, err := b.Do(MethodSendChatAction, SendChatAction{ChatID: cid, Action: action}) +func (b Bot) SendChatAction(p SendChatAction) (ok bool, err error) { + src, err := b.Do(MethodSendChatAction, p) if err != nil { return ok, err } @@ -1367,7 +1547,7 @@ func (b Bot) GetFile(fid string) (*File, error) { return result, nil } -func NewKick(chatID int64, userID int) KickChatMember { +func NewKick(chatID ChatID, userID int) KickChatMember { return KickChatMember{ ChatID: chatID, UserID: userID, @@ -1396,8 +1576,8 @@ func (b Bot) KickChatMember(p KickChatMember) (ok bool, err error) { } // UnbanChatMember unban a previously kicked user in a supergroup or channel. The user will not return to the group or channel automatically, but will be able to join via link, etc. The bot must be an administrator for this to work. Returns True on success. -func (b Bot) UnbanChatMember(cid int64, uid int) (ok bool, err error) { - src, err := b.Do(MethodUnbanChatMember, UnbanChatMember{ChatID: cid, UserID: uid}) +func (b Bot) UnbanChatMember(p UnbanChatMember) (ok bool, err error) { + src, err := b.Do(MethodUnbanChatMember, p) if err != nil { return ok, err } @@ -1414,7 +1594,7 @@ func (b Bot) UnbanChatMember(cid int64, uid int) (ok bool, err error) { return } -func NewRestrict(chatID int64, userID int, permissions ChatPermissions) RestrictChatMember { +func NewRestrict(chatID ChatID, userID int, permissions ChatPermissions) RestrictChatMember { return RestrictChatMember{ ChatID: chatID, UserID: userID, @@ -1441,7 +1621,7 @@ func (b Bot) RestrictChatMember(p RestrictChatMember) (ok bool, err error) { return } -func NewPromote(chatID int64, userID int) PromoteChatMember { +func NewPromote(chatID ChatID, userID int) PromoteChatMember { return PromoteChatMember{ ChatID: chatID, UserID: userID, @@ -1506,8 +1686,8 @@ func (b Bot) SetChatPermissions(p SetChatPermissions) (ok bool, err error) { } // ExportChatInviteLink export an invite link to a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns exported invite link as String on success. -func (b Bot) ExportChatInviteLink(cid int64) (string, error) { - src, err := b.Do(MethodExportChatInviteLink, ExportChatInviteLink{ChatID: cid}) +func (b Bot) ExportChatInviteLink(p ExportChatInviteLink) (string, error) { + src, err := b.Do(MethodExportChatInviteLink, p) if err != nil { return "", err } @@ -1557,8 +1737,8 @@ func (b Bot) SetChatPhoto(cid int64, photo *InputFile) (ok bool, err error) { } // DeleteChatPhoto delete a chat photo. Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns True on success. -func (b Bot) DeleteChatPhoto(cid int64) (ok bool, err error) { - src, err := b.Do(MethodDeleteChatPhoto, DeleteChatPhoto{ChatID: cid}) +func (b Bot) DeleteChatPhoto(p DeleteChatPhoto) (ok bool, err error) { + src, err := b.Do(MethodDeleteChatPhoto, p) if err != nil { return ok, err } @@ -1576,8 +1756,8 @@ func (b Bot) DeleteChatPhoto(cid int64) (ok bool, err error) { } // SetChatTitle change the title of a chat. Titles can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns True on success. -func (b Bot) SetChatTitle(cid int64, title string) (ok bool, err error) { - src, err := b.Do(MethodSetChatTitle, SetChatTitle{ChatID: cid, Title: title}) +func (b Bot) SetChatTitle(p SetChatTitle) (ok bool, err error) { + src, err := b.Do(MethodSetChatTitle, p) if err != nil { return ok, err } @@ -1595,8 +1775,8 @@ func (b Bot) SetChatTitle(cid int64, title string) (ok bool, err error) { } // SetChatDescription change the description of a group, a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns True on success. -func (b Bot) SetChatDescription(cid int64, txt string) (ok bool, err error) { - src, err := b.Do(MethodSetChatDescription, SetChatDescription{ChatID: cid, Description: txt}) +func (b Bot) SetChatDescription(p SetChatDescription) (ok bool, err error) { + src, err := b.Do(MethodSetChatDescription, p) if err != nil { return ok, err } @@ -1613,7 +1793,7 @@ func (b Bot) SetChatDescription(cid int64, txt string) (ok bool, err error) { return } -func NewPin(chatID int64, messageID int) PinChatMessage { +func NewPin(chatID ChatID, messageID int) PinChatMessage { return PinChatMessage{ ChatID: chatID, MessageID: messageID, @@ -1640,8 +1820,29 @@ func (b Bot) PinChatMessage(p PinChatMessage) (ok bool, err error) { } // UnpinChatMessage unpin a message in a group, a supergroup, or a channel. The bot must be an administrator in the chat for this to work and must have the ‘can_pin_messages’ admin right in the supergroup or ‘can_edit_messages’ admin right in the channel. Returns True on success. -func (b Bot) UnpinChatMessage(cid int64) (ok bool, err error) { - src, err := b.Do(MethodUnpinChatMessage, UnpinChatMessage{ChatID: cid}) +func (b Bot) UnpinChatMessage(p UnpinChatMessage) (ok bool, err error) { + src, err := b.Do(MethodUnpinChatMessage, p) + if err != nil { + return ok, err + } + + resp := new(Response) + if err = b.marshler.Unmarshal(src, resp); err != nil { + return + } + + if err = b.marshler.Unmarshal(resp.Result, &ok); err != nil { + return + } + + return +} + +// UnpinChatMessage method to clear the list of pinned messages in a chat. If the chat is not a private chat, the bot +// must be an administrator in the chat for this to work and must have the 'can_pin_messages' admin right in a +// supergroup or 'can_edit_messages' admin right in a channel. Returns True on success. +func (b Bot) UnpinAllChatMessages(p UnpinAllChatMessages) (ok bool, err error) { + src, err := b.Do(MethodUnpinAllChatMessages, p) if err != nil { return ok, err } @@ -1659,8 +1860,8 @@ func (b Bot) UnpinChatMessage(cid int64) (ok bool, err error) { } // LeaveChat leave a group, supergroup or channel. Returns True on success. -func (b Bot) LeaveChat(cid int64) (ok bool, err error) { - src, err := b.Do(MethodLeaveChat, LeaveChat{ChatID: cid}) +func (b Bot) LeaveChat(p LeaveChat) (ok bool, err error) { + src, err := b.Do(MethodLeaveChat, p) if err != nil { return ok, err } @@ -1678,8 +1879,8 @@ func (b Bot) LeaveChat(cid int64) (ok bool, err error) { } // GetChat get up to date information about the chat (current name of the user for one-on-one conversations, current username of a user, group or channel, etc.). Returns a Chat object on success. -func (b Bot) GetChat(cid int64) (*Chat, error) { - src, err := b.Do(MethodGetChat, GetChat{ChatID: cid}) +func (b Bot) GetChat(p GetChat) (*Chat, error) { + src, err := b.Do(MethodGetChat, p) if err != nil { return nil, err } @@ -1693,8 +1894,8 @@ func (b Bot) GetChat(cid int64) (*Chat, error) { } // GetChatAdministrators get a list of administrators in a chat. On success, returns an Array of ChatMember objects that contains information about all chat administrators except other bots. If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned. -func (b Bot) GetChatAdministrators(cid int64) ([]*ChatMember, error) { - src, err := b.Do(MethodGetChatAdministrators, GetChatAdministrators{ChatID: cid}) +func (b Bot) GetChatAdministrators(p GetChatAdministrators) ([]*ChatMember, error) { + src, err := b.Do(MethodGetChatAdministrators, p) if err != nil { return nil, err } @@ -1708,8 +1909,8 @@ func (b Bot) GetChatAdministrators(cid int64) ([]*ChatMember, error) { } // GetChatMembersCount get the number of members in a chat. Returns Int on success. -func (b Bot) GetChatMembersCount(cid int64) (int, error) { - src, err := b.Do(MethodGetChatMembersCount, GetChatMembersCount{ChatID: cid}) +func (b Bot) GetChatMembersCount(p GetChatMembersCount) (int, error) { + src, err := b.Do(MethodGetChatMembersCount, p) if err != nil { return 0, err } @@ -1728,8 +1929,8 @@ func (b Bot) GetChatMembersCount(cid int64) (int, error) { } // GetChatMember get information about a member of a chat. Returns a ChatMember object on success. -func (b Bot) GetChatMember(cid int64, uid int) (*ChatMember, error) { - src, err := b.Do(MethodGetChatMember, GetChatMember{ChatID: cid, UserID: uid}) +func (b Bot) GetChatMember(p GetChatMember) (*ChatMember, error) { + src, err := b.Do(MethodGetChatMember, p) if err != nil { return nil, err } @@ -1743,8 +1944,8 @@ func (b Bot) GetChatMember(cid int64, uid int) (*ChatMember, error) { } // SetChatStickerSet set a new group sticker set for a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Use the field can_set_sticker_set optionally returned in getChat requests to check if the bot can use this method. Returns True on success. -func (b Bot) SetChatStickerSet(cid int64, name string) (ok bool, err error) { - src, err := b.Do(MethodSetChatStickerSet, SetChatStickerSet{ChatID: cid, StickerSetName: name}) +func (b Bot) SetChatStickerSet(p SetChatStickerSet) (ok bool, err error) { + src, err := b.Do(MethodSetChatStickerSet, p) if err != nil { return ok, err } @@ -1762,8 +1963,8 @@ func (b Bot) SetChatStickerSet(cid int64, name string) (ok bool, err error) { } // DeleteChatStickerSet delete a group sticker set from a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Use the field can_set_sticker_set optionally returned in getChat requests to check if the bot can use this method. Returns True on success. -func (b Bot) DeleteChatStickerSet(cid int64) (ok bool, err error) { - src, err := b.Do(MethodDeleteChatStickerSet, DeleteChatStickerSet{ChatID: cid}) +func (b Bot) DeleteChatStickerSet(p DeleteChatStickerSet) (ok bool, err error) { + src, err := b.Do(MethodDeleteChatStickerSet, p) if err != nil { return ok, err } diff --git a/payments.go b/payments.go index fb7b55d..c87d715 100644 --- a/payments.go +++ b/payments.go @@ -202,6 +202,9 @@ type ( // Sends the message silently. Users will receive a notification with no sound. DisableNotification bool `json:"disable_notification,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // A JSON-serialized object for an inline keyboard. If empty, one 'Pay total price' button will be shown. If not empty, the first button must be a Pay button. ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` } diff --git a/stickers.go b/stickers.go index 3ef5a4a..5ac98f8 100644 --- a/stickers.go +++ b/stickers.go @@ -77,8 +77,7 @@ type ( // SendStickerParameters represents data for SetSticker method. SendSticker struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Sticker to send Sticker *InputFile `json:"sticker"` @@ -89,6 +88,9 @@ type ( // If the message is a reply, ID of the original message ReplyToMessageID int `json:"reply_to_message_id,omitempty"` + // Pass True, if the message should be sent even if the specified replied-to message is not found + AllowSendingWithoutReply bool `json:"allow_sending_without_reply,omitempty"` + // Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. ReplyMarkup ReplyMarkup `json:"reply_markup,omitempty"` } @@ -189,7 +191,7 @@ type ( } ) -func NewSticker(chatID int64, sticker *InputFile) SendSticker { +func NewSticker(chatID ChatID, sticker *InputFile) SendSticker { return SendSticker{ ChatID: chatID, Sticker: sticker, diff --git a/types.go b/types.go index 495d0dd..2565ee8 100644 --- a/types.go +++ b/types.go @@ -4,6 +4,7 @@ import ( "encoding/json" "os" "path/filepath" + "strconv" "strings" "time" @@ -12,6 +13,12 @@ import ( ) type ( + // ChatID is a unique identifier for the target chat or username of the target channel + ChatID struct { + ID int64 `json:"-"` + Username string `json:"-"` // @channelUsername + } + // Response represents a response from the Telegram API with the result stored raw. If ok equals true, the request was successful, and the result of the query can be found in the result field. In case of an unsuccessful request, ok equals false, and the error is explained in the error field. Response struct { Description string `json:"description,omitempty"` @@ -104,6 +111,11 @@ type ( // Sender, empty for messages sent to channels From *User `json:"from,omitempty"` + // Sender of the message, sent on behalf of a chat. The channel itself for channel messages. The + // supergroup itself for messages from anonymous group administrators. The linked channel for messages + // automatically forwarded to the discussion group + SenderChat *Chat `json:"sender_chat,omitempty"` + // Date the message was sent in Unix time Date int64 `json:"date"` @@ -149,8 +161,9 @@ type ( // For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text Entities []*MessageEntity `json:"entities,omitempty"` - // For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption - CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Message is an animation, information about the animation. For backward compatibility, when this + // field is set, the document field will also be set + Animation *Animation `json:"animation,omitempty"` // Message is an audio file, information about the file Audio *Audio `json:"audio,omitempty"` @@ -158,12 +171,6 @@ type ( // Message is a general file, information about the file Document *Document `json:"document,omitempty"` - // Message is an animation, information about the animation. For backward compatibility, when this field is set, the document field will also be set - Animation *Animation `json:"animation,omitempty"` - - // Message is a game, information about the game. - Game *Game `json:"game,omitempty"` - // Message is a photo, available sizes of the photo Photo Photo `json:"photo,omitempty"` @@ -173,29 +180,36 @@ type ( // Message is a video, information about the video Video *Video `json:"video,omitempty"` - // Message is a voice message, information about the file - Voice *Voice `json:"voice,omitempty"` - // Message is a video note, information about the video message VideoNote *VideoNote `json:"video_note,omitempty"` + // Message is a voice message, information about the file + Voice *Voice `json:"voice,omitempty"` + // Caption for the document, photo or video, 0-200 characters Caption string `json:"caption,omitempty"` + // For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear + // in the caption + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Message is a shared contact, information about the contact Contact *Contact `json:"contact,omitempty"` - // Message is a shared location, information about the location - Location *Location `json:"location,omitempty"` + // Message is a dice with random value from 1 to 6 + Dice *Dice `json:"dice,omitempty"` - // Message is a venue, information about the venue - Venue *Venue `json:"venue,omitempty"` + // Message is a game, information about the game. + Game *Game `json:"game,omitempty"` // Message is a native poll, information about the poll Poll *Poll `json:"poll,omitempty"` - // Message is a dice with random value from 1 to 6 - Dice *Dice `json:"dice,omitempty"` + // Message is a venue, information about the venue + Venue *Venue `json:"venue,omitempty"` + + // Message is a shared location, information about the location + Location *Location `json:"location,omitempty"` // New members that were added to the group or supergroup and information about them (the bot itself may be one of these members) NewChatMembers []*User `json:"new_chat_members,omitempty"` @@ -242,10 +256,20 @@ type ( // Telegram Passport data PassportData *PassportData `json:"passport_data,omitempty"` + // Service message. A user in the chat triggered another user's proximity alert while sharing Live + // Location. + ProximityAlertTriggered *ProximityAlertTriggered `json:"proximity_alert_triggered,omitempty"` + // Inline keyboard attached to the message. login_url buttons are represented as ordinary url buttons. ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` } + // MessageID represents a unique message identifier. + MessageID struct { + // Unique message identifier + MessageID int `json:"message_id"` + } + // MessageEntity represents one special entity in a text message. For example, hashtags, usernames, URLs, etc. MessageEntity struct { // Type of the entity. Can be mention (@username), hashtag, bot_command, url, email, bold (bold text), italic (italic text), code (monowidth string), pre (monowidth block), text_link (for clickable text URLs), text_mention (for users without usernames) @@ -302,6 +326,9 @@ type ( // Title of the audio as defined by sender or by audio tags Title string `json:"title,omitempty"` + // Original filename as defined by sender + FileName string `json:"file_name,omitempty"` + // MIME type of the file as defined by sender MimeType string `json:"mime_type,omitempty"` @@ -353,6 +380,9 @@ type ( // Video thumbnail Thumb *PhotoSize `json:"thumb,omitempty"` + // Original filename as defined by sender + FileName string `json:"file_name,omitempty"` + // Mime type of a file as defined by sender MimeType string `json:"mime_type,omitempty"` @@ -454,6 +484,20 @@ type ( // Latitude as defined by sender Latitude float32 `json:"latitude"` + + // The radius of uncertainty for the location, measured in meters; 0-1500 + HorizontalAccuracy float32 `json:"horizontal_accuracy,omitempty"` + + // Time relative to the message sending date, during which the location can be updated, in seconds. + // For active live locations only. + LivePeriod int `json:"live_period,omitempty"` // TODO(toby3d): change to time.Duration? + + // The direction in which user is moving, in degrees; 1-360. For active live locations only. + Heading int `json:"heading,omitempty"` + + // Maximum distance for proximity alerts about approaching another chat member, in meters. For sent + // live locations only. + ProximityAlertRadius int `json:"proximity_alert_radius,omitempty"` } // Venue represents a venue. @@ -472,11 +516,17 @@ type ( // Foursquare type of the venue. (For example, "arts_entertainment/default", "arts_entertainment/aquarium" or "food/icecream".) FoursquareType string `json:"foursquare_type,omitempty"` + + // Google Places identifier of the venue + GooglePlaceID string `json:"google_place_id,omitempty"` + + // Google Places type of the venue. + GooglePlaceType string `json:"google_place_type,omitempty"` } // This object contains information about one answer option in a poll. PollOption struct { - // Option text, 1-100 characters + // Option text, 1-300 characters Text string `json:"text"` // Number of users that voted for this option @@ -539,16 +589,29 @@ type ( CloseDate int64 `json:"close_date,omitempty"` } - // Dice represents a dice with random value from 1 to 6 for currently supported base emoji. (Yes, we're aware - // of the “proper” singular of die. But it's awkward, and we decided to help it change. One dice at a time!) + // Dice represents an animated emoji that displays a random value. Dice struct { // Emoji on which the dice throw animation is based Emoji string `json:"emoji"` - // Value of the dice, 1-6 + // Value of the dice, 1-6 for “🎲” and “🎯” base emoji, 1-5 for “🏀” and “⚽” base emoji, 1-64 for + // “🎰” base emoji Value int `json:"value"` } + // ProximityAlertTriggered represents the content of a service message, sent whenever a user in the chat + // triggers a proximity alert set by another user. + ProximityAlertTriggered struct { + // User that triggered the alert + Traveler *User `json:"traveler"` + + // User that set the alert + Watcher *User `json:"watcher"` + + // The distance between the users + Distance int `json:"distance"` + } + // UserProfilePhotos represent a user's profile pictures. UserProfilePhotos struct { // Total number of profile pictures the target user has @@ -746,8 +809,8 @@ type ( // Owner and administrators only. Custom title for this user CustomTitle string `json:"custom_title,omitempty"` - // Restictred and kicked only. Date when restrictions will be lifted for this user, unix time - UntilDate int64 `json:"until_date,omitempty"` + // Owner and administrators only. True, if the user's presence in the chat is hidden + IsAnonymous bool `json:"is_anonymous,omitempty"` // Administrators only. True, if the bot is allowed to edit administrator privileges of that user CanBeEdited bool `json:"can_be_edited,omitempty"` @@ -771,7 +834,11 @@ type ( // Restricted only. True, if the user is a member of the chat at the moment of the request IsMember bool `json:"is_member,omitempty"` + // Actions that a non-administrator user is allowed to take in a chat. ChatPermissions + + // Restictred and kicked only. Date when restrictions will be lifted for this user, unix time + UntilDate int64 `json:"until_date,omitempty"` } // ChatPermissions describes actions that a non-administrator user is allowed to take in a chat. @@ -801,6 +868,15 @@ type ( CanPinMessages bool `json:"can_pin_messages,omitempty"` } + // ChatLocation represents a location to which a chat is connected. + ChatLocation struct { + // The location to which the supergroup is connected. Can't be a live location. + Location Location `json:"location"` + + // Location address; 1-64 characters, as defined by the chat owner + Address string `json:"address"` + } + // BotCommand represents a bot command. BotCommand struct { // Text of the command, 1-32 characters. Can contain only lowercase English letters, digits and @@ -843,6 +919,9 @@ type ( // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` } // InputMediaVideo represents a video to be sent. @@ -853,12 +932,23 @@ type ( // File to send. Pass a file_id to send a file that exists on the Telegram servers (recommended), pass an HTTP URL for Telegram to get a file from the Internet, or pass "attach://" to upload a new one using multipart/form-data under name. Media *InputFile `json:"media"` + // Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported + // server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's + // width and height should not exceed 320. Ignored if the file is not uploaded using + // multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can + // pass “attach://” if the thumbnail was uploaded using multipart/form-data under + // . + Thumb InputFile `json:"thumb,omitempty"` + // Caption of the video to be sent, 0-200 characters Caption string `json:"caption,omitempty"` // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Video width Width int `json:"width,omitempty"` @@ -890,6 +980,9 @@ type ( // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Animation width Width int `json:"width,omitempty"` @@ -917,6 +1010,9 @@ type ( // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // Duration of the audio in seconds Duration int `json:"duration,omitempty"` @@ -943,6 +1039,13 @@ type ( // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + + // Disables automatic server-side content type detection for files uploaded using multipart/form-data. + // Always true, if the document is sent as part of an album. + DisableContentTypeDetection bool `json:"disable_content_type_detection,omitempty"` } // InputFile represents the contents of a file to be uploaded. Must be poste using multipart/form-data in the usual way that files are uploaded via the browser. @@ -984,6 +1087,12 @@ func (u User) HasLastName() bool { return u.LastName != "" } // HaveUsername checks what the current user has a username. func (u User) HasUsername() bool { return u.Username != "" } +// IsAnonymous checks what the current user is a anonymous group admin. +func (u User) IsAnonymous() bool { return u.ID == FromAnonymous } + +// IsChannel checks what the current user is a channel, which message is automatically forwarded to a discussion group. +func (u User) IsForwarder() bool { return u.ID == FromForwarder } + // IsPrivate checks that the current chat is a private chat with single user. func (c Chat) IsPrivate() bool { return strings.EqualFold(c.Type, ChatPrivate) } @@ -1459,8 +1568,12 @@ func (m *InputMediaAnimation) GetMedia() *InputFile { return m.Media } func (m *InputMediaAudio) GetMedia() *InputFile { return m.Media } +func (InputMediaAudio) isAlbumMedia() {} + func (m *InputMediaDocument) GetMedia() *InputFile { return m.Media } +func (InputMediaDocument) isAlbumMedia() {} + func (m *InputMediaPhoto) GetMedia() *InputFile { return m.Media } func (InputMediaPhoto) isAlbumMedia() {} @@ -1475,6 +1588,7 @@ func (f InputFile) IsURI() bool { return f.URI != nil } func (f InputFile) IsAttachment() bool { return f.Attachment != nil } +// MarshalJSON marshals InputFile into single JSON value. func (f InputFile) MarshalJSON() ([]byte, error) { switch { case f.IsFileID(): @@ -1499,4 +1613,28 @@ func (f InputFile) MarshalJSON() ([]byte, error) { } // CloseTime parse CloseDate and returns time.Time. -func (p Poll) CloseTime() time.Time { return time.Unix(p.CloseDate, 0) } +func (p Poll) CloseTime() time.Time { + return time.Unix(p.CloseDate, 0) +} + +// MarshalJSON marshals ChatID into single JSON value. +func (c ChatID) MarshalJSON() ([]byte, error) { + switch { + case c.ID != 0: + return strconv.AppendInt(nil, c.ID, 10), nil + case c.Username != "": + return []byte(c.Username), nil + default: + return nil, nil + } +} + +func (c ChatID) String() string { + if c.ID != 0 { + return strconv.FormatInt(c.ID, 10) + } + + return c.Username +} + +// TODO(toby3d): create method for checking what message from AnonymousGroupBot or this is a auto channel repost diff --git a/types_test.go b/types_test.go index 1596617..f78a94f 100644 --- a/types_test.go +++ b/types_test.go @@ -4,6 +4,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strconv" "testing" "time" @@ -2144,3 +2145,34 @@ func TestPollCloseTime(t *testing.T) { assert.Equal(t, now, p.CloseTime()) } + +func TestChatIDMarshalJSON(t *testing.T) { + for _, tc := range []struct { + name string + input ChatID + expResult []byte + }{{ + name: "chat id", + input: ChatID{ID: 123456}, + expResult: strconv.AppendInt(nil, 123456, 10), + }, { + name: "channel username", + input: ChatID{Username: "@toby3dMe"}, + expResult: []byte("@toby3dMe"), + }, { + name: "prefer id", + input: ChatID{ID: 123456, Username: "@toby3dMe"}, + expResult: strconv.AppendInt(nil, 123456, 10), + }, { + name: "empty", + input: ChatID{}, + expResult: nil, + }} { + tc := tc + t.Run(tc.name, func(t *testing.T) { + result, err := tc.input.MarshalJSON() + assert.NoError(t, err) + assert.Equal(t, tc.expResult, result) + }) + } +} diff --git a/updates.go b/updates.go index 20a28eb..1068358 100644 --- a/updates.go +++ b/updates.go @@ -1,6 +1,7 @@ package telegram import ( + "net" "strconv" "strings" "time" @@ -14,7 +15,7 @@ type ( // At most one of the optional parameters can be present in any given update. Update struct { // The update‘s unique identifier. Update identifiers start from a certain positive number and increase sequentially. This ID becomes especially handy if you’re using Webhooks, since it allows you to ignore repeated updates or to restore the correct update sequence, should they get out of order. - UpdateID int `json:"update_id"` + ID int `json:"update_id"` // New incoming message of any kind — text, photo, sticker, etc. Message *Message `json:"message,omitempty"` @@ -56,15 +57,19 @@ type ( // Webhook URL, may be empty if webhook is not set up URL string `json:"url"` - // Error message in human-readable format for the most recent error that happened when trying to deliver an update via webhook - LastErrorMessage string `json:"last_error_message,omitempty"` - // True, if a custom certificate was provided for webhook certificate checks HasCustomCertificate bool `json:"has_custom_certificate"` // Number of updates awaiting delivery PendingUpdateCount int `json:"pending_update_count"` + // Currently used webhook IP address + IpAddress net.IP `json:"ip_address,omitempty"` + + // Error message in human-readable format for the most recent error that happened when trying to + // deliver an update via webhook + LastErrorMessage string `json:"last_error_message,omitempty"` + // Maximum allowed number of simultaneous HTTPS connections to the webhook for update delivery MaxConnections int `json:"max_connections,omitempty"` @@ -100,6 +105,10 @@ type ( // Upload your public key certificate so that the root certificate in use can be checked. See our self-signed guide for details. Certificate InputFile `json:"certificate,omitempty"` + // The fixed IP address which will be used to send webhook requests instead of the IP address resolved + // through DNS + IpAddress net.IP `json:"ip_address,omitempty"` + // Maximum allowed number of simultaneous HTTPS connections to the webhook for update delivery, 1-100. Defaults to 40. Use lower values to limit the load on your bot‘s server, and higher values to increase your bot’s throughput. MaxConnections int `json:"max_connections,omitempty"` @@ -107,6 +116,14 @@ type ( // // Please note that this parameter doesn't affect updates created before the call to the setWebhook, so unwanted updates may be received for a short period of time. AllowedUpdates []string `json:"allowed_updates,omitempty"` + + // Pass True to drop all pending updates + DropPendingUpdates bool `json:"drop_pending_updates,omitempty"` + } + + DeleteWebhook struct { + // Pass True to drop all pending updates + DropPendingUpdates bool `json:"drop_pending_updates,omitempty"` } // UpdatesChannel represents channel for incoming updates. @@ -134,9 +151,11 @@ func (b Bot) GetUpdates(p *GetUpdates) ([]*Update, error) { func (b Bot) SetWebhook(p SetWebhook) (ok bool, err error) { if p.Certificate.IsAttachment() { _, err := b.Upload(MethodSetWebhook, map[string]string{ - "allowed_updates": strings.Join(p.AllowedUpdates, ","), - "max_connections": strconv.Itoa(p.MaxConnections), - "url": p.URL, + "url": p.URL, + "ip_address": p.IpAddress.String(), + "max_connections": strconv.Itoa(p.MaxConnections), + "allowed_updates": strings.Join(p.AllowedUpdates, ","), + "drop_pending_updates": strconv.FormatBool(p.DropPendingUpdates), }, &p.Certificate) return err == nil, err @@ -155,8 +174,8 @@ func (b Bot) SetWebhook(p SetWebhook) (ok bool, err error) { } // DeleteWebhook remove webhook integration if you decide to switch back to getUpdates. Returns True on success. Requires no parameters. -func (b Bot) DeleteWebhook() (ok bool, err error) { - src, err := b.Do(MethodDeleteWebhook, nil) +func (b Bot) DeleteWebhook(p DeleteWebhook) (ok bool, err error) { + src, err := b.Do(MethodDeleteWebhook, p) if err != nil { return ok, err } diff --git a/updating_messages.go b/updating_messages.go index 72ae0d9..8b99b86 100644 --- a/updating_messages.go +++ b/updating_messages.go @@ -3,8 +3,7 @@ package telegram type ( // EditMessageTextParameters represents data for EditMessageText method. EditMessageText struct { - // Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id,omitempty"` + ChatID ChatID `json:"chat_id,omitempty"` // Required if inline_message_id is not specified. Identifier of the sent message MessageID int `json:"message_id,omitempty"` @@ -18,6 +17,9 @@ type ( // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + Entities []*MessageEntity `json:"entities,omitempty"` + // Disables link previews for links in this message DisableWebPagePreview bool `json:"disable_web_page_preview,omitempty"` @@ -27,8 +29,7 @@ type ( // EditMessageCaptionParameters represents data for EditMessageCaption method. EditMessageCaption struct { - // Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id,omitempty"` + ChatID ChatID `json:"chat_id,omitempty"` // Required if inline_message_id is not specified. Identifier of the sent message MessageID int `json:"message_id,omitempty"` @@ -42,14 +43,16 @@ type ( // Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption. ParseMode string `json:"parse_mode,omitempty"` + // List of special entities that appear in the caption, which can be specified instead of parse_mode + CaptionEntities []*MessageEntity `json:"caption_entities,omitempty"` + // A JSON-serialized object for an inline keyboard. ReplyMarkup *InlineKeyboardMarkup `json:"reply_markup,omitempty"` } // EditMessageMediaParameters represents data for EditMessageMedia method. EditMessageMedia struct { - // Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id,omitempty"` + ChatID ChatID `json:"chat_id,omitempty"` // Required if inline_message_id is not specified. Identifier of the sent message MessageID int `json:"message_id,omitempty"` @@ -66,8 +69,7 @@ type ( // EditMessageReplyMarkupParameters represents data for EditMessageReplyMarkup method. EditMessageReplyMarkup struct { - // Required if inline_message_id is not specified. Unique identifier for the target chat or username of the target channel (in the format @channelusername) - ChatID int64 `json:"chat_id,omitempty"` + ChatID ChatID `json:"chat_id,omitempty"` // Required if inline_message_id is not specified. Identifier of the sent message MessageID int `json:"message_id,omitempty"` @@ -80,8 +82,7 @@ type ( } StopPoll struct { - // Unique identifier for the target chat. A native poll can't be sent to a private chat. - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Identifier of the original message with the poll MessageID int `json:"message_id"` @@ -92,8 +93,7 @@ type ( // DeleteMessageParameters represents data for DeleteMessage method. DeleteMessage struct { - // Unique identifier for the target chat - ChatID int64 `json:"chat_id"` + ChatID ChatID `json:"chat_id"` // Identifier of the message to delete MessageID int `json:"message_id"` @@ -105,7 +105,7 @@ func NewEditText(text string) EditMessageText { } // EditMessageText edit text and game messages sent by the bot or via the bot (for inline bots). On success, if edited message is sent by the bot, the edited Message is returned, otherwise True is returned. -func (b Bot) EditMessageText(p *EditMessageText) (*Message, error) { +func (b Bot) EditMessageText(p EditMessageText) (*Message, error) { src, err := b.Do(MethodEditMessageText, p) if err != nil { return nil, err @@ -120,7 +120,7 @@ func (b Bot) EditMessageText(p *EditMessageText) (*Message, error) { } // EditMessageCaption edit captions of messages sent by the bot or via the bot (for inline bots). On success, if edited message is sent by the bot, the edited Message is returned, otherwise True is returned. -func (b Bot) EditMessageCaption(p *EditMessageCaption) (*Message, error) { +func (b Bot) EditMessageCaption(p EditMessageCaption) (*Message, error) { src, err := b.Do(MethodEditMessageCaption, p) if err != nil { return nil, err @@ -135,7 +135,9 @@ func (b Bot) EditMessageCaption(p *EditMessageCaption) (*Message, error) { } func NewEditMedia(media InputMedia) EditMessageMedia { - return EditMessageMedia{Media: media} + return EditMessageMedia{ + Media: media, + } } // EditMessageMedia edit audio, document, photo, or video messages. If a message is a part of a message album, then it can be edited only to a photo or a video. Otherwise, message type can be changed arbitrarily. When inline message is edited, new file can't be uploaded. Use previously uploaded file via its file_id or specify a URL. On success, if the edited message was sent by the bot, the edited Message is returned, otherwise True is returned. @@ -168,8 +170,11 @@ func (b Bot) EditMessageReplyMarkup(p EditMessageReplyMarkup) (*Message, error) return result, nil } -func NewStopPoll(chatID int64, messageID int) StopPoll { - return StopPoll{ChatID: chatID, MessageID: messageID} +func NewStopPoll(chatID ChatID, messageID int) StopPoll { + return StopPoll{ + ChatID: chatID, + MessageID: messageID, + } } // StopPoll stop a poll which was sent by the bot. On success, the stopped Poll with the final results is returned. @@ -197,8 +202,8 @@ func (b Bot) StopPoll(p StopPoll) (*Poll, error) { // - If the bot has can_delete_messages permission in a supergroup or a channel, it can delete any message there. // // Returns True on success. -func (b Bot) DeleteMessage(cid int64, mid int) (ok bool, err error) { - src, err := b.Do(MethodDeleteMessage, DeleteMessage{ChatID: cid, MessageID: mid}) +func (b Bot) DeleteMessage(p DeleteMessage) (ok bool, err error) { + src, err := b.Do(MethodDeleteMessage, p) if err != nil { return ok, err }