diff --git a/README.md b/README.md index af48acd..5664724 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Golang Telegram bindings for the Bot API +# Golang bindings for the Telegram Bot API [![GoDoc](https://godoc.org/github.com/Syfaro/telegram-bot-api?status.svg)](http://godoc.org/github.com/Syfaro/telegram-bot-api) @@ -7,7 +7,7 @@ If you want a feature that hasn't been added yet or something is broken, open an All methods are fairly self explanatory, and reading the godoc page should explain everything. If something isn't clear, open an issue or submit a pull request. -The scope of this project is just to provide a wrapper around the API without any additional features. There are other projects (including one I am developing myself) for creating something with plugins and command handlers without having to design all that yourself. +The scope of this project is just to provide a wrapper around the API without any additional features. There are other projects for creating something with plugins and command handlers without having to design all that yourself. ## Example diff --git a/bot_test.go b/bot_test.go new file mode 100644 index 0000000..37280f4 --- /dev/null +++ b/bot_test.go @@ -0,0 +1,87 @@ +package tgbotapi_test + +import ( + "github.com/syfaro/telegram-bot-api" + "log" + "os" + "testing" +) + +func TestMain(m *testing.M) { + botToken := os.Getenv("TELEGRAM_API_TOKEN") + + if botToken == "" { + log.Panic("You must provide a TELEGRAM_API_TOKEN env variable to test!") + } + + os.Exit(m.Run()) +} + +func TestNewBotAPI_notoken(t *testing.T) { + _, err := tgbotapi.NewBotAPI("") + + if err.Error() != tgbotapi.APIForbidden { + t.Fail() + } +} + +func TestNewBotAPI_token(t *testing.T) { + _, err := tgbotapi.NewBotAPI(os.Getenv("TELEGRAM_API_TOKEN")) + + if err != nil { + t.Fail() + } +} + +func TestGetUpdates(t *testing.T) { + bot, err := tgbotapi.NewBotAPI(os.Getenv("TELEGRAM_API_TOKEN")) + + if err != nil { + t.Fail() + } + + u := tgbotapi.NewUpdate(0) + u.Limit = 10000 + + _, err = bot.GetUpdates(u) + + if err != nil { + t.Fail() + } +} + +func TestSendMessage(t *testing.T) { + bot, err := tgbotapi.NewBotAPI(os.Getenv("TELEGRAM_API_TOKEN")) + + if err != nil { + t.Fail() + } + + msg := tgbotapi.NewMessage(36529758, "A test message from the test library in telegram-bot-api") + bot.SendMessage(msg) +} + +func ExampleNewBotAPI() { + bot, err := tgbotapi.NewBotAPI("MyAwesomeBotToken") + if err != nil { + log.Panic(err) + } + + bot.Debug = true + + log.Printf("Authorized on account %s", bot.Self.UserName) + + u := tgbotapi.NewUpdate(0) + u.Timeout = 60 + + err = bot.UpdatesChan(u) + + for update := range bot.Updates { + log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text) + + msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text) + msg.ReplyToMessageID = update.Message.MessageID + + bot.SendMessage(msg) + } +} diff --git a/methods.go b/methods.go index 8a1ccac..a724303 100644 --- a/methods.go +++ b/methods.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "errors" + "fmt" "io" "io/ioutil" "log" @@ -14,6 +15,12 @@ import ( "strconv" ) +// Telegram constants +const ( + // APIEndpoint is the endpoint for all API methods, with formatting for Sprintf + APIEndpoint = "https://api.telegram.org/bot%s/%s" +) + // Constant values for ChatActions const ( ChatTyping = "typing" @@ -26,6 +33,12 @@ const ( ChatFindLocation = "find_location" ) +// API errors +const ( + // APIForbidden happens when a token is bad + APIForbidden = "forbidden" +) + // MessageConfig contains information about a SendMessage request. type MessageConfig struct { ChatID int @@ -35,7 +48,7 @@ type MessageConfig struct { ReplyMarkup interface{} } -// ForwardConfig contains infomation about a ForwardMessage request. +// ForwardConfig contains information about a ForwardMessage request. type ForwardConfig struct { ChatID int FromChatID int @@ -131,12 +144,16 @@ type WebhookConfig struct { // MakeRequest makes a request to a specific endpoint with our token. // All requests are POSTs because Telegram doesn't care, and it's easier. func (bot *BotAPI) MakeRequest(endpoint string, params url.Values) (APIResponse, error) { - resp, err := bot.Client.PostForm("https://api.telegram.org/bot"+bot.Token+"/"+endpoint, params) + resp, err := bot.Client.PostForm(fmt.Sprintf(APIEndpoint, bot.Token, endpoint), params) if err != nil { return APIResponse{}, err } defer resp.Body.Close() + if resp.StatusCode == http.StatusForbidden { + return APIResponse{}, errors.New(APIForbidden) + } + bytes, err := ioutil.ReadAll(resp.Body) if err != nil { return APIResponse{}, err @@ -189,7 +206,7 @@ func (bot *BotAPI) UploadFile(endpoint string, params map[string]string, fieldna w.Close() - req, err := http.NewRequest("POST", "https://api.telegram.org/bot"+bot.Token+"/"+endpoint, &b) + req, err := http.NewRequest("POST", fmt.Sprintf(APIEndpoint, bot.Token, endpoint), &b) if err != nil { return APIResponse{}, err } @@ -274,7 +291,7 @@ func (bot *BotAPI) SendMessage(config MessageConfig) (Message, error) { // ForwardMessage forwards a message from one chat to another. // -// Requires ChatID (destionation), FromChatID (source), and MessageID. +// Requires ChatID (destination), FromChatID (source), and MessageID. func (bot *BotAPI) ForwardMessage(config ForwardConfig) (Message, error) { v := url.Values{} v.Add("chat_id", strconv.Itoa(config.ChatID)) diff --git a/updates.go b/updates.go index 72f518b..a3c6c46 100644 --- a/updates.go +++ b/updates.go @@ -5,8 +5,8 @@ import ( "time" ) -// UpdatesChan returns a chan that is called whenever a new message is gotten. -func (bot *BotAPI) UpdatesChan(config UpdateConfig) (chan Update, error) { +// UpdatesChan starts a channel for getting updates. +func (bot *BotAPI) UpdatesChan(config UpdateConfig) error { bot.Updates = make(chan Update, 100) go func() { @@ -33,5 +33,5 @@ func (bot *BotAPI) UpdatesChan(config UpdateConfig) (chan Update, error) { } }() - return bot.Updates, nil + return nil }