Archived
1
This repository has been archived on 2022-11-04. You can view files and clone it, but cannot push or open issues or pull requests.
fwzookeeper/internal/router/router.go
Vladimir Hodakov 5820a37326
Add LICENSE and first command
This commit may be used as template for making any new Telegram bots.
Just check out it, change your variables and start developing new
shiny bot!

Maybe I need to create bot generator...
2018-11-29 20:51:36 +04:00

147 lines
4.7 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 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 handleInlineQuery(update *telegram.Update) {
rxpMatched := false
for rxp, function := range router.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 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 handleGroupRequest(update *telegram.Update) {
handleRequest(update, router.groupCommands, router.groupRegulars)
}
func handlePrivateRequest(update *telegram.Update) {
handleRequest(update, router.privateCommands, router.privateRegulars)
}
// RegisterPrivateCommand adds function to private commands list
func RegisterPrivateCommand(command string, handleFunc func(update *telegram.Update)) {
log.Debug().Msgf("Registering handler for private command /%s", command)
router.privateCommands[command] = handleFunc
}
// RegisterPrivateRegexp adds function to private regexp list
func 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))
router.privateRegulars[rxp] = handleFunc
}
// RegisterGroupCommand adds function to group commands list
func RegisterGroupCommand(command string, handleFunc func(update *telegram.Update)) {
log.Debug().Msgf("Registering handler for group command /%s", command)
router.groupCommands[command] = handleFunc
}
// RegisterGroupRegexp adds function to group regexp list
func 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))
router.groupRegulars[rxp] = handleFunc
}
// RegisterInlineQueryResult adds function to list of inline queries
func 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))
router.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 Respond(update telegram.Update) {
switch {
case update.Message != nil:
if update.Message.Text != "" {
if update.Message.ForwardFrom != nil {
err := checkForward(&update)
if err != nil {
log.Warn().Err(err)
return
}
}
if update.Message.Chat.IsPrivate() {
handlePrivateRequest(&update)
} else if update.Message.Chat.IsGroup() || update.Message.Chat.IsSuperGroup() {
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 != "" {
handleInlineQuery(&update)
}
default:
log.Debug().Msg("Can't handle empty Message for now")
}
}