Files
trbot/utils/plugin_utils/handler_by_chatid.go

128 lines
3.7 KiB
Go

package plugin_utils
import (
"trbot/utils"
"trbot/utils/flaterr"
"trbot/utils/handler_params"
"trbot/utils/type/update_utils"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
type HandlerByChatID map[int64]map[string]ByChatIDHandler
/*
It is allowed to set multiple handlers,
and each handler will be triggered.
However, due to the nature of the map,
the execution order cannot be guaranteed.
*/
type ByChatIDHandler struct {
ForChatID int64 // 0 for all chats
PluginName string
UpdateHandler func(*handler_params.Update) error
}
func AddHandlerByChatIDHandlers(handlers ...ByChatIDHandler) int {
if AllPlugins.HandlerByChatID == nil { AllPlugins.HandlerByChatID = HandlerByChatID{} }
var handlerCount int
for _, handler := range handlers {
if handler.PluginName == "" || handler.UpdateHandler == nil {
log.Error().
Str(utils.GetCurrentFuncName()).
Str("pluginName", handler.PluginName).
Int64("forChatID", handler.ForChatID).
Msgf("Not enough parameters, skip this handler")
continue
}
if AllPlugins.HandlerByChatID[handler.ForChatID] == nil { AllPlugins.HandlerByChatID[handler.ForChatID] = map[string]ByChatIDHandler{} }
_, isExist := AllPlugins.HandlerByChatID[handler.ForChatID][handler.PluginName]
if isExist {
log.Error().
Str(utils.GetCurrentFuncName()).
Int64("forChatID", handler.ForChatID).
Str("name", handler.PluginName).
Msg("Duplicate plugin exists, registration skipped")
} else {
AllPlugins.HandlerByChatID[handler.ForChatID][handler.PluginName] = handler
handlerCount++
}
}
return handlerCount
}
func RemoveHandlerByChatIDHandler(chatID int64, pluginName string) {
if AllPlugins.HandlerByChatID == nil { return }
_, isExist := AllPlugins.HandlerByChatID[chatID][pluginName]
if isExist {
delete(AllPlugins.HandlerByChatID[chatID], pluginName)
}
}
func RunByChatIDHandlers(params *handler_params.Update) (int, error) {
if AllPlugins.HandlerByChatID == nil { return 0, nil }
var handlerRunCount int
var handlerErr flaterr.MultErr
updateType := update_utils.GetUpdateType(params.Update)
FromID := update_utils.GetUpdateFromID(params.Update)
logger := zerolog.Ctx(params.Ctx).
With().
Str(utils.GetCurrentFuncName()).
Str("updateType", updateType.Str()).
Logger()
for name, handler := range AllPlugins.HandlerByChatID[FromID] {
slogger := logger.With().
Str("handlerName", name).
Int64("forChatID", handler.ForChatID).
Logger()
if handler.UpdateHandler != nil {
slogger.Info().Msg("Hit by chat ID handler")
handlerRunCount++
err := handler.UpdateHandler(params)
if err != nil {
slogger.Error().
Err(err).
Msg("Error in by chat ID handler")
handlerErr.Addf("Error in by chat ID handler [%s]: %w", name, err)
}
} else {
slogger.Warn().Msg("Hit by chat ID handler, but this handler function is nil, skip")
handlerErr.Addf("hit by chat ID handler [%s], but this handler function is nil, skip", name)
}
}
for name, handler := range AllPlugins.HandlerByChatID[0] {
slogger := logger.With().
Str("handlerName", name).
Int64("forChatID", handler.ForChatID).
Logger()
if handler.UpdateHandler != nil {
slogger.Info().Msg("Hit by chat ID handler for any chat")
handlerRunCount++
err := handler.UpdateHandler(params)
if err != nil {
slogger.Error().
Err(err).
Msg("Error in by chat ID handler for any chat")
handlerErr.Addf("Error in by chat ID handler for any chat [%s]: %w", name, err)
}
} else {
slogger.Warn().Msg("Hit by chat ID handler, but this handler function is nil, skip")
handlerErr.Addf("hit by chat ID handler [%s], but this handler function is nil, skip", name)
}
}
return handlerRunCount, handlerErr.Flat()
}