// 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") } }