Skip to content

Commit 9fc294a

Browse files
authored
Merge pull request #65 from eastrocky/api-4-7
Support Telegram Bot API 4.7
2 parents 8e5f4d6 + a2aa6b5 commit 9fc294a

File tree

4 files changed

+126
-8
lines changed

4 files changed

+126
-8
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
## Features
66

7-
- Full Telegram Bot API **4.6** support
7+
- Full Telegram Bot API **4.7** support
88
- **Zero** dependency
99
- Type-safe API client with functional options
1010
- Capture messages by regexp

client.go

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,32 @@ func (c *Client) AnswerCallbackQuery(callbackQueryID string, opts ...sendOption)
12991299
return c.doRequest("answerCallbackQuery", req, &success)
13001300
}
13011301

1302+
// BotCommand represents a bot command.
1303+
type BotCommand struct {
1304+
Command string `json:"command"` // Text of the command, 1-32 characters. Can contain only lowercase English letters, digits and underscores.
1305+
Description string `json:"description"` // Description of the command, 3-256 characters.
1306+
}
1307+
1308+
/*
1309+
GetMyCommands get the current list of bot commands.
1310+
*/
1311+
func (c *Client) GetMyCommands() (*[]BotCommand, error) {
1312+
botCommands := &[]BotCommand{}
1313+
err := c.doRequest("getMyCommands", url.Values{}, botCommands)
1314+
return botCommands, err
1315+
}
1316+
1317+
/*
1318+
SetMyCommands set the list of bot commands.
1319+
*/
1320+
func (c *Client) SetMyCommands(commands []BotCommand) error {
1321+
req := url.Values{}
1322+
cmd, _ := json.Marshal(commands)
1323+
req.Set("commands", string(cmd))
1324+
var set bool
1325+
return c.doRequest("setMyCommands", url.Values{}, set)
1326+
}
1327+
13021328
/*
13031329
EditMessageText edit text and game messages sent by the bot. Available options:
13041330
- OptParseModeHTML
@@ -1461,11 +1487,12 @@ func (c *Client) SendSticker(chatID, fileID string, opts ...sendOption) (*Messag
14611487

14621488
// StickerSet represents sticker set
14631489
type StickerSet struct {
1464-
Name string `json:"name"`
1465-
Title string `json:"title"`
1466-
IsAnimated bool `json:"is_animated"`
1467-
ContainsMasks bool `json:"contains_masks"`
1468-
Stickers []Sticker `json:"stickers"`
1490+
Name string `json:"name"`
1491+
Title string `json:"title"`
1492+
IsAnimated bool `json:"is_animated"`
1493+
ContainsMasks bool `json:"contains_masks"`
1494+
Stickers []Sticker `json:"stickers"`
1495+
Thumb *PhotoSize `json:"thumb"`
14691496
}
14701497

14711498
/*
@@ -1501,12 +1528,16 @@ var (
15011528
v.Set("mask_position", string(p))
15021529
}
15031530
}
1531+
OptAnimatedSticker = func(v url.Values) {
1532+
v.Set("tgs_sticker", "true")
1533+
}
15041534
)
15051535

15061536
/*
15071537
CreateNewStickerSetFile creates new sticker set with sticker file. Available options:
15081538
- OptContainsMasks
15091539
- OptMaskPosition(pos *MaskPosition)
1540+
- OptAnimatedSticker
15101541
*/
15111542
func (c *Client) CreateNewStickerSetFile(userID int, name, title, stickerFilename, emojis string, opts ...sendOption) error {
15121543
req := url.Values{}
@@ -1517,8 +1548,15 @@ func (c *Client) CreateNewStickerSetFile(userID int, name, title, stickerFilenam
15171548
for _, opt := range opts {
15181549
opt(req)
15191550
}
1551+
stickerFile := inputFile{name: stickerFilename}
1552+
if len(req.Get("tgs_sticker")) > 0 {
1553+
stickerFile.field = "tgs_sticker"
1554+
req.Del("tgs_sticker")
1555+
} else {
1556+
stickerFile.field = "png_sticker"
1557+
}
15201558
var created bool
1521-
return c.doRequestWithFiles("createNewStickerSet", req, &created, inputFile{field: "png_sticker", name: stickerFilename})
1559+
return c.doRequestWithFiles("createNewStickerSet", req, &created, stickerFile)
15221560
}
15231561

15241562
/*
@@ -1543,6 +1581,7 @@ func (c *Client) CreateNewStickerSet(userID int, name, title, fileID, emojis str
15431581
/*
15441582
AddStickerToSetFile add a new sticker file to a set created by the bot. Available options:
15451583
- OptMaskPosition(pos *MaskPosition)
1584+
- OptAnimatedSticker
15461585
*/
15471586
func (c *Client) AddStickerToSetFile(userID int, name, filename, emojis string, opts ...sendOption) error {
15481587
req := url.Values{}
@@ -1552,8 +1591,15 @@ func (c *Client) AddStickerToSetFile(userID int, name, filename, emojis string,
15521591
for _, opt := range opts {
15531592
opt(req)
15541593
}
1594+
stickerFile := inputFile{name: filename}
1595+
if len(req.Get("tgs_sticker")) > 0 {
1596+
stickerFile.field = "tgs_sticker"
1597+
req.Del("tgs_sticker")
1598+
} else {
1599+
stickerFile.field = "png_sticker"
1600+
}
15551601
var added bool
1556-
return c.doRequestWithFiles("addStickerToSet", req, &added, inputFile{field: "png_sticker", name: filename})
1602+
return c.doRequestWithFiles("addStickerToSet", req, &added, stickerFile)
15571603
}
15581604

15591605
/*
@@ -1594,6 +1640,29 @@ func (c *Client) DeleteStickerFromSet(fileID string) error {
15941640
return c.doRequest("deleteStickerFromSet", req, &deleted)
15951641
}
15961642

1643+
/*
1644+
SetStickerSetThumb sets the thumbnail of a sticker set with a previously uploaded file.
1645+
*/
1646+
func (c *Client) SetStickerSetThumb(userID int, name, thumb string) error {
1647+
req := url.Values{}
1648+
req.Set("user_id", fmt.Sprint(userID))
1649+
req.Set("name", name)
1650+
req.Set("thumb", thumb)
1651+
var set bool
1652+
return c.doRequest("setStickerSetThumb", req, &set)
1653+
}
1654+
1655+
/*
1656+
SetStickerSetThumbFile sets the thumbnail of a sticker set with thumbnail file.
1657+
*/
1658+
func (c *Client) SetStickerSetThumbFile(userID int, name, thumbnailFilename string) error {
1659+
req := url.Values{}
1660+
req.Set("user_id", fmt.Sprint(userID))
1661+
req.Set("name", name)
1662+
var set bool
1663+
return c.doRequestWithFiles("setStickerSetThumb", req, &set, inputFile{field: "thumb", name: thumbnailFilename})
1664+
}
1665+
15971666
// InputMessageContent content of a message to be sent as a result of an inline query
15981667
type InputMessageContent interface {
15991668
inputMessageContent()
@@ -2410,6 +2479,29 @@ func (c *Client) SendPoll(chatID string, question string, options []string, opts
24102479
return msg, err
24112480
}
24122481

2482+
/*
2483+
SendDice sends native telegram dice. Available Options:
2484+
- OptDisableNotification
2485+
- OptReplyToMessageID(id int)
2486+
- OptInlineKeyboardMarkup(markup *InlineKeyboardMarkup)
2487+
- OptReplyKeyboardMarkup(markup *ReplyKeyboardMarkup)
2488+
- OptReplyKeyboardRemove
2489+
- OptReplyKeyboardRemoveSelective
2490+
- OptForceReply
2491+
- OptForceReplySelective
2492+
*/
2493+
func (c *Client) SendDice(chatID string, emoji string, opts ...sendOption) (*Dice, error) {
2494+
req := url.Values{}
2495+
req.Set("chat_id", chatID)
2496+
req.Set("emoji", emoji)
2497+
for _, opt := range opts {
2498+
opt(req)
2499+
}
2500+
dice := &Dice{}
2501+
err := c.doRequest("sendDice", req, dice)
2502+
return dice, err
2503+
}
2504+
24132505
/*
24142506
StopPoll stops poll. Available Options:
24152507
- OptInlineKeyboardMarkup(markup *InlineKeyboardMarkup)

client_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,25 @@ func TestSendPhotoFile(t *testing.T) {
158158
}
159159
}
160160

161+
func TestSendDice(t *testing.T) {
162+
c := testClient(t, `
163+
{
164+
"ok": true,
165+
"result": {
166+
"emoji": "🎲",
167+
"value": 6
168+
}
169+
}
170+
`)
171+
msg, err := c.SendDice("123", "🎲")
172+
if err != nil {
173+
t.Fatalf("error on sendDice: %v", err)
174+
}
175+
if msg.Value == 0 {
176+
t.Fatalf("empty dice value")
177+
}
178+
}
179+
161180
func testClient(t *testing.T, resp string) *tbot.Client {
162181
t.Helper()
163182
handler := func(w http.ResponseWriter, r *http.Request) {

updates.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ type Message struct {
298298
Location *Location `json:"location"`
299299
Venue *Venue `json:"venue"`
300300
Poll *Poll `json:"poll"`
301+
Dice *Dice `json:"dice"`
301302
NewChatMembers []*User `json:"new_chat_members"`
302303
LeftChatMember *User `json:"left_chat_member"`
303304
NewChatTitle string `json:"new_chat_title"`
@@ -430,6 +431,12 @@ type Poll struct {
430431
CorrectOptionID int `json:"correct_option_id"`
431432
}
432433

434+
// Dice represents native telegram dice
435+
type Dice struct {
436+
Emoji string `json:"emoji"`
437+
Value int `json:"value"`
438+
}
439+
433440
// PollOption is an option for Poll
434441
type PollOption struct {
435442
Text string `json:"text"`

0 commit comments

Comments
 (0)