Skip to content

Commit 366879b

Browse files
committed
Merge branch 'master' into develop
1 parent 18c023f commit 366879b

File tree

8 files changed

+2487
-788
lines changed

8 files changed

+2487
-788
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![GoDoc](https://godoc.org/github.com/go-telegram-bot-api/telegram-bot-api?status.svg)](http://godoc.org/github.com/go-telegram-bot-api/telegram-bot-api)
44
[![Travis](https://travis-ci.org/go-telegram-bot-api/telegram-bot-api.svg)](https://travis-ci.org/go-telegram-bot-api/telegram-bot-api)
55

6-
All methods are fairly self explanatory, and reading the godoc page should
6+
All methods are fairly self explanatory, and reading the [godoc](http://godoc.org/github.com/go-telegram-bot-api/telegram-bot-api) page should
77
explain everything. If something isn't clear, open an issue or submit
88
a pull request.
99

bot.go

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,20 @@ import (
1818
"github.com/technoweenie/multipartstreamer"
1919
)
2020

21+
// HTTPClient is the type needed for the bot to perform HTTP requests.
22+
type HTTPClient interface {
23+
Do(req *http.Request) (*http.Response, error)
24+
PostForm(url string, data url.Values) (*http.Response, error)
25+
}
26+
2127
// BotAPI allows you to interact with the Telegram Bot API.
2228
type BotAPI struct {
2329
Token string `json:"token"`
2430
Debug bool `json:"debug"`
2531
Buffer int `json:"buffer"`
2632

27-
Self User `json:"-"`
28-
Client *http.Client `json:"-"`
33+
Self User `json:"-"`
34+
Client HTTPClient `json:"-"`
2935
shutdownChannel chan interface{}
3036

3137
apiEndpoint string
@@ -35,21 +41,29 @@ type BotAPI struct {
3541
//
3642
// It requires a token, provided by @BotFather on Telegram.
3743
func NewBotAPI(token string) (*BotAPI, error) {
38-
return NewBotAPIWithClient(token, &http.Client{})
44+
return NewBotAPIWithClient(token, APIEndpoint, &http.Client{})
45+
}
46+
47+
// NewBotAPIWithAPIEndpoint creates a new BotAPI instance
48+
// and allows you to pass API endpoint.
49+
//
50+
// It requires a token, provided by @BotFather on Telegram and API endpoint.
51+
func NewBotAPIWithAPIEndpoint(token, apiEndpoint string) (*BotAPI, error) {
52+
return NewBotAPIWithClient(token, apiEndpoint, &http.Client{})
3953
}
4054

4155
// NewBotAPIWithClient creates a new BotAPI instance
4256
// and allows you to pass a http.Client.
4357
//
44-
// It requires a token, provided by @BotFather on Telegram.
45-
func NewBotAPIWithClient(token string, client *http.Client) (*BotAPI, error) {
58+
// It requires a token, provided by @BotFather on Telegram and API endpoint.
59+
func NewBotAPIWithClient(token, apiEndpoint string, client HTTPClient) (*BotAPI, error) {
4660
bot := &BotAPI{
4761
Token: token,
4862
Client: client,
4963
Buffer: 100,
5064
shutdownChannel: make(chan interface{}),
5165

52-
apiEndpoint: APIEndpoint,
66+
apiEndpoint: apiEndpoint,
5367
}
5468

5569
self, err := bot.GetMe()
@@ -413,6 +427,7 @@ func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) UpdatesChannel {
413427
for {
414428
select {
415429
case <-bot.shutdownChannel:
430+
close(ch)
416431
return
417432
default:
418433
}
@@ -451,21 +466,35 @@ func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
451466
ch := make(chan Update, bot.Buffer)
452467

453468
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
454-
ch <- bot.HandleUpdate(w, r)
469+
update, err := bot.HandleUpdate(r)
470+
if err != nil {
471+
errMsg, _ := json.Marshal(map[string]string{"error": err.Error()})
472+
w.WriteHeader(http.StatusBadRequest)
473+
w.Header().Set("Content-Type", "application/json")
474+
_, _ = w.Write(errMsg)
475+
return
476+
}
477+
478+
ch <- *update
455479
})
456480

457481
return ch
458482
}
459483

460484
// HandleUpdate parses and returns update received via webhook
461-
func (bot *BotAPI) HandleUpdate(res http.ResponseWriter, req *http.Request) Update {
462-
bytes, _ := ioutil.ReadAll(req.Body)
463-
req.Body.Close()
485+
func (bot *BotAPI) HandleUpdate(r *http.Request) (*Update, error) {
486+
if r.Method != http.MethodPost {
487+
err := errors.New("wrong HTTP method required POST")
488+
return nil, err
489+
}
464490

465491
var update Update
466-
json.Unmarshal(bytes, &update)
492+
err := json.NewDecoder(r.Body).Decode(&update)
493+
if err != nil {
494+
return nil, err
495+
}
467496

468-
return update
497+
return &update, nil
469498
}
470499

471500
// WriteToHTTPResponse writes the request to the HTTP ResponseWriter.

bot_test.go

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,25 @@ const (
2323
ExistingStickerFileID = "BQADAgADcwADjMcoCbdl-6eB--YPAg"
2424
)
2525

26+
type testLogger struct {
27+
t *testing.T
28+
}
29+
30+
func (t testLogger) Println(v ...interface{}) {
31+
t.t.Log(v...)
32+
}
33+
34+
func (t testLogger) Printf(format string, v ...interface{}) {
35+
t.t.Logf(format, v...)
36+
}
37+
2638
func getBot(t *testing.T) (*BotAPI, error) {
2739
bot, err := NewBotAPI(TestToken)
2840
bot.Debug = true
2941

42+
logger := testLogger{t}
43+
SetLogger(logger)
44+
3045
if err != nil {
3146
t.Error(err)
3247
}
@@ -417,6 +432,32 @@ func TestSendWithExistingStickerAndKeyboardHide(t *testing.T) {
417432
}
418433
}
419434

435+
func TestSendWithDice(t *testing.T) {
436+
bot, _ := getBot(t)
437+
438+
msg := NewDice(ChatID)
439+
_, err := bot.Send(msg)
440+
441+
if err != nil {
442+
t.Error(err)
443+
t.Fail()
444+
}
445+
446+
}
447+
448+
func TestSendWithDiceWithEmoji(t *testing.T) {
449+
bot, _ := getBot(t)
450+
451+
msg := NewDiceWithEmoji(ChatID, "🏀")
452+
_, err := bot.Send(msg)
453+
454+
if err != nil {
455+
t.Error(err)
456+
t.Fail()
457+
}
458+
459+
}
460+
420461
func TestGetFile(t *testing.T) {
421462
bot, _ := getBot(t)
422463

@@ -634,7 +675,12 @@ func ExampleWebhookHandler() {
634675
}
635676

636677
http.HandleFunc("/"+bot.Token, func(w http.ResponseWriter, r *http.Request) {
637-
log.Printf("%+v\n", bot.HandleUpdate(w, r))
678+
update, err := bot.HandleUpdate(r)
679+
if err != nil {
680+
log.Printf("%+v\n", err.Error())
681+
} else {
682+
log.Printf("%+v\n", *update)
683+
}
638684
})
639685

640686
go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil)

configs.go

Lines changed: 62 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ type RemoveWebhookConfig struct {
831831
}
832832

833833
func (config RemoveWebhookConfig) method() string {
834-
return "setWebhook"
834+
return "deleteWebhook"
835835
}
836836

837837
func (config RemoveWebhookConfig) params() (Params, error) {
@@ -878,12 +878,9 @@ func (config InlineConfig) params() (Params, error) {
878878
params.AddNonEmpty("next_offset", config.NextOffset)
879879
params.AddNonEmpty("switch_pm_text", config.SwitchPMText)
880880
params.AddNonEmpty("switch_pm_parameter", config.SwitchPMParameter)
881+
err := params.AddInterface("results", config.Results)
881882

882-
if err := params.AddInterface("results", config.Results); err != nil {
883-
return params, err
884-
}
885-
886-
return params, nil
883+
return params, err
887884
}
888885

889886
// CallbackConfig contains information on making a CallbackQuery response.
@@ -975,12 +972,10 @@ func (config RestrictChatMemberConfig) params() (Params, error) {
975972
params.AddFirstValid("chat_id", config.ChatID, config.SuperGroupUsername, config.ChannelUsername)
976973
params.AddNonZero("user_id", config.UserID)
977974

978-
if err := params.AddInterface("permissions", config.Permissions); err != nil {
979-
return params, err
980-
}
975+
err := params.AddInterface("permissions", config.Permissions)
981976
params.AddNonZero64("until_date", config.UntilDate)
982977

983-
return params, nil
978+
return params, err
984979
}
985980

986981
// PromoteChatMemberConfig contains fields to promote members of chat
@@ -1200,10 +1195,7 @@ func (config InvoiceConfig) params() (Params, error) {
12001195
params["start_parameter"] = config.StartParameter
12011196
params["currency"] = config.Currency
12021197

1203-
if err = params.AddInterface("prices", config.Prices); err != nil {
1204-
return params, err
1205-
}
1206-
1198+
err = params.AddInterface("prices", config.Prices)
12071199
params.AddNonEmpty("provider_data", config.ProviderData)
12081200
params.AddNonEmpty("photo_url", config.PhotoURL)
12091201
params.AddNonZero("photo_size", config.PhotoSize)
@@ -1217,7 +1209,7 @@ func (config InvoiceConfig) params() (Params, error) {
12171209
params.AddBool("send_phone_number_to_provider", config.SendPhoneNumberToProvider)
12181210
params.AddBool("send_email_to_provider", config.SendEmailToProvider)
12191211

1220-
return params, nil
1212+
return params, err
12211213
}
12221214

12231215
func (config InvoiceConfig) method() string {
@@ -1232,13 +1224,42 @@ type ShippingConfig struct {
12321224
ErrorMessage string
12331225
}
12341226

1227+
func (config ShippingConfig) method() string {
1228+
return "answerShippingQuery"
1229+
}
1230+
1231+
func (config ShippingConfig) params() (Params, error) {
1232+
params := make(Params)
1233+
1234+
params["shipping_query_id"] = config.ShippingQueryID
1235+
params.AddBool("ok", config.OK)
1236+
err := params.AddInterface("shipping_options", config.ShippingOptions)
1237+
params.AddNonEmpty("error_message", config.ErrorMessage)
1238+
1239+
return params, err
1240+
}
1241+
12351242
// PreCheckoutConfig conatins information for answerPreCheckoutQuery request.
12361243
type PreCheckoutConfig struct {
12371244
PreCheckoutQueryID string // required
12381245
OK bool // required
12391246
ErrorMessage string
12401247
}
12411248

1249+
func (config PreCheckoutConfig) method() string {
1250+
return "answerPreCheckoutQuery"
1251+
}
1252+
1253+
func (config PreCheckoutConfig) params() (Params, error) {
1254+
params := make(Params)
1255+
1256+
params["pre_checkout_query_id"] = config.PreCheckoutQueryID
1257+
params.AddBool("ok", config.OK)
1258+
params.AddNonEmpty("error_message", config.ErrorMessage)
1259+
1260+
return params, nil
1261+
}
1262+
12421263
// DeleteMessageConfig contains information of a message in a chat to delete.
12431264
type DeleteMessageConfig struct {
12441265
ChannelUsername string
@@ -1678,30 +1699,6 @@ func (config MediaGroupConfig) params() (Params, error) {
16781699
return params, nil
16791700
}
16801701

1681-
// DiceConfig allows you to send a random dice roll to Telegram.
1682-
//
1683-
// Emoji may be one of the following: 🎲 (1-6), 🎯 (1-6), 🏀 (1-5).
1684-
type DiceConfig struct {
1685-
BaseChat
1686-
1687-
Emoji string
1688-
}
1689-
1690-
func (config DiceConfig) method() string {
1691-
return "sendDice"
1692-
}
1693-
1694-
func (config DiceConfig) params() (Params, error) {
1695-
params, err := config.BaseChat.params()
1696-
if err != nil {
1697-
return params, err
1698-
}
1699-
1700-
params.AddNonEmpty("emoji", config.Emoji)
1701-
1702-
return params, err
1703-
}
1704-
17051702
// GetMyCommandsConfig gets a list of the currently registered commands.
17061703
type GetMyCommandsConfig struct{}
17071704

@@ -1710,7 +1707,7 @@ func (config GetMyCommandsConfig) method() string {
17101707
}
17111708

17121709
func (config GetMyCommandsConfig) params() (Params, error) {
1713-
return make(Params), nil
1710+
return nil, nil
17141711
}
17151712

17161713
// SetMyCommandsConfig sets a list of commands the bot understands.
@@ -1729,3 +1726,28 @@ func (config SetMyCommandsConfig) params() (Params, error) {
17291726

17301727
return params, err
17311728
}
1729+
1730+
// DiceConfig contains information about a sendDice request.
1731+
type DiceConfig struct {
1732+
BaseChat
1733+
// Emoji on which the dice throw animation is based.
1734+
// Currently, must be one of “🎲”, “🎯”, or “🏀”.
1735+
// Dice can have values 1-6 for “🎲” and “🎯”, and values 1-5 for “🏀”.
1736+
// Defaults to “🎲”
1737+
Emoji string
1738+
}
1739+
1740+
func (config DiceConfig) method() string {
1741+
return "sendDice"
1742+
}
1743+
1744+
func (config DiceConfig) params() (Params, error) {
1745+
params, err := config.BaseChat.params()
1746+
if err != nil {
1747+
return params, err
1748+
}
1749+
1750+
params.AddNonEmpty("emoji", config.Emoji)
1751+
1752+
return params, err
1753+
}

0 commit comments

Comments
 (0)