Move bot config to separate struct.
This commit is contained in:
parent
aa0cdf3719
commit
1b1af39b61
8 changed files with 353 additions and 286 deletions
110
bot.go
110
bot.go
|
@ -14,66 +14,56 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HTTPClient is the type needed for the bot to perform HTTP requests.
|
const DefaultBufferSize = 100
|
||||||
type HTTPClient interface {
|
|
||||||
|
// HTTPClientI is the type needed for the bot to perform HTTP requests.
|
||||||
|
type HTTPClientI interface {
|
||||||
Do(req *http.Request) (*http.Response, error)
|
Do(req *http.Request) (*http.Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BotAPI allows you to interact with the Telegram Bot API.
|
// BotAPI allows you to interact with the Telegram Bot API.
|
||||||
type BotAPI struct {
|
type BotAPI struct {
|
||||||
Token string `json:"token"`
|
config BotConfigI
|
||||||
Debug bool `json:"debug"`
|
client HTTPClientI
|
||||||
Buffer int `json:"buffer"`
|
readonly bool
|
||||||
|
|
||||||
Self User `json:"-"`
|
buffer int
|
||||||
Client HTTPClient `json:"-"`
|
|
||||||
shutdownChannel chan interface{}
|
shutdownChannel chan interface{}
|
||||||
|
|
||||||
apiEndpoint string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBotAPI creates a new BotAPI instance.
|
// NewBot creates a new BotAPI instance.
|
||||||
//
|
//
|
||||||
// It requires a token, provided by @BotFather on Telegram.
|
// It requires a token, provided by @BotFather on Telegram.
|
||||||
func NewBotAPI(token string) (*BotAPI, error) {
|
func NewBot(config BotConfigI) *BotAPI {
|
||||||
return NewBotAPIWithClient(token, APIEndpoint, &http.Client{})
|
return NewBotWithClient(config, &http.Client{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBotAPIWithAPIEndpoint creates a new BotAPI instance
|
// NewBotWithClient creates a new BotAPI instance
|
||||||
// and allows you to pass API endpoint.
|
|
||||||
//
|
|
||||||
// It requires a token, provided by @BotFather on Telegram and API endpoint.
|
|
||||||
func NewBotAPIWithAPIEndpoint(token, apiEndpoint string) (*BotAPI, error) {
|
|
||||||
return NewBotAPIWithClient(token, apiEndpoint, &http.Client{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBotAPIWithClient creates a new BotAPI instance
|
|
||||||
// and allows you to pass a http.Client.
|
// and allows you to pass a http.Client.
|
||||||
//
|
//
|
||||||
// It requires a token, provided by @BotFather on Telegram and API endpoint.
|
// It requires a token, provided by @BotFather on Telegram and API endpoint.
|
||||||
func NewBotAPIWithClient(token, apiEndpoint string, client HTTPClient) (*BotAPI, error) {
|
func NewBotWithClient(config BotConfigI, client HTTPClientI) *BotAPI {
|
||||||
bot := &BotAPI{
|
bot := &BotAPI{
|
||||||
Token: token,
|
config: config.(*BotConfig),
|
||||||
Client: client,
|
client: client,
|
||||||
Buffer: 100,
|
buffer: DefaultBufferSize,
|
||||||
shutdownChannel: make(chan interface{}),
|
shutdownChannel: make(chan interface{}),
|
||||||
|
|
||||||
apiEndpoint: apiEndpoint,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self, err := bot.GetMe()
|
return bot
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.Self = self
|
|
||||||
|
|
||||||
return bot, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAPIEndpoint changes the Telegram Bot API endpoint used by the instance.
|
func (b *BotAPI) GetConfig() BotConfigI {
|
||||||
func (bot *BotAPI) SetAPIEndpoint(apiEndpoint string) {
|
return b.config
|
||||||
bot.apiEndpoint = apiEndpoint
|
}
|
||||||
|
|
||||||
|
func (b *BotAPI) Validate() error {
|
||||||
|
_, err := b.GetMe()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bot *BotAPI) SetReadonly(readonly bool) {
|
||||||
|
bot.readonly = readonly
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildParams(in Params) url.Values {
|
func buildParams(in Params) url.Values {
|
||||||
|
@ -92,11 +82,11 @@ func buildParams(in Params) url.Values {
|
||||||
|
|
||||||
// MakeRequest makes a request to a specific endpoint with our token.
|
// MakeRequest makes a request to a specific endpoint with our token.
|
||||||
func (bot *BotAPI) MakeRequest(endpoint string, params Params) (*APIResponse, error) {
|
func (bot *BotAPI) MakeRequest(endpoint string, params Params) (*APIResponse, error) {
|
||||||
if bot.Debug {
|
if bot.config.GetDebug() {
|
||||||
log.Printf("Endpoint: %s, params: %v\n", endpoint, params)
|
log.Printf("Endpoint: %s, params: %v\n", endpoint, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
method := fmt.Sprintf(bot.apiEndpoint, bot.Token, endpoint)
|
method := fmt.Sprintf(bot.config.GetApiEndpoint(), bot.config.GetToken(), endpoint)
|
||||||
|
|
||||||
values := buildParams(params)
|
values := buildParams(params)
|
||||||
|
|
||||||
|
@ -106,7 +96,7 @@ func (bot *BotAPI) MakeRequest(endpoint string, params Params) (*APIResponse, er
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
resp, err := bot.Client.Do(req)
|
resp, err := bot.client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -118,7 +108,7 @@ func (bot *BotAPI) MakeRequest(endpoint string, params Params) (*APIResponse, er
|
||||||
return &apiResp, err
|
return &apiResp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if bot.Debug {
|
if bot.config.GetDebug() {
|
||||||
log.Printf("Endpoint: %s, response: %s\n", endpoint, string(bytes))
|
log.Printf("Endpoint: %s, response: %s\n", endpoint, string(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +133,7 @@ func (bot *BotAPI) MakeRequest(endpoint string, params Params) (*APIResponse, er
|
||||||
// If debug disabled, just decode http.Response.Body stream to APIResponse struct
|
// If debug disabled, just decode http.Response.Body stream to APIResponse struct
|
||||||
// for efficient memory usage
|
// for efficient memory usage
|
||||||
func (bot *BotAPI) decodeAPIResponse(responseBody io.Reader, resp *APIResponse) ([]byte, error) {
|
func (bot *BotAPI) decodeAPIResponse(responseBody io.Reader, resp *APIResponse) ([]byte, error) {
|
||||||
if !bot.Debug {
|
if !bot.config.GetDebug() {
|
||||||
dec := json.NewDecoder(responseBody)
|
dec := json.NewDecoder(responseBody)
|
||||||
err := dec.Decode(resp)
|
err := dec.Decode(resp)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -217,11 +207,11 @@ func (bot *BotAPI) UploadFiles(endpoint string, params Params, files []RequestFi
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if bot.Debug {
|
if bot.config.GetDebug() {
|
||||||
log.Printf("Endpoint: %s, params: %v, with %d files\n", endpoint, params, len(files))
|
log.Printf("Endpoint: %s, params: %v, with %d files\n", endpoint, params, len(files))
|
||||||
}
|
}
|
||||||
|
|
||||||
method := fmt.Sprintf(bot.apiEndpoint, bot.Token, endpoint)
|
method := fmt.Sprintf(bot.config.GetApiEndpoint(), bot.config.GetToken(), endpoint)
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", method, r)
|
req, err := http.NewRequest("POST", method, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -230,7 +220,7 @@ func (bot *BotAPI) UploadFiles(endpoint string, params Params, files []RequestFi
|
||||||
|
|
||||||
req.Header.Set("Content-Type", m.FormDataContentType())
|
req.Header.Set("Content-Type", m.FormDataContentType())
|
||||||
|
|
||||||
resp, err := bot.Client.Do(req)
|
resp, err := bot.client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -242,7 +232,7 @@ func (bot *BotAPI) UploadFiles(endpoint string, params Params, files []RequestFi
|
||||||
return &apiResp, err
|
return &apiResp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if bot.Debug {
|
if bot.config.GetDebug() {
|
||||||
log.Printf("Endpoint: %s, response: %s\n", endpoint, string(bytes))
|
log.Printf("Endpoint: %s, response: %s\n", endpoint, string(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +262,7 @@ func (bot *BotAPI) GetFileDirectURL(fileID string) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return file.Link(bot.Token), nil
|
return file.Link(bot.config.GetToken()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMe fetches the currently authenticated bot.
|
// GetMe fetches the currently authenticated bot.
|
||||||
|
@ -292,12 +282,12 @@ func (bot *BotAPI) GetMe() (User, error) {
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsMessageToMe returns true if message directed to this bot.
|
//// IsMessageToMe returns true if message directed to this bot.
|
||||||
//
|
////
|
||||||
// It requires the Message.
|
//// It requires the Message.
|
||||||
func (bot *BotAPI) IsMessageToMe(message Message) bool {
|
//func (bot *BotAPI) IsMessageToMe(message Message) bool {
|
||||||
return strings.Contains(message.Text, "@"+bot.Self.UserName)
|
// return strings.Contains(message.Text, "@"+bot.Self.UserName)
|
||||||
}
|
//}
|
||||||
|
|
||||||
func hasFilesNeedingUpload(files []RequestFile) bool {
|
func hasFilesNeedingUpload(files []RequestFile) bool {
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
|
@ -428,7 +418,7 @@ func (bot *BotAPI) GetWebhookInfo() (WebhookInfo, error) {
|
||||||
|
|
||||||
// GetUpdatesChan starts and returns a channel for getting updates.
|
// GetUpdatesChan starts and returns a channel for getting updates.
|
||||||
func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) UpdatesChannel {
|
func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) UpdatesChannel {
|
||||||
ch := make(chan Update, bot.Buffer)
|
ch := make(chan Update, bot.buffer)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
|
@ -462,15 +452,16 @@ func (bot *BotAPI) GetUpdatesChan(config UpdateConfig) UpdatesChannel {
|
||||||
|
|
||||||
// StopReceivingUpdates stops the go routine which receives updates
|
// StopReceivingUpdates stops the go routine which receives updates
|
||||||
func (bot *BotAPI) StopReceivingUpdates() {
|
func (bot *BotAPI) StopReceivingUpdates() {
|
||||||
if bot.Debug {
|
if bot.config.GetDebug() {
|
||||||
log.Println("Stopping the update receiver routine...")
|
log.Println("Stopping the update receiver routine...")
|
||||||
}
|
}
|
||||||
close(bot.shutdownChannel)
|
close(bot.shutdownChannel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: get rid of bot dependancy
|
||||||
// ListenForWebhook registers a http handler for a webhook.
|
// ListenForWebhook registers a http handler for a webhook.
|
||||||
func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
|
func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
|
||||||
ch := make(chan Update, bot.Buffer)
|
ch := make(chan Update, bot.buffer)
|
||||||
|
|
||||||
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
||||||
update, err := bot.HandleUpdate(r)
|
update, err := bot.HandleUpdate(r)
|
||||||
|
@ -488,9 +479,10 @@ func (bot *BotAPI) ListenForWebhook(pattern string) UpdatesChannel {
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Remove dependancy on bot
|
||||||
// ListenForWebhookRespReqFormat registers a http handler for a single incoming webhook.
|
// ListenForWebhookRespReqFormat registers a http handler for a single incoming webhook.
|
||||||
func (bot *BotAPI) ListenForWebhookRespReqFormat(w http.ResponseWriter, r *http.Request) UpdatesChannel {
|
func (bot *BotAPI) ListenForWebhookRespReqFormat(w http.ResponseWriter, r *http.Request) UpdatesChannel {
|
||||||
ch := make(chan Update, bot.Buffer)
|
ch := make(chan Update, bot.buffer)
|
||||||
|
|
||||||
func(w http.ResponseWriter, r *http.Request) {
|
func(w http.ResponseWriter, r *http.Request) {
|
||||||
defer close(ch)
|
defer close(ch)
|
||||||
|
@ -510,6 +502,8 @@ func (bot *BotAPI) ListenForWebhookRespReqFormat(w http.ResponseWriter, r *http.
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: move it outside of bot struct, it's not related to bot
|
||||||
|
|
||||||
// HandleUpdate parses and returns update received via webhook
|
// HandleUpdate parses and returns update received via webhook
|
||||||
func (bot *BotAPI) HandleUpdate(r *http.Request) (*Update, error) {
|
func (bot *BotAPI) HandleUpdate(r *http.Request) (*Update, error) {
|
||||||
if r.Method != http.MethodPost {
|
if r.Method != http.MethodPost {
|
||||||
|
|
42
bot_config.go
Normal file
42
bot_config.go
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
package tgbotapi
|
||||||
|
|
||||||
|
type BotConfigI interface {
|
||||||
|
GetApiEndpoint() string
|
||||||
|
GetToken() string
|
||||||
|
GetDebug() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type BotConfig struct {
|
||||||
|
token string
|
||||||
|
debug bool
|
||||||
|
|
||||||
|
apiEndpoint string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBotConfig(token, apiEndpoint string, debug bool) *BotConfig {
|
||||||
|
return &BotConfig{
|
||||||
|
token: token,
|
||||||
|
debug: debug,
|
||||||
|
apiEndpoint: apiEndpoint,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultBotConfig(token string) *BotConfig {
|
||||||
|
return &BotConfig{
|
||||||
|
token: token,
|
||||||
|
debug: false,
|
||||||
|
apiEndpoint: APIEndpoint,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *BotConfig) GetApiEndpoint() string {
|
||||||
|
return c.apiEndpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *BotConfig) GetToken() string {
|
||||||
|
return c.token
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *BotConfig) GetDebug() bool {
|
||||||
|
return c.debug
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ import (
|
||||||
gomock "go.uber.org/mock/gomock"
|
gomock "go.uber.org/mock/gomock"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockHTTPClient is a mock of HTTPClient interface.
|
// MockHTTPClient is a mock of HTTPClientI interface.
|
||||||
type MockHTTPClient struct {
|
type MockHTTPClient struct {
|
||||||
ctrl *gomock.Controller
|
ctrl *gomock.Controller
|
||||||
recorder *MockHTTPClientMockRecorder
|
recorder *MockHTTPClientMockRecorder
|
||||||
|
|
130
bot_test.go
130
bot_test.go
|
@ -36,7 +36,8 @@ func expectGetMe(t *testing.T, c *MockHTTPClient) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewBotInstance_WithEmptyToken(t *testing.T) {
|
func TestNewBotInstance_WithEmptyToken(t *testing.T) {
|
||||||
_, err := NewBotAPI("")
|
bot := NewBot(NewDefaultBotConfig(""))
|
||||||
|
err := bot.Validate()
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +95,8 @@ func TestGetUpdates(t *testing.T) {
|
||||||
return newOKResponse(updateResp), nil
|
return newOKResponse(updateResp), nil
|
||||||
})
|
})
|
||||||
|
|
||||||
bot, err := NewBotAPIWithClient(TestToken, APIEndpoint, client)
|
bot := NewBotWithClient(NewBotConfig(TestToken, APIEndpoint, false), client)
|
||||||
|
err := bot.Validate()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
u := NewUpdate(0)
|
u := NewUpdate(0)
|
||||||
|
@ -107,25 +109,25 @@ func TestSendWithMessage(t *testing.T) {
|
||||||
defer client.ctrl.Finish()
|
defer client.ctrl.Finish()
|
||||||
|
|
||||||
responseBody := `{
|
responseBody := `{
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"result": {
|
"result": {
|
||||||
"message_id": 123,
|
"message_id": 123,
|
||||||
"from": {
|
"from": {
|
||||||
"id": 123456789,
|
"id": 123456789,
|
||||||
"is_bot": true,
|
"is_bot": true,
|
||||||
"first_name": "MyBot",
|
"first_name": "MyBot",
|
||||||
"username": "my_bot"
|
"username": "my_bot"
|
||||||
},
|
},
|
||||||
"chat": {
|
"chat": {
|
||||||
"id": 987654321,
|
"id": 987654321,
|
||||||
"first_name": "John",
|
"first_name": "John",
|
||||||
"username": "john_doe",
|
"username": "john_doe",
|
||||||
"type": "private"
|
"type": "private"
|
||||||
},
|
},
|
||||||
"date": 1640001112,
|
"date": 1640001112,
|
||||||
"text": "Hello, John!"
|
"text": "Hello, John!"
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
expectGetMe(t, client)
|
expectGetMe(t, client)
|
||||||
|
|
||||||
|
@ -137,7 +139,8 @@ func TestSendWithMessage(t *testing.T) {
|
||||||
return newOKResponse(responseBody), nil
|
return newOKResponse(responseBody), nil
|
||||||
})
|
})
|
||||||
|
|
||||||
bot, err := NewBotAPIWithClient(TestToken, APIEndpoint, client)
|
bot := NewBotWithClient(NewBotConfig(TestToken, APIEndpoint, false), client)
|
||||||
|
err := bot.Validate()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api")
|
msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api")
|
||||||
|
@ -151,25 +154,25 @@ func TestSendWithMessageReply(t *testing.T) {
|
||||||
defer client.ctrl.Finish()
|
defer client.ctrl.Finish()
|
||||||
|
|
||||||
responseBody := `{
|
responseBody := `{
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"result": {
|
"result": {
|
||||||
"message_id": 123,
|
"message_id": 123,
|
||||||
"from": {
|
"from": {
|
||||||
"id": 123456789,
|
"id": 123456789,
|
||||||
"is_bot": true,
|
"is_bot": true,
|
||||||
"first_name": "MyBot",
|
"first_name": "MyBot",
|
||||||
"username": "my_bot"
|
"username": "my_bot"
|
||||||
},
|
},
|
||||||
"chat": {
|
"chat": {
|
||||||
"id": 987654321,
|
"id": 987654321,
|
||||||
"first_name": "John",
|
"first_name": "John",
|
||||||
"username": "john_doe",
|
"username": "john_doe",
|
||||||
"type": "private"
|
"type": "private"
|
||||||
},
|
},
|
||||||
"date": 1640001112,
|
"date": 1640001112,
|
||||||
"text": "Hello, John!"
|
"text": "Hello, John!"
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
expectGetMe(t, client)
|
expectGetMe(t, client)
|
||||||
|
|
||||||
|
@ -181,7 +184,8 @@ func TestSendWithMessageReply(t *testing.T) {
|
||||||
return newOKResponse(responseBody), nil
|
return newOKResponse(responseBody), nil
|
||||||
})
|
})
|
||||||
|
|
||||||
bot, err := NewBotAPIWithClient(TestToken, APIEndpoint, client)
|
bot := NewBotWithClient(NewBotConfig(TestToken, APIEndpoint, false), client)
|
||||||
|
err := bot.Validate()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api")
|
msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api")
|
||||||
|
@ -196,25 +200,25 @@ func TestCopyMessage(t *testing.T) {
|
||||||
expectGetMe(t, client)
|
expectGetMe(t, client)
|
||||||
|
|
||||||
responseBody := `{
|
responseBody := `{
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"result": {
|
"result": {
|
||||||
"message_id": 123,
|
"message_id": 123,
|
||||||
"from": {
|
"from": {
|
||||||
"id": 123456789,
|
"id": 123456789,
|
||||||
"is_bot": true,
|
"is_bot": true,
|
||||||
"first_name": "MyBot",
|
"first_name": "MyBot",
|
||||||
"username": "my_bot"
|
"username": "my_bot"
|
||||||
},
|
},
|
||||||
"chat": {
|
"chat": {
|
||||||
"id": 987654321,
|
"id": 987654321,
|
||||||
"first_name": "John",
|
"first_name": "John",
|
||||||
"username": "john_doe",
|
"username": "john_doe",
|
||||||
"type": "private"
|
"type": "private"
|
||||||
},
|
},
|
||||||
"date": 1640001112,
|
"date": 1640001112,
|
||||||
"text": "Hello, John!"
|
"text": "Hello, John!"
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
client.EXPECT().
|
client.EXPECT().
|
||||||
Do(gomock.Any()).
|
Do(gomock.Any()).
|
||||||
|
@ -232,7 +236,8 @@ func TestCopyMessage(t *testing.T) {
|
||||||
return newOKResponse(responseBody), nil
|
return newOKResponse(responseBody), nil
|
||||||
})
|
})
|
||||||
|
|
||||||
bot, err := NewBotAPIWithClient(TestToken, APIEndpoint, client)
|
bot := NewBotWithClient(NewBotConfig(TestToken, APIEndpoint, false), client)
|
||||||
|
err := bot.Validate()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api")
|
msg := NewMessage(ChatID, "A test message from the test library in telegram-bot-api")
|
||||||
|
@ -245,7 +250,6 @@ func TestCopyMessage(t *testing.T) {
|
||||||
|
|
||||||
require.Equal(t, messageID.MessageID, message.MessageID)
|
require.Equal(t, messageID.MessageID, message.MessageID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPrepareInputMediaForParams(t *testing.T) {
|
func TestPrepareInputMediaForParams(t *testing.T) {
|
||||||
media := []any{
|
media := []any{
|
||||||
NewInputMediaPhoto(FilePath("./image.jpg")),
|
NewInputMediaPhoto(FilePath("./image.jpg")),
|
||||||
|
|
|
@ -14,6 +14,8 @@ const (
|
||||||
// APIEndpoint is the endpoint for all API methods,
|
// APIEndpoint is the endpoint for all API methods,
|
||||||
// with formatting for Sprintf.
|
// with formatting for Sprintf.
|
||||||
APIEndpoint = "https://api.telegram.org/bot%s/%s"
|
APIEndpoint = "https://api.telegram.org/bot%s/%s"
|
||||||
|
// APITestEndpoint is the endpoint for Telegram test server,
|
||||||
|
APITestEndpoint = "https://api.telegram.org/bot%s/test/%s"
|
||||||
// FileEndpoint is the endpoint for downloading a file from Telegram.
|
// FileEndpoint is the endpoint for downloading a file from Telegram.
|
||||||
FileEndpoint = "https://api.telegram.org/file/bot%s/%s"
|
FileEndpoint = "https://api.telegram.org/file/bot%s/%s"
|
||||||
)
|
)
|
||||||
|
|
181
example/example_bot.go
Normal file
181
example/example_bot.go
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
package example
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/eli-l/telegram-bot-api/v7"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleNewBotAPI() {
|
||||||
|
cfg := tgbotapi.NewBotConfig("MyAwesomeBotToken", tgbotapi.APIEndpoint, true)
|
||||||
|
bot := tgbotapi.NewBot(cfg)
|
||||||
|
|
||||||
|
if err := bot.Validate(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
usr, err := bot.GetMe()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Authorized on account %s", usr.UserName)
|
||||||
|
u := tgbotapi.NewUpdate(0)
|
||||||
|
u.Timeout = 60
|
||||||
|
|
||||||
|
updates := bot.GetUpdatesChan(u)
|
||||||
|
|
||||||
|
// Optional: wait for updates and clear them if you don't want to handle
|
||||||
|
// a large backlog of old messages
|
||||||
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
updates.Clear()
|
||||||
|
|
||||||
|
for update := range updates {
|
||||||
|
if update.Message == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)
|
||||||
|
|
||||||
|
msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text)
|
||||||
|
msg.ReplyParameters.MessageID = update.Message.MessageID
|
||||||
|
|
||||||
|
_, err := bot.Send(msg)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleNewWebhook() {
|
||||||
|
cfg := tgbotapi.NewBotConfig("MyAwesomeBotToken", tgbotapi.APIEndpoint, true)
|
||||||
|
bot := tgbotapi.NewBot(cfg)
|
||||||
|
|
||||||
|
if err := bot.Validate(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
usr, err := bot.GetMe()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Authorized on account %s", usr.UserName)
|
||||||
|
|
||||||
|
wh, err := tgbotapi.NewWebhookWithCert("https://www.google.com:8443/"+cfg.GetToken(), tgbotapi.FilePath("cert.pem"))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = bot.Request(wh)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := bot.GetWebhookInfo()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.LastErrorDate != 0 {
|
||||||
|
fmt.Printf("failed to set webhook: %s", info.LastErrorMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
updates := bot.ListenForWebhook("/" + cfg.GetToken())
|
||||||
|
go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil)
|
||||||
|
|
||||||
|
for update := range updates {
|
||||||
|
fmt.Printf("%+v\n", update)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleWebhookHandler() {
|
||||||
|
cfg := tgbotapi.NewBotConfig("MyAwesomeBotToken", tgbotapi.APIEndpoint, true)
|
||||||
|
bot := tgbotapi.NewBot(cfg)
|
||||||
|
|
||||||
|
if err := bot.Validate(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
usr, err := bot.GetMe()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Authorized on account %s", usr.UserName)
|
||||||
|
|
||||||
|
wh, err := tgbotapi.NewWebhookWithCert("https://www.google.com:8443/"+cfg.GetToken(), tgbotapi.FilePath("cert.pem"))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = bot.Request(wh)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
info, err := bot.GetWebhookInfo()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if info.LastErrorDate != 0 {
|
||||||
|
fmt.Printf("[Telegram callback failed]%s", info.LastErrorMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
http.HandleFunc("/"+cfg.GetToken(), func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
update, err := bot.HandleUpdate(r)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%+v\n", err.Error())
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%+v\n", *update)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
go http.ListenAndServeTLS("0.0.0.0:8443", "./tests/cert.pem", "./tests/key.pem", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleInlineConfig() {
|
||||||
|
cfg := tgbotapi.NewBotConfig("MyAwesomeBotToken", tgbotapi.APIEndpoint, true)
|
||||||
|
bot := tgbotapi.NewBot(cfg)
|
||||||
|
|
||||||
|
if err := bot.Validate(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
usr, err := bot.GetMe()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Authorized on account %s", usr.UserName)
|
||||||
|
|
||||||
|
u := tgbotapi.NewUpdate(0)
|
||||||
|
u.Timeout = 60
|
||||||
|
|
||||||
|
updates := bot.GetUpdatesChan(u)
|
||||||
|
|
||||||
|
for update := range updates {
|
||||||
|
if update.InlineQuery == nil { // if no inline query, ignore it
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
article := tgbotapi.NewInlineQueryResultArticle(update.InlineQuery.ID, "Echo", update.InlineQuery.Query)
|
||||||
|
article.Description = update.InlineQuery.Query
|
||||||
|
|
||||||
|
inlineConf := tgbotapi.InlineConfig{
|
||||||
|
InlineQueryID: update.InlineQuery.ID,
|
||||||
|
IsPersonal: true,
|
||||||
|
CacheTime: 0,
|
||||||
|
Results: []interface{}{article},
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := bot.Request(inlineConf); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
123
example_bot.go
123
example_bot.go
|
@ -1,123 +0,0 @@
|
||||||
package tgbotapi
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ExampleNewBotAPI() {
|
|
||||||
bot, err := NewBotAPI("MyAwesomeBotToken")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.Debug = true
|
|
||||||
|
|
||||||
fmt.Printf("Authorized on account %s", bot.Self.UserName)
|
|
||||||
u := NewUpdate(0)
|
|
||||||
u.Timeout = 60
|
|
||||||
|
|
||||||
updates := bot.GetUpdatesChan(u)
|
|
||||||
|
|
||||||
// Optional: wait for updates and clear them if you don't want to handle
|
|
||||||
// a large backlog of old messages
|
|
||||||
time.Sleep(time.Millisecond * 500)
|
|
||||||
updates.Clear()
|
|
||||||
|
|
||||||
for update := range updates {
|
|
||||||
if update.Message == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)
|
|
||||||
|
|
||||||
msg := NewMessage(update.Message.Chat.ID, update.Message.Text)
|
|
||||||
msg.ReplyParameters.MessageID = update.Message.MessageID
|
|
||||||
|
|
||||||
_, err := bot.Send(msg)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleNewWebhook() {
|
|
||||||
bot, err := NewBotAPI("MyAwesomeBotToken")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.Debug = true
|
|
||||||
|
|
||||||
fmt.Printf("Authorized on account %s", bot.Self.UserName)
|
|
||||||
|
|
||||||
wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, FilePath("cert.pem"))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = bot.Request(wh)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
info, err := bot.GetWebhookInfo()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.LastErrorDate != 0 {
|
|
||||||
fmt.Printf("failed to set webhook: %s", info.LastErrorMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
updates := bot.ListenForWebhook("/" + bot.Token)
|
|
||||||
go http.ListenAndServeTLS("0.0.0.0:8443", "cert.pem", "key.pem", nil)
|
|
||||||
|
|
||||||
for update := range updates {
|
|
||||||
fmt.Printf("%+v\n", update)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleWebhookHandler() {
|
|
||||||
bot, err := NewBotAPI("MyAwesomeBotToken")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
bot.Debug = true
|
|
||||||
|
|
||||||
fmt.Printf("Authorized on account %s", bot.Self.UserName)
|
|
||||||
|
|
||||||
wh, err := NewWebhookWithCert("https://www.google.com:8443/"+bot.Token, FilePath("cert.pem"))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = bot.Request(wh)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
info, err := bot.GetWebhookInfo()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if info.LastErrorDate != 0 {
|
|
||||||
fmt.Printf("[Telegram callback failed]%s", info.LastErrorMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
http.HandleFunc("/"+bot.Token, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
update, err := bot.HandleUpdate(r)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("%+v\n", err.Error())
|
|
||||||
} else {
|
|
||||||
fmt.Printf("%+v\n", *update)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
go http.ListenAndServeTLS("0.0.0.0:8443", "./tests/cert.pem", "./tests/key.pem", nil)
|
|
||||||
}
|
|
|
@ -1,7 +1,6 @@
|
||||||
package tests
|
package tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -52,9 +51,9 @@ func (t testLogger) Printf(format string, v ...interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBot(t *testing.T) (*tgbotapi.BotAPI, error) {
|
func getBot(t *testing.T) (*tgbotapi.BotAPI, error) {
|
||||||
bot, err := tgbotapi.NewBotAPI(TestToken)
|
bot := tgbotapi.NewBot(tgbotapi.NewBotConfig(TestToken, tgbotapi.APIEndpoint, Debug))
|
||||||
|
err := bot.Validate()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
bot.Debug = Debug
|
|
||||||
|
|
||||||
logger := testLogger{t}
|
logger := testLogger{t}
|
||||||
err = tgbotapi.SetLogger(logger)
|
err = tgbotapi.SetLogger(logger)
|
||||||
|
@ -64,9 +63,10 @@ func getBot(t *testing.T) (*tgbotapi.BotAPI, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewBotAPI_notoken(t *testing.T) {
|
func TestNewBotAPI_notoken(t *testing.T) {
|
||||||
bot, err := tgbotapi.NewBotAPI("")
|
bot := tgbotapi.NewBot(tgbotapi.NewBotConfig("", tgbotapi.APIEndpoint, Debug))
|
||||||
|
require.NotNil(t, bot)
|
||||||
|
err := bot.Validate()
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Nil(t, bot)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetUpdates(t *testing.T) {
|
func TestGetUpdates(t *testing.T) {
|
||||||
|
@ -545,13 +545,14 @@ func TestGetUserProfilePhotos(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetWebhookWithCert(t *testing.T) {
|
func TestSetWebhookWithCert(t *testing.T) {
|
||||||
|
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
time.Sleep(time.Second * 2)
|
time.Sleep(time.Second * 2)
|
||||||
|
|
||||||
bot.Request(tgbotapi.DeleteWebhookConfig{})
|
bot.Request(tgbotapi.DeleteWebhookConfig{})
|
||||||
|
|
||||||
wh, err := tgbotapi.NewWebhookWithCert("https://example.com/tgbotapi-test/"+bot.Token, tgbotapi.FilePath("./cert.pem"))
|
wh, err := tgbotapi.NewWebhookWithCert("https://example.com/tgbotapi-test/"+bot.GetConfig().GetToken(), tgbotapi.FilePath("./cert.pem"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, err = bot.Request(wh)
|
_, err = bot.Request(wh)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -571,7 +572,7 @@ func TestSetWebhookWithoutCert(t *testing.T) {
|
||||||
|
|
||||||
bot.Request(tgbotapi.DeleteWebhookConfig{})
|
bot.Request(tgbotapi.DeleteWebhookConfig{})
|
||||||
|
|
||||||
wh, err := tgbotapi.NewWebhook("https://example.com/tgbotapi-test/" + bot.Token)
|
wh, err := tgbotapi.NewWebhook("https://example.com/tgbotapi-test/" + bot.GetConfig().GetToken())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, err = bot.Request(wh)
|
_, err = bot.Request(wh)
|
||||||
|
@ -631,40 +632,6 @@ func TestSendWithMediaGroupAudio(t *testing.T) {
|
||||||
require.Equal(t, len(cfg.Media), len(messages))
|
require.Equal(t, len(cfg.Media), len(messages))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleInlineConfig() {
|
|
||||||
bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken") // create new bot
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Authorized on account %s", bot.Self.UserName)
|
|
||||||
|
|
||||||
u := tgbotapi.NewUpdate(0)
|
|
||||||
u.Timeout = 60
|
|
||||||
|
|
||||||
updates := bot.GetUpdatesChan(u)
|
|
||||||
|
|
||||||
for update := range updates {
|
|
||||||
if update.InlineQuery == nil { // if no inline query, ignore it
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
article := tgbotapi.NewInlineQueryResultArticle(update.InlineQuery.ID, "Echo", update.InlineQuery.Query)
|
|
||||||
article.Description = update.InlineQuery.Query
|
|
||||||
|
|
||||||
inlineConf := tgbotapi.InlineConfig{
|
|
||||||
InlineQueryID: update.InlineQuery.ID,
|
|
||||||
IsPersonal: true,
|
|
||||||
CacheTime: 0,
|
|
||||||
Results: []interface{}{article},
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := bot.Request(inlineConf); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDeleteMessage(t *testing.T) {
|
func TestDeleteMessage(t *testing.T) {
|
||||||
bot, _ := getBot(t)
|
bot, _ := getBot(t)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue