diff --git a/bot.go b/bot.go index eb5a20e..58c496f 100644 --- a/bot.go +++ b/bot.go @@ -7,7 +7,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/technoweenie/multipartstreamer" "io/ioutil" "log" "net/http" @@ -16,14 +15,19 @@ import ( "strconv" "strings" "time" + + "github.com/technoweenie/multipartstreamer" ) // BotAPI allows you to interact with the Telegram Bot API. type BotAPI struct { - Token string `json:"token"` - Debug bool `json:"debug"` - Self User `json:"-"` - Client *http.Client `json:"-"` + Token string `json:"token"` + Debug bool `json:"debug"` + Self User `json:"-"` + Client *http.Client `json:"-"` + CommandHandlers map[string]MessageHandlerFunc + TextHandler MessageHandlerFunc + InlineHandler InlineHandlerFunc } // NewBotAPI creates a new BotAPI instance. @@ -39,8 +43,9 @@ func NewBotAPI(token string) (*BotAPI, error) { // It requires a token, provided by @BotFather on Telegram. func NewBotAPIWithClient(token string, client *http.Client) (*BotAPI, error) { bot := &BotAPI{ - Token: token, - Client: client, + Token: token, + Client: client, + CommandHandlers: map[string]MessageHandlerFunc{}, } self, err := bot.GetMe() @@ -53,6 +58,55 @@ func NewBotAPIWithClient(token string, client *http.Client) (*BotAPI, error) { return bot, nil } +// ProcessUpdate calls corresponding handler for update +func (bot *BotAPI) ProcessUpdate(update Update) { + if !update.IsInlineQuery() { + msg := update.Message + if msg.IsCommand() { + cmd := msg.Command() + if f, ok := bot.CommandHandlers[cmd]; ok { + f.Serve(bot, msg) + } else { + log.Fatal("No handler defined for: " + cmd) + } + } else { + if f := bot.TextHandler; f != nil { + f.Serve(bot, msg) + } else { + log.Fatal("No Text Handler defined") + } + } + } else { + query := update.InlineQuery + if f := bot.InlineHandler; f != nil { + f.Serve(bot, query) + } else { + log.Fatal("No Inline Query Handler defined") + } + } +} + +// AddCommandHandler adds a MessageHandlerFunc for commands +// +// +func (bot *BotAPI) AddCommandHandler(cmd string, f MessageHandlerFunc) { + bot.CommandHandlers[cmd] = f +} + +// AddTextHandler adds a MessageHandlerFunc for non-commands +// +// +func (bot *BotAPI) AddTextHandler(f MessageHandlerFunc) { + bot.TextHandler = f +} + +// AddInlineHandler adds a InlineHandlerFunc for inline querys +// +// +func (bot *BotAPI) AddInlineHandler(f InlineHandlerFunc) { + bot.InlineHandler = f +} + // MakeRequest makes a request to a specific endpoint with our token. func (bot *BotAPI) MakeRequest(endpoint string, params url.Values) (APIResponse, error) { method := fmt.Sprintf(APIEndpoint, bot.Token, endpoint) diff --git a/types.go b/types.go index 18ba5db..668b056 100644 --- a/types.go +++ b/types.go @@ -25,6 +25,14 @@ type Update struct { ChosenInlineResult ChosenInlineResult `json:"chosen_inline_result"` } +// Checks if Update is InlineQuery +func (u Update) IsInlineQuery() bool { + if u.InlineQuery.ID != "" { + return true + } + return false +} + // User is a user on Telegram. type User struct { ID int `json:"id"` @@ -369,3 +377,19 @@ type ChosenInlineResult struct { From User `json:"from"` Query string `json:"query"` } + +// MessageHandlerFunc for handling Messages +// Something similar in line to http.HandlerFunc +type MessageHandlerFunc func(*BotAPI, Message) + +func (f MessageHandlerFunc) Serve(bot *BotAPI, msg Message) { + f(bot, msg) +} + +// InlineHandlerFunc for handling Inline Query +// Something similar in line to http.HandlerFunc +type InlineHandlerFunc func(*BotAPI, InlineQuery) + +func (f InlineHandlerFunc) Serve(bot *BotAPI, q InlineQuery) { + f(bot, q) +}