147 lines
4.8 KiB
Go
147 lines
4.8 KiB
Go
|
// Fantasy World Zookeeper Bot
|
||
|
// Copyright (c) 2018 Vladimir "fat0troll" Hodakov
|
||
|
|
||
|
package router
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"regexp"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
|
||
|
"gitlab.com/toby3d/telegram"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
// acceptingForwardsFrom defines list of users which messages can be used as
|
||
|
// forwarded
|
||
|
// In case of this bot, this is @FWorldBot
|
||
|
acceptingForwardsFrom = []int{}
|
||
|
)
|
||
|
|
||
|
func (r *Router) checkForward(update *telegram.Update) error {
|
||
|
if update.Message.ForwardFrom != nil {
|
||
|
log.Debug().Msgf("Processing forward from Telegram ID = %d", update.Message.ForwardFrom.ID)
|
||
|
for i := range acceptingForwardsFrom {
|
||
|
if acceptingForwardsFrom[i] == update.Message.ForwardFrom.ID {
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return errors.New("Can't handle forward from Telegram user with ID =" + strconv.Itoa(update.Message.ForwardFrom.ID))
|
||
|
}
|
||
|
|
||
|
func (r *Router) handleInlineQuery(update *telegram.Update) {
|
||
|
rxpMatched := false
|
||
|
for rxp, function := range r.inlineQueries {
|
||
|
if rxp.MatchString(update.InlineQuery.Query) {
|
||
|
if rxpMatched {
|
||
|
log.Warn().Msgf("The message handled more than once: %s, %s", update.InlineQuery.Query, strings.Replace(rxp.String(), "\n", "\\n", -1))
|
||
|
} else {
|
||
|
rxpMatched = true
|
||
|
function(update)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if !rxpMatched {
|
||
|
log.Debug().Msgf("There is no handler for inline: %s", update.InlineQuery.Query)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (r *Router) handleRequest(update *telegram.Update, commands map[string]func(*telegram.Update), rxps map[*regexp.Regexp]func(*telegram.Update)) {
|
||
|
switch {
|
||
|
case update.Message.IsCommand():
|
||
|
if commands[update.Message.Command()] != nil {
|
||
|
commands[update.Message.Command()](update)
|
||
|
} else {
|
||
|
log.Warn().Msgf("There is no handler for command /%s", update.Message.Command())
|
||
|
}
|
||
|
default:
|
||
|
rxpMatched := false
|
||
|
for rxp, function := range rxps {
|
||
|
if rxp.MatchString(update.Message.Text) {
|
||
|
if rxpMatched {
|
||
|
log.Warn().Msgf("The message handled more than once: %s, %s", update.Message.Text, strings.Replace(rxp.String(), "\n", "\\n", -1))
|
||
|
} else {
|
||
|
rxpMatched = true
|
||
|
function(update)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if !rxpMatched {
|
||
|
log.Debug().Msgf("There is no handler for message: %s", update.Message.Text)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (r *Router) handleGroupRequest(update *telegram.Update) {
|
||
|
r.handleRequest(update, r.groupCommands, r.groupRegulars)
|
||
|
}
|
||
|
|
||
|
func (r *Router) handlePrivateRequest(update *telegram.Update) {
|
||
|
r.handleRequest(update, r.privateCommands, r.privateRegulars)
|
||
|
}
|
||
|
|
||
|
// RegisterPrivateCommand adds function to private commands list
|
||
|
func (r *Router) RegisterPrivateCommand(command string, handleFunc func(update *telegram.Update)) {
|
||
|
log.Debug().Msgf("Registering handler for private command /%s", command)
|
||
|
r.privateCommands[command] = handleFunc
|
||
|
}
|
||
|
|
||
|
// RegisterPrivateRegexp adds function to private regexp list
|
||
|
func (r *Router) RegisterPrivateRegexp(rxp *regexp.Regexp, handleFunc func(update *telegram.Update)) {
|
||
|
log.Debug().Msgf("Registering handler for regular expresson: %s", strings.Replace(rxp.String(), "\n", "\\n", -1))
|
||
|
r.privateRegulars[rxp] = handleFunc
|
||
|
}
|
||
|
|
||
|
// RegisterGroupCommand adds function to group commands list
|
||
|
func (r *Router) RegisterGroupCommand(command string, handleFunc func(update *telegram.Update)) {
|
||
|
log.Debug().Msgf("Registering handler for group command /%s", command)
|
||
|
r.groupCommands[command] = handleFunc
|
||
|
}
|
||
|
|
||
|
// RegisterGroupRegexp adds function to group regexp list
|
||
|
func (r *Router) RegisterGroupRegexp(rxp *regexp.Regexp, handleFunc func(update *telegram.Update)) {
|
||
|
log.Debug().Msgf("Registering handler for regular expresson: %s", strings.Replace(rxp.String(), "\n", "\\n", -1))
|
||
|
r.groupRegulars[rxp] = handleFunc
|
||
|
}
|
||
|
|
||
|
// RegisterInlineQueryResult adds function to list of inline queries
|
||
|
func (r *Router) RegisterInlineQueryResult(rxp *regexp.Regexp, handleFunc func(update *telegram.Update)) {
|
||
|
log.Debug().Msgf("Registering handler for inline regular expresson: %s", strings.Replace(rxp.String(), "\n", "\\n", -1))
|
||
|
r.inlineQueries[rxp] = handleFunc
|
||
|
}
|
||
|
|
||
|
// Respond searches for appropriative answer to the request and passes request to found function
|
||
|
// If none of the functions can handle this request, it will be warned in log file
|
||
|
func (r *Router) Respond(update telegram.Update) {
|
||
|
switch {
|
||
|
case update.Message != nil:
|
||
|
if update.Message.Text != "" {
|
||
|
if update.Message.ForwardFrom != nil {
|
||
|
err := r.checkForward(&update)
|
||
|
if err != nil {
|
||
|
log.Warn().Err(err)
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
if update.Message.Chat.IsPrivate() {
|
||
|
r.handlePrivateRequest(&update)
|
||
|
} else if update.Message.Chat.IsGroup() || update.Message.Chat.IsSuperGroup() {
|
||
|
r.handleGroupRequest(&update)
|
||
|
} else {
|
||
|
log.Debug().Msg("Can't handle update")
|
||
|
}
|
||
|
} else {
|
||
|
log.Debug().Msg("Can't handle empty Message for now")
|
||
|
}
|
||
|
case update.InlineQuery != nil:
|
||
|
if update.InlineQuery.Query != "" {
|
||
|
r.handleInlineQuery(&update)
|
||
|
}
|
||
|
default:
|
||
|
log.Debug().Msg("Can't handle empty Message for now")
|
||
|
}
|
||
|
}
|