Documentation
¶
Overview ¶
Code generated by go generate; DO NOT EDIT.
Code generated by go generate; DO NOT EDIT.
Index ¶
- Constants
- Variables
- func AddToReviewHistory(s *Session, historyType ReviewHistoryType, id int64)
- func RemoveFromReviewHistory(s *Session, historyType ReviewHistoryType, index int)
- type BotSettingKey
- type BufferKey
- type Info
- type Key
- type Manager
- func (m *Manager) CloseSession(ctx context.Context, session *Session, userID uint64, messageID uint64)
- func (m *Manager) GetActiveSessionCount(ctx context.Context) (uint64, error)
- func (m *Manager) GetActiveUsers(ctx context.Context) []uint64
- func (m *Manager) GetOrCreateSession(ctx context.Context, userID snowflake.ID, messageID uint64, ...) (*Session, bool, error)
- func (m *Manager) GetUserSessions(ctx context.Context, userID uint64, cleanupSelector bool) ([]Info, error)
- type NumericMetadata
- type NumericProcessor
- type ReviewHistoryType
- type Session
- type Setting
- type SettingRegistry
- type UserSettingKey
- type Validator
- type ValueGetter
- type ValueProcessor
- type ValueUpdater
- type ViewerAction
Constants ¶
const ( // Prefix is prepended to all session keys in Redis to namespace them // and avoid conflicts with other data stored in the same Redis instance. Prefix = "session:" // ScanBatchSize controls how many Redis keys are retrieved in each SCAN operation // when listing active sessions. This helps balance memory usage and performance. ScanBatchSize = 100 // MaxSessionsPerUser is the maximum number of sessions allowed per user. MaxSessionsPerUser = 3 )
const ( // TypeMetadataPrefix is used to prefix all type metadata fields. TypeMetadataPrefix = "__type:" // NumericTypeMeta is used to mark numeric fields that were converted to strings. NumericTypeMeta = "numeric" )
const ( // Timeout defines how long a session remains valid before expiring. // After this duration, Redis will automatically delete the session data. Timeout = 10 * time.Minute // ReviewerTimeout defines how long a reviewer's session remains valid. // Reviewers get a longer timeout due to their trusted status. ReviewerTimeout = 6 * time.Hour )
Variables ¶
var ( // UserID stores the user ID UserID = NewKey[uint64]("UserID", false) // IsGuildOwner indicates if the user is a guild owner IsGuildOwner = NewKey[bool]("IsGuildOwner", false) // ExistingSessions stores information about user's existing sessions ExistingSessions = NewKey[[]Info]("ExistingSessions", false) // LastUsed stores when the session was last accessed LastUsed = NewKey[time.Time]("LastUsed", true) // MessageID stores the ID of the current message MessageID = NewKey[uint64]("MessageID", true) // CurrentPage stores the current page identifier CurrentPage = NewKey[string]("CurrentPage", true) // PreviousPages stores the navigation history PreviousPages = NewKey[[]string]("PreviousPages", true) // PaginationPage stores the current pagination page number PaginationPage = NewKey[int]("PaginationPage", true) // PaginationOffset stores the starting offset PaginationOffset = NewKey[int]("PaginationOffset", true) // PaginationTotalItems stores the total number of items PaginationTotalItems = NewKey[int]("PaginationTotalItems", true) // PaginationTotalPages stores the total number of pages PaginationTotalPages = NewKey[int]("PaginationTotalPages", true) // PaginationHasNextPage indicates if there is a next page PaginationHasNextPage = NewKey[bool]("PaginationHasNextPage", true) // PaginationHasPrevPage indicates if there is a previous page PaginationHasPrevPage = NewKey[bool]("PaginationHasPrevPage", true) // PaginationIsStreaming indicates if image streaming is active PaginationIsStreaming = NewKey[bool]("PaginationIsStreaming", true) // StatsIsRefreshed indicates if the data has been refreshed StatsIsRefreshed = NewKey[bool]("StatsIsRefreshed", true) // StatsUserCounts stores user statistics StatsUserCounts = NewKey[*types.UserCounts]("StatsUserCounts", true) // StatsGroupCounts stores group statistics StatsGroupCounts = NewKey[*types.GroupCounts]("StatsGroupCounts", true) // StatsActiveUsers stores the list of active reviewers StatsActiveUsers = NewKey[[]uint64]("StatsActiveUsers", true) // StatusWorkers stores worker status information StatusWorkers = NewKey[[]core.Status]("StatusWorkers", false) // SettingName stores the name of the current setting SettingName = NewKey[string]("SettingName", true) // SettingType stores the type of the current setting SettingType = NewKey[string]("SettingType", true) // SettingValue stores the setting value SettingValue = NewKey[*Setting]("SettingValue", true) // SettingDisplay stores the display value of the setting SettingDisplay = NewKey[string]("SettingDisplay", true) // SettingCustomID stores the custom identifier SettingCustomID = NewKey[string]("SettingCustomID", true) // UserTarget stores the currently selected user UserTarget = NewKey[*types.ReviewUser]("UserTarget", true) // UserFlaggedFriends stores flagged friends UserFlaggedFriends = NewKey[map[int64]*types.ReviewUser]("UserFlaggedFriends", true) // UserFlaggedGroups stores flagged groups UserFlaggedGroups = NewKey[map[int64]*types.ReviewGroup]("UserFlaggedGroups", true) // UserFriends stores the user's friend list UserFriends = NewKey[[]*apiTypes.ExtendedFriend]("UserFriends", true) // UserPresences stores friend presence information UserPresences = NewKey[map[int64]*apiTypes.UserPresenceResponse]("UserPresences", true) // UserGroups stores the list of groups UserGroups = NewKey[[]*apiTypes.UserGroupRoles]("UserGroups", true) // UserOutfits stores user outfits UserOutfits = NewKey[[]*apiTypes.Outfit]("UserOutfits", true) // UserFlaggedOutfits stores outfit names that appear in reason evidence UserFlaggedOutfits = NewKey[map[string]struct{}]("UserFlaggedOutfits", true) // UserDuplicateOutfitNames stores outfit names that have multiple instances UserDuplicateOutfitNames = NewKey[map[string]struct{}]("UserDuplicateOutfitNames", true) // UserReviewHistory stores IDs of previously reviewed users UserReviewHistory = NewKey[[]int64]("UserReviewHistory", true) // UserReviewHistoryIndex stores the current position in the review history UserReviewHistoryIndex = NewKey[int]("UserReviewHistoryIndex", true) // GroupTarget stores the currently selected group GroupTarget = NewKey[*types.ReviewGroup]("GroupTarget", true) // GroupInfo stores additional group information GroupInfo = NewKey[*apiTypes.GroupResponse]("GroupInfo", true) // GroupFlaggedMembersCount stores the total number of flagged members in the current group GroupFlaggedMembersCount = NewKey[int]("GroupFlaggedMembersCount", true) // GroupPageFlaggedMembers stores flagged member details for the current page GroupPageFlaggedMembers = NewKey[map[int64]*types.ReviewUser]("GroupPageFlaggedMembers", true) // GroupPageFlaggedMemberIDs stores flagged member IDs for the current page GroupPageFlaggedMemberIDs = NewKey[[]int64]("GroupPageFlaggedMemberIDs", true) // GroupReviewHistory stores IDs of previously reviewed groups GroupReviewHistory = NewKey[[]int64]("GroupReviewHistory", true) // GroupReviewHistoryIndex stores the current position in the review history GroupReviewHistoryIndex = NewKey[int]("GroupReviewHistoryIndex", true) // ReasonsChanged indicates if reasons have been modified ReasonsChanged = NewKey[bool]("ReasonsChanged", true) // OriginalUserReasons stores the initial user reasons OriginalUserReasons = NewKey[types.Reasons[enum.UserReasonType]]("OriginalUserReasons", true) // OriginalGroupReasons stores the initial group reasons OriginalGroupReasons = NewKey[types.Reasons[enum.GroupReasonType]]("OriginalGroupReasons", true) // UnsavedUserReasons tracks which user reason types have been modified but not saved UnsavedUserReasons = NewKey[map[enum.UserReasonType]struct{}]("UnsavedUserReasons", true) // UnsavedGroupReasons tracks which group reason types have been modified but not saved UnsavedGroupReasons = NewKey[map[enum.GroupReasonType]struct{}]("UnsavedGroupReasons", true) // SelectedReasonType stores the currently selected reason type for modal handling SelectedReasonType = NewKey[string]("SelectedReasonType", true) // ReviewLogs stores the current review logs ReviewLogs = NewKey[[]*types.ActivityLog]("ReviewLogs", true) // ReviewLogsHasMore indicates if there are more logs available ReviewLogsHasMore = NewKey[bool]("ReviewLogsHasMore", true) // ReviewComments stores comments for the current user or group ReviewComments = NewKey[[]*types.Comment]("ReviewComments", true) // QueueStats stores queue statistics QueueStats = NewKey[*cloudflare.Stats]("QueueStats", true) // QueuedUserID stores the ID of the currently queued user QueuedUserID = NewKey[int64]("QueuedUserID", true) // QueuedUserTimestamp stores when the user was queued QueuedUserTimestamp = NewKey[time.Time]("QueuedUserTimestamp", true) // QueuedUserProcessing indicates if the user is being processed QueuedUserProcessing = NewKey[bool]("QueuedUserProcessing", true) // QueuedUserProcessed indicates if the user has been processed QueuedUserProcessed = NewKey[bool]("QueuedUserProcessed", true) // QueuedUserFlagged indicates if the processed user was flagged QueuedUserFlagged = NewKey[bool]("QueuedUserFlagged", true) // DiscordUserLookupID stores the Discord user ID being looked up DiscordUserLookupID = NewKey[uint64]("DiscordUserLookupID", true) // DiscordUserLookupName stores the Discord username DiscordUserLookupName = NewKey[string]("DiscordUserLookupName", true) // DiscordUserGuilds stores a Discord user's guild memberships DiscordUserGuilds = NewKey[[]*types.UserGuildInfo]("DiscordUserGuilds", true) // DiscordUserGuildNames stores guild names for a Discord user DiscordUserGuildNames = NewKey[map[uint64]string]("DiscordUserGuildNames", true) // DiscordUserMessageSummary stores the user's inappropriate message summary DiscordUserMessageSummary = NewKey[*types.InappropriateUserSummary]("DiscordUserMessageSummary", true) // DiscordUserTotalGuilds stores the total number of flagged guilds for the user DiscordUserTotalGuilds = NewKey[int]("DiscordUserTotalGuilds", true) // GuildLookupCursor stores the current guild lookup cursor GuildLookupCursor = NewKey[*types.GuildCursor]("GuildLookupCursor", true) // GuildLookupNextCursor stores the next guild lookup cursor GuildLookupNextCursor = NewKey[*types.GuildCursor]("GuildLookupNextCursor", true) // GuildLookupPrevCursors stores previous guild lookup cursors GuildLookupPrevCursors = NewKey[[]*types.GuildCursor]("GuildLookupPrevCursors", true) // DiscordUserMessages stores the current page of messages DiscordUserMessages = NewKey[[]*types.InappropriateMessage]("DiscordUserMessages", true) // DiscordUserMessageCursor stores the current message cursor DiscordUserMessageCursor = NewKey[*types.MessageCursor]("DiscordUserMessageCursor", true) // DiscordUserMessageNextCursor stores the next message cursor DiscordUserMessageNextCursor = NewKey[*types.MessageCursor]("DiscordUserMessageNextCursor", true) // DiscordUserMessagePrevCursors stores previous message cursors DiscordUserMessagePrevCursors = NewKey[[]*types.MessageCursor]("DiscordUserMessagePrevCursors", true) // DiscordUserMessageGuildID stores the currently selected guild ID for messages DiscordUserMessageGuildID = NewKey[uint64]("DiscordUserMessageGuildID", true) // DiscordUserDataRedacted indicates if the user has requested data deletion DiscordUserDataRedacted = NewKey[bool]("DiscordUserDataRedacted", true) // DiscordUserMessageGuilds stores a map of guild IDs where the user has inappropriate messages DiscordUserMessageGuilds = NewKey[map[uint64]struct{}]("DiscordUserMessageGuilds", true) // ChatContext stores structured context and message history ChatContext = NewKey[ai.ChatContext]("ChatContext", true) // ChatStreamingMessage stores the current streaming message content ChatStreamingMessage = NewKey[string]("ChatStreamingMessage", true) // LogActivities stores activity logs LogActivities = NewKey[[]*types.ActivityLog]("LogActivities", true) // LogCursor stores the current log cursor LogCursor = NewKey[*types.LogCursor]("LogCursor", true) // LogNextCursor stores the next log cursor LogNextCursor = NewKey[*types.LogCursor]("LogNextCursor", true) // LogPrevCursors stores previous log cursors LogPrevCursors = NewKey[[]*types.LogCursor]("LogPrevCursors", true) // LogFilterGuildID stores guild ID filter LogFilterGuildID = NewKey[uint64]("LogFilterGuildID", true) // LogFilterDiscordID stores Discord ID filter LogFilterDiscordID = NewKey[uint64]("LogFilterDiscordID", true) // LogFilterUserID stores user ID filter LogFilterUserID = NewKey[int64]("LogFilterUserID", true) // LogFilterGroupID stores group ID filter LogFilterGroupID = NewKey[int64]("LogFilterGroupID", true) // LogFilterReviewerID stores reviewer ID filter LogFilterReviewerID = NewKey[uint64]("LogFilterReviewerID", true) // LogFilterActivityType stores activity type filter LogFilterActivityType = NewKey[enum.ActivityType]("LogFilterActivityType", true) // LogFilterActivityCategory stores the currently selected activity category LogFilterActivityCategory = NewKey[string]("LogFilterActivityCategory", true) // LogFilterDateRangeStart stores start date filter LogFilterDateRangeStart = NewKey[time.Time]("LogFilterDateRangeStart", true) // LogFilterDateRangeEnd stores end date filter LogFilterDateRangeEnd = NewKey[time.Time]("LogFilterDateRangeEnd", true) // VerifyUserID stores the user ID being verified VerifyUserID = NewKey[uint64]("VerifyUserID", true) // VerifyReason stores the verification reason VerifyReason = NewKey[string]("VerifyReason", true) // VerifyCode stores the verification code VerifyCode = NewKey[string]("VerifyCode", true) // CaptchaAnswer stores the CAPTCHA answer CaptchaAnswer = NewKey[string]("CaptchaAnswer", true) // AdminAction stores the current admin action AdminAction = NewKey[string]("AdminAction", true) // AdminActionID stores the admin action ID AdminActionID = NewKey[string]("AdminActionID", true) // AdminReason stores the admin action reason AdminReason = NewKey[string]("AdminReason", true) // ReviewerStats stores reviewer statistics ReviewerStats = NewKey[map[uint64]*types.ReviewerStats]("ReviewerStats", true) // ReviewerUsernames stores usernames for reviewers ReviewerUsernames = NewKey[map[uint64]string]("ReviewerUsernames", true) // ReviewerStatsCursor stores the current reviewer stats cursor ReviewerStatsCursor = NewKey[*types.ReviewerStatsCursor]("ReviewerStatsCursor", true) // ReviewerStatsNextCursor stores the next reviewer stats cursor ReviewerStatsNextCursor = NewKey[*types.ReviewerStatsCursor]("ReviewerStatsNextCursor", true) // ReviewerStatsPrevCursors stores previous reviewer stats cursors ReviewerStatsPrevCursors = NewKey[[]*types.ReviewerStatsCursor]("ReviewerStatsPrevCursors", true) // ReviewerStatsLastRefresh stores the last refresh time ReviewerStatsLastRefresh = NewKey[time.Time]("ReviewerStatsLastRefresh", true) // ReviewerStatsNextRefresh stores the next refresh time ReviewerStatsNextRefresh = NewKey[time.Time]("ReviewerStatsNextRefresh", true) // GuildScanType stores the type of guild scan selected (messages or servers) GuildScanType = NewKey[string]("GuildScanType", true) // GuildStatsID stores the current guild ID GuildStatsID = NewKey[uint64]("GuildStatsID", true) // GuildStatsName stores the current guild name GuildStatsName = NewKey[string]("GuildStatsName", true) // GuildStatsUniqueGuilds stores the count of unique guilds in the database GuildStatsUniqueGuilds = NewKey[int]("GuildStatsUniqueGuilds", false) // GuildStatsUniqueUsers stores the count of unique users in the database GuildStatsUniqueUsers = NewKey[int]("GuildStatsUniqueUsers", false) // GuildStatsInappropriateUsers stores the count of users with inappropriate messages GuildStatsInappropriateUsers = NewKey[int]("GuildStatsInappropriateUsers", false) // GuildScanGuildNames stores guild names for flagged users GuildScanGuildNames = NewKey[map[uint64]string]("GuildScanGuildNames", true) // GuildScanUserGuilds stores users and their guilds GuildScanUserGuilds = NewKey[map[uint64][]*types.UserGuildInfo]("GuildScanUserGuilds", true) // GuildScanMessageSummaries stores message summaries for users GuildScanMessageSummaries = NewKey[map[uint64]*types.InappropriateUserSummary]("GuildScanMessageSummaries", true) // GuildScanFilteredUsers stores users filtered by criteria GuildScanFilteredUsers = NewKey[map[uint64][]*types.UserGuildInfo]("GuildScanFilteredUsers", true) // GuildScanFilteredSummaries stores filtered message summaries GuildScanFilteredSummaries = NewKey[map[uint64]*types.InappropriateUserSummary]("GuildScanFilteredSummaries", true) // GuildScanMinGuilds stores the minimum guilds filter value GuildScanMinGuilds = NewKey[int]("GuildScanMinGuilds", true) // GuildScanMinJoinDuration stores the minimum join duration filter value GuildScanMinJoinDuration = NewKey[time.Duration]("GuildScanMinJoinDuration", true) // GuildBanLogs stores guild ban operation logs GuildBanLogs = NewKey[[]*types.GuildBanLog]("GuildBanLogs", true) // GuildBanLogCursor stores the current guild ban log cursor GuildBanLogCursor = NewKey[*types.LogCursor]("GuildBanLogCursor", true) // GuildBanLogNextCursor stores the next guild ban log cursor GuildBanLogNextCursor = NewKey[*types.LogCursor]("GuildBanLogNextCursor", true) // GuildBanLogPrevCursors stores previous guild ban log cursors GuildBanLogPrevCursors = NewKey[[]*types.LogCursor]("GuildBanLogPrevCursors", true) // GuildBanLogCSVReport stores the ID of the ban log that has a CSV report attached GuildBanLogCSVReport = NewKey[int64]("GuildBanLogCSVReport", true) // CaptchaImageBuffer stores binary image data for CAPTCHA verification CaptchaImageBuffer = NewBufferKey("CaptchaImageBuffer", true) // ImageBuffer stores binary image data ImageBuffer = NewBufferKey("ImageBuffer", true) )
var ( ErrSessionLimitReached = errors.New("session limit reached") ErrSessionNotFound = errors.New("session not found") ErrFailedToLoadSettings = errors.New("failed to load settings") ErrFailedToGetSession = errors.New("failed to get session data") ErrFailedToParseSession = errors.New("failed to parse session data") )
var ( ErrInvalidNumber = errors.New("value must be a valid number") ErrInvalidIDFormat = errors.New("invalid Discord ID format") ErrSelfAssignment = errors.New("you cannot add/remove yourself") ErrInvalidOption = errors.New("invalid option selected") ErrInvalidBoolValue = errors.New("value must be true or false") ErrWelcomeMessageTooLong = errors.New("welcome message cannot exceed 512 characters") ErrAnnouncementTooLong = errors.New("announcement message cannot exceed 512 characters") ErrNotReviewer = errors.New("you are not an official reviewer") ErrMissingInput = errors.New("missing input") )
Validation errors.
var ( // StreamerMode controls streamer-friendly display UserStreamerMode = NewUserSettingKey("StreamerMode", func(s *Session) bool { return s.userSettings.StreamerMode }, func(s *Session, value bool) { s.userSettings.StreamerMode = value s.userSettingsUpdate = true }) // UserDefaultSort sets default user review sorting UserUserDefaultSort = NewUserSettingKey("UserDefaultSort", func(s *Session) enum.ReviewSortBy { return s.userSettings.UserDefaultSort }, func(s *Session, value enum.ReviewSortBy) { s.userSettings.UserDefaultSort = value s.userSettingsUpdate = true }) // GroupDefaultSort sets default group review sorting UserGroupDefaultSort = NewUserSettingKey("GroupDefaultSort", func(s *Session) enum.ReviewSortBy { return s.userSettings.GroupDefaultSort }, func(s *Session, value enum.ReviewSortBy) { s.userSettings.GroupDefaultSort = value s.userSettingsUpdate = true }) // ChatModel sets the AI chat model UserChatModel = NewUserSettingKey("ChatModel", func(s *Session) enum.ChatModel { return s.userSettings.ChatModel }, func(s *Session, value enum.ChatModel) { s.userSettings.ChatModel = value s.userSettingsUpdate = true }) // ReviewMode sets the review mode UserReviewMode = NewUserSettingKey("ReviewMode", func(s *Session) enum.ReviewMode { return s.userSettings.ReviewMode }, func(s *Session, value enum.ReviewMode) { s.userSettings.ReviewMode = value s.userSettingsUpdate = true }) // ReviewTargetMode sets the review target mode UserReviewTargetMode = NewUserSettingKey("ReviewTargetMode", func(s *Session) enum.ReviewTargetMode { return s.userSettings.ReviewTargetMode }, func(s *Session, value enum.ReviewTargetMode) { s.userSettings.ReviewTargetMode = value s.userSettingsUpdate = true }) // ReviewerStatsPeriod sets the reviewer stats time period UserReviewerStatsPeriod = NewUserSettingKey("ReviewerStatsPeriod", func(s *Session) enum.ReviewerStatsPeriod { return s.userSettings.ReviewerStatsPeriod }, func(s *Session, value enum.ReviewerStatsPeriod) { s.userSettings.ReviewerStatsPeriod = value s.userSettingsUpdate = true }) // ChatMessageUsageFirstMessageTime tracks first message time in 24h period UserChatMessageUsageFirstMessageTime = NewUserSettingKey("ChatMessageUsage.FirstMessageTime", func(s *Session) time.Time { return s.userSettings.ChatMessageUsage.FirstMessageTime }, func(s *Session, value time.Time) { s.userSettings.ChatMessageUsage.FirstMessageTime = value s.userSettingsUpdate = true }) // ChatMessageUsageMessageCount tracks message count in 24h period UserChatMessageUsageMessageCount = NewUserSettingKey("ChatMessageUsage.MessageCount", func(s *Session) int { return s.userSettings.ChatMessageUsage.MessageCount }, func(s *Session, value int) { s.userSettings.ChatMessageUsage.MessageCount = value s.userSettingsUpdate = true }) // CaptchaUsageCaptchaReviewCount tracks reviews since last CAPTCHA UserCaptchaUsageCaptchaReviewCount = NewUserSettingKey("CaptchaUsage.CaptchaReviewCount", func(s *Session) int { return s.userSettings.CaptchaUsage.CaptchaReviewCount }, func(s *Session, value int) { s.userSettings.CaptchaUsage.CaptchaReviewCount = value s.userSettingsUpdate = true }) // ReviewBreakNextReviewTime tracks when user can resume reviewing UserReviewBreakNextReviewTime = NewUserSettingKey("ReviewBreak.NextReviewTime", func(s *Session) time.Time { return s.userSettings.ReviewBreak.NextReviewTime }, func(s *Session, value time.Time) { s.userSettings.ReviewBreak.NextReviewTime = value s.userSettingsUpdate = true }) // ReviewBreakReviewCount tracks reviews in current window UserReviewBreakReviewCount = NewUserSettingKey("ReviewBreak.ReviewCount", func(s *Session) int { return s.userSettings.ReviewBreak.ReviewCount }, func(s *Session, value int) { s.userSettings.ReviewBreak.ReviewCount = value s.userSettingsUpdate = true }) // ReviewBreakWindowStartTime tracks start of current review window UserReviewBreakWindowStartTime = NewUserSettingKey("ReviewBreak.WindowStartTime", func(s *Session) time.Time { return s.userSettings.ReviewBreak.WindowStartTime }, func(s *Session, value time.Time) { s.userSettings.ReviewBreak.WindowStartTime = value s.userSettingsUpdate = true }) // ReviewerIDs stores authorized reviewer IDs BotReviewerIDs = NewBotSettingKey("ReviewerIDs", func(s *Session) []uint64 { return s.botSettings.ReviewerIDs }, func(s *Session, value []uint64) { s.botSettings.ReviewerIDs = value s.botSettings.ReviewerMap = nil s.botSettingsUpdate = true }) // AdminIDs stores authorized admin IDs BotAdminIDs = NewBotSettingKey("AdminIDs", func(s *Session) []uint64 { return s.botSettings.AdminIDs }, func(s *Session, value []uint64) { s.botSettings.AdminIDs = value s.botSettings.AdminMap = nil s.botSettingsUpdate = true }) // SessionLimit sets maximum concurrent sessions BotSessionLimit = NewBotSettingKey("SessionLimit", func(s *Session) uint64 { return s.botSettings.SessionLimit }, func(s *Session, value uint64) { s.botSettings.SessionLimit = value s.botSettingsUpdate = true }) // WelcomeMessage sets the welcome message BotWelcomeMessage = NewBotSettingKey("WelcomeMessage", func(s *Session) string { return s.botSettings.WelcomeMessage }, func(s *Session, value string) { s.botSettings.WelcomeMessage = value s.botSettingsUpdate = true }) // AnnouncementType sets the announcement type BotAnnouncementType = NewBotSettingKey("Announcement.Type", func(s *Session) enum.AnnouncementType { return s.botSettings.Announcement.Type }, func(s *Session, value enum.AnnouncementType) { s.botSettings.Announcement.Type = value s.botSettingsUpdate = true }) // AnnouncementMessage sets the announcement message BotAnnouncementMessage = NewBotSettingKey("Announcement.Message", func(s *Session) string { return s.botSettings.Announcement.Message }, func(s *Session, value string) { s.botSettings.Announcement.Message = value s.botSettingsUpdate = true }) )
Functions ¶
func AddToReviewHistory ¶
func AddToReviewHistory(s *Session, historyType ReviewHistoryType, id int64)
AddToReviewHistory adds an ID to the specified review history and updates the index in the session. It trims the history if it exceeds the maximum size.
func RemoveFromReviewHistory ¶
func RemoveFromReviewHistory(s *Session, historyType ReviewHistoryType, index int)
RemoveFromReviewHistory removes an item at the specified index from the review history and adjusts the index accordingly.
Types ¶
type BotSettingKey ¶
type BotSettingKey[T any] struct { // contains filtered or unexported fields }
BotSettingKey represents a strongly typed key for bot settings.
func NewBotSettingKey ¶
func NewBotSettingKey[T any](name string, getter func(*Session) T, setter func(*Session, T)) BotSettingKey[T]
NewBotSettingKey creates a new bot setting key.
func (BotSettingKey[T]) Get ¶
func (k BotSettingKey[T]) Get(s *Session) T
Get retrieves the bot setting value.
func (BotSettingKey[T]) Set ¶
func (k BotSettingKey[T]) Set(s *Session, value T)
Set updates the bot setting value.
type BufferKey ¶
type BufferKey struct {
// contains filtered or unexported fields
}
BufferKey represents a key for binary data.
func NewBufferKey ¶
NewBufferKey creates a new buffer key.
type Info ¶
type Info struct {
MessageID uint64 `json:"messageId"`
PageName string `json:"pageName"`
LastUsed time.Time `json:"lastUsed"`
}
Info contains information about a user's session.
type Key ¶
type Key[T any] struct { // contains filtered or unexported fields }
Key represents a strongly typed session key for storing arbitrary data.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager manages the session lifecycle using Redis as the backing store. Sessions are prefixed and stored with automatic expiration.
func NewManager ¶
func NewManager(db database.Client, redisManager *redis.Manager, logger *zap.Logger) (*Manager, error)
NewManager creates a new session manager that uses Redis as the backing store.
func (*Manager) CloseSession ¶
func (m *Manager) CloseSession(ctx context.Context, session *Session, userID uint64, messageID uint64)
CloseSession removes a user's session from Redis immediately rather than waiting for expiration.
func (*Manager) GetActiveSessionCount ¶
GetActiveSessionCount returns the number of active sessions.
func (*Manager) GetActiveUsers ¶
GetActiveUsers scans Redis for all session keys and extracts the user IDs. Uses cursor-based scanning to handle large numbers of sessions.
type NumericMetadata ¶
type NumericMetadata struct {
// IsNumeric indicates if the string represents a numeric value
IsNumeric bool
// IsUint64 indicates if the string can be parsed as a uint64
IsUint64 bool
// IsInt64 indicates if the string can be parsed as an int64
IsInt64 bool
// IsFloat indicates if the string should remain as a float
IsFloat bool
}
NumericMetadata tracks information about numeric conversions to help determine whether values should be converted to integers or remain as strings.
type NumericProcessor ¶
type NumericProcessor struct{}
NumericProcessor encapsulates methods for handling numeric precision in data structures. This helps maintain precision for large integer values like uint64 during serialization.
func NewNumericProcessor ¶
func NewNumericProcessor() *NumericProcessor
NewNumericProcessor creates a new instance of the numeric processor.
func (*NumericProcessor) AnalyzeNumeric ¶
func (p *NumericProcessor) AnalyzeNumeric(s string) NumericMetadata
AnalyzeNumeric examines a string to determine its numeric properties.
func (*NumericProcessor) PreserveNumericPrecision ¶
func (p *NumericProcessor) PreserveNumericPrecision(data any) any
PreserveNumericPrecision recursively processes a data structure and converts json.Number and numeric strings to uint64 where appropriate, maintaining precision for large integer values.
type ReviewHistoryType ¶
type ReviewHistoryType int
ReviewHistoryType represents the type of review history being managed.
const ( UserReviewHistoryType ReviewHistoryType = iota GroupReviewHistoryType )
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session maintains user state through a Redis-backed key-value store where values are serialized as JSON strings. The session automatically expires after a configured timeout.
func NewSession ¶
func NewSession( userSettings *types.UserSetting, botSettings *types.BotSetting, db database.Client, redis rueidis.Client, key string, data map[string]any, logger *zap.Logger, ) *Session
NewSession creates a new session for the given user.
func (*Session) BotSettings ¶
func (s *Session) BotSettings() *types.BotSetting
BotSettings returns the current bot settings.
func (*Session) Close ¶
func (s *Session) Close()
Close marks the session as closed to prevent further updates.
func (*Session) Touch ¶
Touch serializes the session data to JSON and updates the TTL in Redis to prevent expiration. If serialization fails, the error is logged but the session continues.
func (*Session) UpdateData ¶
UpdateData replaces the session data with new data and updates the message ID.
func (*Session) UserSettings ¶
func (s *Session) UserSettings() *types.UserSetting
UserSettings returns the current user settings.
type Setting ¶
type Setting struct {
Key string `json:"key"` // Unique identifier for the setting
Name string `json:"name"` // Display name
Description string `json:"description"` // Help text explaining the setting
Type enum.SettingType `json:"type"` // Data type of the setting
DefaultValue any `json:"defaultValue"` // Default value
Options []types.SettingOption `json:"options"` // Available options for enum types
Validators []Validator `json:"-"` // Functions to validate input
ValueGetter ValueGetter `json:"-"` // Function to retrieve the value
ValueUpdater ValueUpdater `json:"-"` // Function to update the value
}
Setting defines the structure and behavior of a single setting.
type SettingRegistry ¶
type SettingRegistry struct {
UserSettings map[string]*Setting // User-specific settings
BotSettings map[string]*Setting // Bot-wide settings
}
SettingRegistry manages the available settings.
func NewSettingRegistry ¶
func NewSettingRegistry() *SettingRegistry
NewSettingRegistry creates and initializes the setting registry.
type UserSettingKey ¶
type UserSettingKey[T any] struct { // contains filtered or unexported fields }
UserSettingKey represents a strongly typed key for user settings.
func NewUserSettingKey ¶
func NewUserSettingKey[T any](name string, getter func(*Session) T, setter func(*Session, T)) UserSettingKey[T]
NewUserSettingKey creates a new user setting key.
func (UserSettingKey[T]) Get ¶
func (k UserSettingKey[T]) Get(s *Session) T
Get retrieves the user setting value.
func (UserSettingKey[T]) Set ¶
func (k UserSettingKey[T]) Set(s *Session, value T)
Set updates the user setting value.
type Validator ¶
Validator is a function that validates setting input. It takes the value to validate and the ID of the user making the change.
type ValueGetter ¶
ValueGetter is a function that retrieves the value of a setting.
type ValueProcessor ¶
type ValueProcessor struct{}
ValueProcessor encapsulates the logic for processing values before serialization. It converts special types like uint64 to string and properly handles embedded structs. It also skips zero-valued fields to optimize storage in Redis.
func NewValueProcessor ¶
func NewValueProcessor() *ValueProcessor
NewValueProcessor creates a new instance of the value processor.
func (*ValueProcessor) ProcessValue ¶
func (p *ValueProcessor) ProcessValue(value any) any
ProcessValue recursively processes complex data types for JSON serialization.
type ValueUpdater ¶
ValueUpdater is a function type where customID is provided to identify which action is being performed.
type ViewerAction ¶
type ViewerAction string
ViewerAction represents the type of page navigation action.
const ( // ViewerFirstPage moves to the first available page. ViewerFirstPage ViewerAction = "first_page" // ViewerPrevPage moves to the previous page if available. ViewerPrevPage ViewerAction = "prev_page" // ViewerNextPage moves to the next page if available. ViewerNextPage ViewerAction = "next_page" // ViewerLastPage moves to the last available page. ViewerLastPage ViewerAction = "last_page" )
Navigation actions for moving between pages in a paginated view.
func (ViewerAction) ParsePageAction ¶
func (h ViewerAction) ParsePageAction(s *Session, maxPage int) int
ParsePageAction updates the session's pagination page based on the requested action. Returns the new page number and true if the action was valid, or 0 and false if invalid. The maxPage parameter prevents navigation beyond the available pages.