-
-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
Auto-generated from source code comments.
- IGiveawayCPH
- Loc
- MetricsContainer
- ProfileMetrics
- UserMetrics
- MetricsService
- UserMetricSet
- IGiveawayEvent
- IEventBus
- EventBus
- GiveawayStartedEvent
- GiveawayEndedEvent
- WinnerDrawnEvent
- WheelReadyEvent
- EntryAcceptedEvent
- EntryRejectedEvent
- ToastNotificationEvent
- ChatMessageEvent
- ObsUpdateEvent
- MetricsUpdatedEvent
- ConfigReloadedEvent
- GiveawayManager
- TriggerResult
- TriggerInspector
- PersistenceService
- FileLogger
- EntryValidator
- GiveawayBotConfig
- GlobalSettings
- GiveawayProfileConfig
- BotListenerRule
- WheelConfig
- GiveawayState
- Entry
- WheelOfNamesClient
- MultiPlatformMessenger
- ObsController
- UserMetricSet
- UpdateService
Interface wrapper for Streamer.bot's
CPHobject. Allows us to mock the CPH interaction for unit testing outside of Streamer.bot. This abstraction is crucial for maintaining testability and decoupling the bot logic from the runtime environment.
void LogInfo(string message)Logs an informational message to the Streamer.bot log.
void LogWarn(string message)Logs a warning message to the Streamer.bot log.
void LogDebug(string message)Logs a debug message to the Streamer.bot log (requires verbose logging).
void LogError(string message)Logs an error message to the Streamer.bot log.
void LogTrace(string message)Logs a trace message for deep debugging.
void LogVerbose(string message)Logs a verbose message.
void LogFatal(string message)Logs a fatal error message, typically indicating a crash or critical failure.
bool TryGetArg<T>(string argName, out T value)Attempts to retrieving an argument from the action's argument dictionary.
| Parameter | Description |
|---|---|
| argName | The key name of the argument. |
| value | The output value if found. |
Returns: True if found and successfully converted, otherwise false.
T GetGlobalVar<T>(string varName, bool persisted = true)Retrieves a global variable from Streamer.bot's persistent store.
void SetGlobalVar(string varName, object value, bool persisted = true)Sets a global variable in Streamer.bot's persistent store.
T GetUserVar<T>(string userId, string varName, bool persisted = true)Retrieves a user-specific variable.
void SetUserVar(string userId, string varName, object value, bool persisted = true)Sets a user-specific variable.
List<string> GetGlobalVarNames(bool persisted = true)Gets a list of all global variable names (used for cleanup).
void UnsetGlobalVar(string varName, bool persisted = true)Removes a global variable from the store.
void SendMessage(string message, bool bot = true)Sends a chat message to the active platform (Twitch/YouTube/Kick).
void SendYouTubeMessage(string message)Sends a chat message specifically to YouTube.
void SendKickMessage(string message)Sends a chat message specifically to Kick.
void TwitchReplyToMessage(string message, string replyId, bool useBot = true, bool fallback = true)Replies to a specific message on Twitch.
bool IsTwitchLive()Checks if the Twitch broadcaster is live.
bool IsYouTubeLive()Checks if the YouTube broadcaster is live.
bool IsKickLive()Checks if the Kick broadcaster is live.
bool TwitchIsUserFollower(string userId)Checks if a user is following the channel on Twitch.
bool TwitchIsUserSubscriber(string userId)Checks if a user is subscribed to the channel on Twitch.
void ObsSetBrowserSource(string scene, string source, string url)Updates a browser source URL in OBS via Streamer.bot.
void ShowToastNotification(string title, string message)Shows a Windows toast notification via Streamer.bot.
bool RunAction(string actionName, bool runImmediately = true)Executes another Streamer.bot action by name.
object GetEventType()Gets the event trigger type.
public bool Execute()Entry point for the Streamer.bot Action. This method is called every time the action is triggered. It ensures the manager is initialized and then processes the current trigger.
Static Localization Helper. Manages default strings and user overrides from config.
public const string ToastTitle = "ToastTitle"Common toast title localization key. Use this constant instead of hardcoding "ToastTitle" string.
public static string Get(string key, params object[] args)Gets a localized string for the specified key, with optional formatting arguments. Uses global custom strings and defaults (no profile-specific override).
| Parameter | Description |
|---|---|
| key | Localization key to retrieve |
| args | Optional formatting arguments for placeholders like {0}, {1}, etc. |
Returns: Formatted localized string
public static string GetGlobal(string key, params object[] args)Gets a global localized string, explicitly bypassing profile-specific overrides. Use this for system messages (like update notifications) that should always use the same text regardless of which giveaway profile is active.
| Parameter | Description |
|---|---|
| key | Localization key to retrieve |
| args | Optional formatting arguments for placeholders like {0}, {1}, etc. |
Returns: Formatted localized string from global custom strings or defaults
public static string Get(string key, string profileName, params object[] args)Gets a localized string with optional profile-specific override support. Resolution order: profile messages → global custom strings → defaults.
| Parameter | Description |
|---|---|
| key | Localization key to retrieve |
| profileName | Optional profile name for profile-specific message lookup |
| args | Optional formatting arguments for placeholders like {0}, {1}, etc. |
Returns: Formatted localized string
Represents aggregated metrics data across all giveaway profiles.
public string ToJson()Serializes metrics to JSON string.
public static MetricsContainer FromGlobalVars(CPHAdapter adapter)Loads aggregated metrics from global variables.
Metrics for a specific giveaway profile.
Metrics for a specific user.
Service for tracking and aggregating giveaway metrics. Provides cross-profile analytics and per-user statistics.
public MetricsContainer GetGlobalMetrics(CPHAdapter adapter)Gets aggregated metrics across all profiles.
public ProfileMetrics GetProfileMetrics(string profileName, CPHAdapter adapter)Gets metrics for a specific profile.
public UserMetrics GetUserMetrics(string userId, CPHAdapter adapter)Gets metrics for a specific user.
public void RecordEntry(string profileName, string userId, CPHAdapter adapter)Records an entry for a user in a specific profile.
public void RecordWin(string profileName, string userId, CPHAdapter adapter)Records a win for a user in a specific profile.
public void RecordDraw(string profileName, CPHAdapter adapter)Records a draw execution for a specific profile.
Legacy diagnostic metric set for a user (backward compatibility).
public MetricsService()Initializes file path for diagnostic metrics persistence.
public void SaveMetrics(CPHAdapter adapter, MetricsContainer metrics)Saves diagnostic metrics data to JSON file.
public MetricsContainer LoadMetrics(CPHAdapter adapter)Loads diagnostic metrics data from JSON file.
Base interface for all giveaway events.
CPHAdapter Adapter { get; }CPH adapter context for this event.
string ProfileName { get; }Profile name associated with this event.
DateTime Timestamp { get; }Timestamp when the event was created.
Event Bus interface for decoupled communication.
void Subscribe<T>(Action<T> handler) where T : IGiveawayEventSubscribes a handler to a specific event type.
| Parameter | Description |
|---|---|
| handler | The action to execute when the event is published. |
void Unsubscribe<T>(Action<T> handler) where T : IGiveawayEventUnsubscribes a handler from a specific event type.
| Parameter | Description |
|---|---|
| handler | The handler to remove. |
void Publish<T>(T evt) where T : IGiveawayEventPublishes an event to all subscribed handlers.
| Parameter | Description |
|---|---|
| evt | The event instance to publish. |
Thread-safe Event Bus implementation for pub/sub event handling. Isolates handler exceptions to prevent cascading failures.
Event published when a giveaway is started/opened.
Event published when a giveaway is ended/closed.
Event published when a winner is drawn.
Event published when Wheel of Names URL is ready.
Event published when an entry is successfully accepted.
Event published when an entry is rejected.
Event requesting a toast notification.
Event requesting a chat broadcast.
Event requesting an OBS scene/source update.
Event published when metrics are updated.
Event published when configuration is reloaded.
Core logic manager for the Giveaway Bot. Handles configuration loading, state management, trigger routing, and command execution.
public static GiveawayBotConfig GlobalConfigGets or sets the globally shared configuration object. This is static to allow access from helper classes (like CPHAdapter logs), but effectively owned by the singleton GiveawayManager.
public static GiveawayBotConfig StaticConfig => _globalConfigAccessor for use in static contexts (like logging).
public ConcurrentDictionary<string, GiveawayState> States { get; private set; }Thread-safe dictionary of active giveaway states, keyed by profile name (e.g., "Main", "Weekly").
private void SetGlobalVarIfChanged(CPHAdapter adapter, string varName, object value, bool persisted = true)
private void SetGlobalVarIfChanged(CPHAdapter adapter, string varName, object value, bool persisted = true)Helper to set a global variable only if the value has changed. Dramatically reduces log spam by avoiding redundant SetGlobalVar calls.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter |
| varName | Variable Name |
| value | New Value |
| persisted | Persist to disk (default true) |
public GiveawayManager()Initializes a new instance of the class. Sets up the state container.
public static string SanitizePath(string input)Sanitizes a string by replacing the application base directory with [BaseDir]. Prevents leaking absolute paths in chat messages.
| Parameter | Description |
|---|---|
| input | The raw path string. |
Returns: The sanitized string with [BaseDir] placeholder.
public static string PickRandomMessage(string rawMsg)Selects a random message option if the input contains delimiters (| or ,). Prioritizes Pipe (|) splitting. duplicate commas are treated as text if pipes exist.
| Parameter | Description |
|---|---|
| rawMsg | The input message string (potentially containing delimiters). |
Returns: A single selected message string.
public static int? ParseDuration(string durationStr)Parses a duration string (e.g., "10m", "1h", "30s") into total seconds. Defaults to minutes if no unit is specified (e.g., "5" -> 300s). Returns null if parsing fails.
| Parameter | Description |
|---|---|
| durationStr | The duration string to parse. |
public static bool TryParseDurationSafe(string durationStr, out int seconds, CPHAdapter adapter = null)
public static bool TryParseDurationSafe(string durationStr, out int seconds, CPHAdapter adapter = null)Safely parses a duration string without throwing exceptions. Wraps ParseDuration logic in a try-catch for robustness.
private List<string> ParseProfileTargets(CPHAdapter adapter, string input)Resolves a target string (ProfileName, *, all, or comma-list) into a list of profile names.
public void Dispose()Disposes managed resources including timer and lock. Call this method on bot shutdown to prevent resource leaks.
private void LifecycleTick(object state)Periodic tick handler to check for timed giveaway expirations and periodic tasks.
| Parameter | Description |
|---|---|
| state | The CPHAdapter instance. |
public void Initialize(CPHAdapter adapter)Sets up the manager dependencies and loads initial state.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter for Streamer.bot interaction. |
// TODO: Remove in v2.0 (Legacy Migration)Migrates legacy security settings to the current standard. Generates a portable EncryptionSalt if one does not exist. Re-encrypts existing API keys using the new salt if necessary.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter for logging and variable access. |
// TODO: Remove in v2.0 (Legacy Migration)Automatically encrypts or upgrades API keys to AES-256-CBC encryption. Supports backward-compatible auto-conversion from legacy OBF (Base64) format. Warns users if legacy DPAPI keys are detected (non-portable).
public static string EncryptSecret(string plainText)Encrypts a secret using AES-256-CBC. Uses EncryptionSalt from GlobalConfig if available (portable), else falls back to MachineName (legacy).
| Parameter | Description |
|---|---|
| plainText | The text to encrypt. |
Returns: The encrypted string prefixed with "AES:", or null if input is empty.
private static string EncryptWithSeed(string plainText, string seed)Encrypts a string using AES-256-CBC with a specific seed.
| Parameter | Description |
|---|---|
| plainText | The text to encrypt. |
| seed | The seed string to derive the key/IV from. |
Returns: The encrypted string in base64 format prefixed with "AES:", or null on failure.
// TODO: Remove in v2.0 (Legacy Migration)Decrypts AES-256-CBC encrypted secret. Tries configured EncryptionSalt first, then falls back to legacy MachineName. Auto-converts legacy OBF: format (Base64) to plaintext.
private static string TryDecrypt(string secret, string seed)Attempts to decrypt the provided secret using the given seed. Returns null if decryption fails.
private static string SanitizeForLog(string input)Sanitizes strings for logging - removes potential key/sensitive material. Redacts patterns that look like API keys, tokens, or encrypted blobs.
private void CleanupExpiredMessageIds(CPHAdapter adapter)Periodically cleans up expired message IDs from the anti-loop cache. Removes entries older than MESSAGE_ID_CACHE_TTL_MINUTES to prevent memory leak. Runs every MESSAGE_ID_CLEANUP_INTERVAL_MS milliseconds via timer.
private void SyncEnhancedMetrics(CPHAdapter adapter)Synchronizes enhanced metrics to Streamer.bot global variables. Exposes diagnostic counters for real-time monitoring in UI. Optimized to only update variables that have changed to reduce log spam.
private void IncGlobalMetric(CPHAdapter adapter, string n, long d = 1)Increments a global metric counter.
| Parameter | Description |
|---|---|
| adapter | CPH adapter instance. |
| n | Metric name suffix (e.g., "Giveaway_Started"). |
| d | Amount to increment (default: 1). |
public static void TrackMetric(CPHAdapter adapter, string metricName, long delta = 1)Public wrapper for incrementing global metrics (thread-safe). Allows external classes (e.g., WheelOfNamesClient, ObsController) to track metrics. Uses Streamer.bot's global variable locking mechanism for thread safety.
| Parameter | Description |
|---|---|
| adapter | CPH adapter instance (required) |
| metricName | Metric name without prefix (e.g., "WheelAPI_Errors") |
| delta | Amount to increment (default: 1) |
private bool IsLoopDetected(CPHAdapter adapter, out string reason)Checks if a message/event should be ignored due to anti-loop protections. Returns true if the message should be IGNORED (loop detected). Implements three-layer protection: message ID dedup, invisible token, bot source flag.
| Parameter | Description |
|---|---|
| adapter | CPH adapter for argument extraction and logging |
| reason | Output parameter explaining why loop was detected (if any) |
Returns: True if loop detected (ignore message), False if safe to process
private async Task<bool> HandleBotMessage(CPHAdapter adapter)Checks if the message is from an allowed external bot and triggers actions if it matches a pattern. Returns TRUE if an action was taken (handled), FALSE otherwise.
// TODO: Remove in v2.0 (Legacy Migration)Resolves the AllowedExternalBots list from multiple possible sources. Priority: File Path -> Streamer.bot Variable -> Inline List
| Parameter | Description |
|---|---|
| adapter | CPH adapter for logging and variable access |
| allowedBots | Source list from config (may be file path, variable name, or inline list) |
Returns: Resolved list of bot names (case-sensitive)
private async Task ExecuteExternalAction(CPHAdapter adapter, string profileName, string action, string userName, string userId, string message, string platform)
private async Task ExecuteExternalAction(CPHAdapter adapter, string profileName, string action, string userName, string userId, string message, string platform)Executes an external action (like a toast or OBS change) based on a configured event name.
| Parameter | Description |
|---|---|
| adapter | CPH adapter. |
| profileName | Current profile name. |
| action | Action name ("Open", "Close", "Winner"). |
| userName | User triggering the action. |
| userId | User ID triggering the action. |
| message | Original message content. |
| platform | Platform of the trigger. |
private bool IsEntryNameInvalid(string userName, string gameNameInput, GiveawayProfileConfig config, CPHAdapter adapter, out string validName)
private bool IsEntryNameInvalid(string userName, string gameNameInput, GiveawayProfileConfig config, CPHAdapter adapter, out string validName)Validates username OR entry input against configured regex pattern. Returns true if INVALID (should be rejected). Supports dual-check: If userName matches, it's valid. If not, checks gameNameInput.
| Parameter | Description |
|---|---|
| userName | The username to check. |
| gameNameInput | Optional game name input to check if username fails. |
| config | The profile configuration containing the regex pattern. |
| adapter | The CPH adapter context. |
| validName | Output parameter for the valid name found (if any). |
Returns: True if INVALID (reject), False if Valid (allow)
private void IncUserMetric(CPHAdapter adapter, string userId, string userName, string metricKey, string gameName = null)
private void IncUserMetric(CPHAdapter adapter, string userId, string userName, string metricKey, string gameName = null)Increments a user-specific metric counter, storing it in Streamer.bot's user variables. Also updates the in-memory cached metrics for real-time display.
| Parameter | Description |
|---|---|
| adapter | CPH adapter instance. |
| userId | The user's ID (e.g., Twitch User ID). |
| userName | The user's display name. |
| metricKey | The metric key to increment. |
| gameName | Optional game name to update. |
public void SyncAllVariables(CPHAdapter adapter)Synchronizes Streamer.bot variables for ALL profiles and global settings. Useful after initialization or configuration changes. Strategy: 1. Reset 'touched' variables tracker. 2. Sync Global Settings (RunMode, API Keys, etc.). 3. Sync Profile Variables (Triggers, Configs, Live Stats). 4. Prune any variables that were NOT touched (Orphan cleanup).
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
private static void PruneUnusedVariables(CPHAdapter adapter)Identifies and removes Streamer.bot global variables starting with 'GiveawayBot_' that were not updated (touched) during the most recent synchronization.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
public void SyncGlobalVars(CPHAdapter adapter)Exposes global management variables to Streamer.bot for visibility. Aggregates metrics from all profiles for a comprehensive sync. Optimized to avoid redundant log spam.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
private void UpdateMetric(CPHAdapter adapter, string name, long value)Updates a snapshot metric (e.g., latency, processing time) without incrementing. Logs a performance warning if latency exceeds thresholds.
| Parameter | Description |
|---|---|
| adapter | CPH adapter instance. |
| name | Metric name suffix (e.g., "EntryProcessingAvgMs"). |
| value | The new value for the metric. |
public void SaveDirtyMetrics(CPHAdapter adapter)Persists the current in-memory metrics to storage (file/GlobalVar).
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
private void SyncProfileVariables(CPHAdapter adapter, string profileName, GiveawayProfileConfig config, GiveawayState state, GlobalSettings globals)
private void SyncProfileVariables(CPHAdapter adapter, string profileName, GiveawayProfileConfig config, GiveawayState state, GlobalSettings globals)Synchronizes profile-specific variables to Streamer.bot global variables. Handles 'ExposeVariables' logic to selectively show/hide runtime data. Optimized to avoid redundant log spam.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| profileName | The name of the profile to sync. |
| config | The profile configuration. |
| state | The current runtime state of the profile. |
| globals | The global settings. |
private static bool? ParseBoolVariant(string input)Robustly parses a boolean value from various string representations (true, on, 1, yes, etc.). Returns null if the input cannot be parsed as a boolean.
| Parameter | Description |
|---|---|
| input | The string to parse. |
Returns: True, False, or null if parsing fails.
private static int ParseDurationMinutes(string input)Parses a time duration string (e.g., "10m", "1h", "300s") into integer minutes. Wraps the existing ParseDuration helper to ensure consistency.
| Parameter | Description |
|---|---|
| input | The time duration string to parse. |
Returns: The duration in minutes, or 0 if parsing fails.
private static void ApplyGameFilter(GiveawayProfileConfig config)Applies game-specific username pattern and entropy settings based on GameFilter config. Currently supports "GW2" (Guild Wars 2) to enforce account name format (Name.1234).
| Parameter | Description |
|---|---|
| config | Profile configuration to modify. |
private static bool IsBroadcaster(CPHAdapter adapter)Determines if the triggering user is the broadcaster/owner. Checks against Streamer.bot's broadcastUserId argument or Role Level 4 (Broadcaster).
| Parameter | Description |
|---|---|
| adapter | The CPH Adapter. |
Returns: True if the user is the broadcaster, otherwise false.
public async Task<bool> HandleProfileCommand(CPHAdapter adapter, string rawInput, string platform)Handles profile management commands (!giveaway profile ...). Supports create, delete, clone, listing, and configuration updates.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter. |
| rawInput | The full command string. |
| platform | The source platform. |
Returns: True if the command was handled.
private static string GetWheelApiKey(CPHAdapter adapter)Retrieves the WheelOfNames API Key, prioritizing the direct global variable. Returns null if no valid key is found (strict mode).
| Parameter | Description |
|---|---|
| adapter | CPH Adapter. |
Returns: The API Key string or null.
// Checks global variables for changes and updates internal config if needed.Periodic check for configuration updates from Streamer.bot Global Variables. This allows users to update Triggers via JSON blobs which then sync back to disk.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter. |
| fullSync | If true, performs expensive checks (Triggers, API Key validation). False for lightweight polling. |
public async Task<bool> ProcessTrigger(CPHAdapter adapter)Processes a trigger event (Chat, Command, etc.) from Streamer.bot. This is the main entry point for all giveaway interactions.
| Parameter | Description |
|---|---|
| adapter | CPH adapter containing the event arguments. |
Returns: True if processed successfully, False otherwise.
Handles a user entering the giveaway. Performs validation (spam, filters, cooldowns) and updates the state.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter. |
| config | Profile configuration. |
| state | Current giveaway state. |
| profileName | Name of the profile. |
| explicitUserId | Optional: User ID injected from external source (bypasses CPH args). |
| explicitUserName | Optional: User Name injected from external source. |
Returns: True if the entry was processed (accepted or rejected with reason).
private bool ValidateEntryRequest(CPHAdapter adapter, GiveawayProfileConfig config, GiveawayState state, string profileName, string userId, string userName, string platform)
private bool ValidateEntryRequest(CPHAdapter adapter, GiveawayProfileConfig config, GiveawayState state, string profileName, string userId, string userName, string platform)Performs all pre-lock validation checks for an entry request. Includes Game Filters, Cooldowns, Rate Limits, Strictness Checks (Follower/Sub), Regex, Entropy, and Account Age.
| Parameter | Description |
|---|---|
| adapter | The CPHAdapter instance for interacting with Streamer.bot. |
| config | The configuration for the specific giveaway profile. |
| state | The current state of the giveaway for the profile. |
| profileName | The name of the giveaway profile. |
| userId | The ID of the user attempting to enter. |
| userName | The name of the user attempting to enter. |
| platform | The platform from which the entry request originated (e.g., "Twitch"). |
Returns: True if the entry request is valid and should proceed to locking/state checks. False if rejected.
private async Task<bool> HandleDraw(CPHAdapter adapter, GiveawayProfileConfig config, GiveawayState state, string profileName, string platform)
private async Task<bool> HandleDraw(CPHAdapter adapter, GiveawayProfileConfig config, GiveawayState state, string profileName, string platform)Handles drawing a winner for the giveaway. Supports determining winners via local RNG or the WheelOfNames API.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter. |
| config | Profile configuration. |
| state | Current state. |
| profileName | Profile name. |
| platform | Platform context. |
Returns: True if the command was processed.
Opens the giveaway for new entries. Resets state, starts timers (if configured), and broadcasts the open message.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter. |
| config | Profile Config. |
| state | Profile State. |
| profileName | Profile Name. |
| platform | Platform context. |
Returns: True if processed.
Closes the giveaway and optionally dumps the final entry list. Stops timers, resets cooldowns, and broadcasts the closed message.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter. |
| config | Profile Config. |
| state | Profile State. |
| profileName | Profile Name. |
| platform | Platform. |
| bypassAuth | If true, skips broadcaster/mod checks (used for auto-close). |
private static async Task DumpWinnersAsync(CPHAdapter adapter, string profileName, List<string> pool, GiveawayProfileConfig config, GiveawayState state = null)
private static async Task DumpWinnersAsync(CPHAdapter adapter, string profileName, List<string> pool, GiveawayProfileConfig config, GiveawayState state = null)Asynchronously dumps the list of winners to a timestamped file. Supports TXT, CSV, and JSON formats based on profile config.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter used for logging errors. |
| profileName | Name of the profile (used for directory structure). |
| pool | List of winner usernames. |
| config | Profile configuration determining the output format. |
| state | Giveaway state to lookup extra entry details (like GameName). |
private static async Task DumpEntriesAsync(CPHAdapter adapter, string profileName, GiveawayState state, GiveawayProfileConfig config)
private static async Task DumpEntriesAsync(CPHAdapter adapter, string profileName, GiveawayState state, GiveawayProfileConfig config)Asynchronously dumps full entry details to a timestamped file. This is typically called when a giveaway ends.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter. |
| profileName | Name of the profile. |
| state | Current state containing the entries to dump. |
| config | Configuration determining dump format. |
public async Task PerformSystemCheck(CPHAdapter adapter)Performs a comprehensive health check of the bot's environment (Files, Config, Persistence, API). Logs results to the Streamer.bot log and broadcasts them to chat.
private async Task HandleRegexTest(CPHAdapter adapter, string rawInput, string platform)Tests a regex pattern against sample text, showing match results and captured groups. Includes timeout protection to prevent ReDoS (Regular Expression Denial of Service).
| Parameter | Description |
|---|---|
| adapter | CPH adapter for messaging |
| rawInput | Full command string |
| platform | Platform to send response to |
private void ProcessPendingDumpsCallback(object state)Timer callback to check all profiles for pending entry dumps. Processes batches based on configured throttle seconds.
private static async Task FlushPendingDumpsAsync(CPHAdapter adapter, string profileName, GiveawayState state)
private static async Task FlushPendingDumpsAsync(CPHAdapter adapter, string profileName, GiveawayState state)Asynchronously flushes pending entry dumps to disk in batched writes. Implements error recovery by re-queuing failed entries.
| Parameter | Description |
|---|---|
| adapter | CPH adapter for logging |
| profileName | Profile name for file organization |
| state | Giveaway state containing pending dumps |
private async Task<bool> HandleDataDeletion(CPHAdapter adapter, string rawInput, string platform)Handles GDPR data deletion requests. Removes a user from all active profiles, metrics, and global variables. Also attempts to sanitize historical log files.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter. |
| rawInput | Command string. |
| platform | Platform context. |
private async Task<bool> HandleStatsCommand(CPHAdapter adapter, string rawInput, string platform)Handles the '!giveaway stats' command. Displays global aggregated stats or stats for a specific profile.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter. |
| rawInput | Command string. |
| platform | Platform context. |
private static bool CheckDataCmd(string s) => s != null && (s.Contains(GiveawayConstants.CmdPattern_GiveawayPrefix + GiveawayConstants.CmdPrefix_Data) || s.Contains(GiveawayConstants.CmdPattern_GaPrefix + GiveawayConstants.CmdPrefix_Data) || s.Contains(GiveawayConstants.CmdPattern_GiveawayPrefix + GiveawayConstants.CmdPrefix_DataShort) || s.Contains(GiveawayConstants.CmdPattern_GaPrefix + GiveawayConstants.CmdPrefix_DataShort))
private static bool CheckDataCmd(string s) => s != null && (s.Contains(GiveawayConstants.CmdPattern_GiveawayPrefix + GiveawayConstants.CmdPrefix_Data) || s.Contains(GiveawayConstants.CmdPattern_GaPrefix + GiveawayConstants.CmdPrefix_Data) || s.Contains(GiveawayConstants.CmdPattern_GiveawayPrefix + GiveawayConstants.CmdPrefix_DataShort) || s.Contains(GiveawayConstants.CmdPattern_GaPrefix + GiveawayConstants.CmdPrefix_DataShort))Checks if the input string corresponds to a data command (e.g., for GDPR actions).
| Parameter | Description |
|---|---|
| s | The input string to check. |
Returns: True if the string contains a data command, false otherwise.
Data transfer object holding the results of a trigger identification. Indicates which profile and action should be executed.
public void Deconstruct(out string profile, out string action, out string platform, out string details)
public void Deconstruct(out string profile, out string action, out string platform, out string details)Deconstructs the result into its component parts.
Routes incoming Streamer.bot triggers (Commands, StreamDeck, Raw Input) to specific giveaway profiles. Returns the profile name and the abstract action (Entry, Draw, etc.) to perform.
public static TriggerResult IdentifyTrigger(CPHAdapter adapter, Dictionary<string, GiveawayProfileConfig> profiles)
public static TriggerResult IdentifyTrigger(CPHAdapter adapter, Dictionary<string, GiveawayProfileConfig> profiles)Analyzes an incoming trigger to determine if it matches any configured profile triggers.
| Parameter | Description |
|---|---|
| adapter | CPH adapter instance. |
| profiles | The dictionary of configured profiles. |
Returns: A TriggerResult indicating the matched profile and action, or empty if no match.
#pragma warning disable IDE0028 // Simplify collection initializationReal implementation of IGiveawayCPH that forwards calls to the actual Streamer.bot CPH instance. Uses explicit method resolution to avoid AmbiguousMatchException.
private const bool LogReflectionGetGlobalVar = falseControls whether GetGlobalVar calls are logged to TRACE. Useful to disable for reducing log spam while keeping other reflection logs.
private readonly HashSet<string> _touchedGlobalVars = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
private readonly HashSet<string> _touchedGlobalVars = new HashSet<string>(StringComparer.OrdinalIgnoreCase)Tracks which global variables have been accessed/modified to optimize updates.
public CPHAdapter(object cph, Dictionary<string, object> args)Initializes a new instance of the class.
| Parameter | Description |
|---|---|
| cph | The raw Streamer.bot CPH object. |
| args | The arguments dictionary from the action context. |
public void ShowToastNotification(string title, string message)Displays a toast notification in Streamer.bot.
| Parameter | Description |
|---|---|
| title | Title of the notification. |
| message | Body message of the notification. |
public Dictionary<string, object> ArgsGets or sets the arguments dictionary for the current action. Mirrors the CPH.Args dictionary for mockability.
public void ResetTouchedVars() { _touchedGlobalVars.Clear(); }Clears the set of "touched" or updated variables for the current cycle.
public IEnumerable<string> GetTouchedVars() { return _touchedGlobalVars; }Returns a list of global variables that were updated during the current cycle. Used for pruning orphans.
public static bool IsManagedVariable(string name)Determines if a variable name indicates it is managed by this bot. Supports both new 'Giveaway ' and legacy 'GiveawayBot_' prefixes for backward compatibility and cleanup.
public void TouchGlobalVar(string name) { if (IsManagedVariable(name)) _touchedGlobalVars.Add(name); }
public void TouchGlobalVar(string name) { if (IsManagedVariable(name)) _touchedGlobalVars.Add(name); }Marks a global variable as "touched" (active) to prevent pruning.
private MethodInfo GetMethod(string name, int paramCount)Helper to find methods safely via reflection, handling overloads.
| Parameter | Description |
|---|---|
| name | Method name. |
| paramCount | Number of parameters. |
Returns: The MethodInfo if found, otherwise null.
public void DumpMethods()Dumps all available methods on the underlying CPH object to the log for debugging purposes.
public void LogInfo(string m) { Logger?.LogInfo(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogInfo", new object[] { m }, 1); }
public void LogInfo(string m) { Logger?.LogInfo(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogInfo", new object[] { m }, 1); }Logs an informational message to the Streamer.bot log.
public void LogWarn(string m) { Logger?.LogWarn(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogWarn", new object[] { m }, 1); }
public void LogWarn(string m) { Logger?.LogWarn(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogWarn", new object[] { m }, 1); }Logs a warning message to the Streamer.bot log.
public void LogDebug(string m) { Logger?.LogDebug(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogDebug", new object[] { m }, 1); }
public void LogDebug(string m) { Logger?.LogDebug(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogDebug", new object[] { m }, 1); }Logs a debug message to the Streamer.bot log.
public void LogError(string m) { Logger?.LogError(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogError", new object[] { m }, 1); }
public void LogError(string m) { Logger?.LogError(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogError", new object[] { m }, 1); }Logs an error message to the Streamer.bot log.
public void LogVerbose(string m) { Logger?.LogVerbose(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogDebug", new object[] { m }, 1); }
public void LogVerbose(string m) { Logger?.LogVerbose(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogDebug", new object[] { m }, 1); }Logs a verbose message (mapped to Debug in SB).
public void LogTrace(string m) { Logger?.LogTrace(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogDebug", new object[] { m }, 1); }
public void LogTrace(string m) { Logger?.LogTrace(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogDebug", new object[] { m }, 1); }Logs a trace message (mapped to Debug in SB).
public void LogFatal(string m) { Logger?.LogFatal(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogError", new object[] { "[FATAL] " + m }, 1); }
public void LogFatal(string m) { Logger?.LogFatal(this, "CPH", m); if (GiveawayManager.StaticConfig?.Globals?.LogToStreamerBot ?? true) InvokeSafe("LogError", new object[] { "[FATAL] " + m }, 1); }Logs a fatal error message (mapped to Error in SB with prefix).
private object InvokeSafe(string name, object[] args, int paramCount)Invokes a method on the underlying CPH object via reflection safely. Handles method resolution and error catching.
| Parameter | Description |
|---|---|
| name | Name of the method to invoke. |
| args | Arguments to pass. |
| paramCount | Number of parameters expected (for overload resolution). |
Returns: The return value of the method, or null on failure.
public bool TryGetArg<T>(string n, out T v)Attempts to get an argument value from the action context.
| Parameter | Description |
|---|---|
| n | The name of the argument. |
| v | When this method returns, contains the value of the argument, or default(T) if not found. |
Returns: True if the argument was found and successfully converted; otherwise, false.
public T GetGlobalVar<T>(string n, bool p = true)Retrieves the value of a global variable from Streamer.bot.
| Parameter | Description |
|---|---|
| n | The name of the variable. |
| p | Whether to persist the variable (default: true). |
Returns: The confirmed value of the variable, or default(T) if not found/error.
public void SetGlobalVar(string n, object v, bool p = true)Sets a global variable value.
| Parameter | Description |
|---|---|
| n | The name of the variable. |
| v | The value to set. |
| p | Whether to persist the variable (default: true). |
public List<string> GetGlobalVarNames(bool p = true)Retrieves a list of all current global variable names. Used for identifying orphaned variables that should be deleted.
| Parameter | Description |
|---|---|
| p | Whether to check persisted variables (default: true). |
Returns: A list of variable names.
public void UnsetGlobalVar(string n, bool p = true) { InvokeSafe("UnsetGlobalVar", new object[] { n, p }, 2); }
public void UnsetGlobalVar(string n, bool p = true) { InvokeSafe("UnsetGlobalVar", new object[] { n, p }, 2); }Removes a global variable.
| Parameter | Description |
|---|---|
| n | The name of the variable to unset. |
| p | Whether it is a persisted variable (default: true). |
public T GetUserVar<T>(string u, string n, bool p = true)Retrieves the value of a user-specific variable.
| Parameter | Description |
|---|---|
| u | The user ID (or login). |
| n | The variable name. |
| p | Whether to persist (default: true). |
Returns: The variable value, or default(T).
public void SetUserVar(string u, string n, object v, bool p = true)Sets a user-specific variable value.
| Parameter | Description |
|---|---|
| u | The user ID (or login). |
| n | The variable name. |
| v | The value to set. |
| p | Whether to persist (default: true). |
public void SendMessage(string m, bool b = true)Sends a chat message to the default platform (usually Twitch). Automatically appends the anti-loop token (zero-width space) to prevent determining self-triggering.
| Parameter | Description |
|---|---|
| m | The message to send. |
| b | Whether to use the bot account (default: true). |
public void SendYouTubeMessage(string m)Sends a chat message to YouTube. Automatically appends the anti-loop token.
| Parameter | Description |
|---|---|
| m | The message to send. |
public void SendKickMessage(string m)Sends a chat message to Kick. Automatically appends the anti-loop token.
| Parameter | Description |
|---|---|
| m | The message to send. |
public void DiscordSendMessage(string channelId, string message)Sends a message to a Discord channel via Streamer.bot integration.
| Parameter | Description |
|---|---|
| channelId | The Discord Channel ID. |
| message | The message to send. |
public void TwitchReplyToMessage(string message, string replyId, bool useBot = true, bool fallback = true)
public void TwitchReplyToMessage(string message, string replyId, bool useBot = true, bool fallback = true)Sends a threaded reply to a specific Twitch chat message.
| Parameter | Description |
|---|---|
| message | Message content to send. |
| replyId | Message ID to reply to. |
| useBot | Use bot account (true) or broadcaster account (false). |
| fallback | Fallback to broadcast account if bot is not available. |
public bool IsTwitchLive()Checks if the connected Twitch broadcaster account is currently live.
public bool IsYouTubeLive()Checks if the connected YouTube broadcaster account is currently live.
public bool IsKickLive()Checks if the connected Kick broadcaster account is currently live.
public bool TwitchIsUserFollower(string userId) => InvokeSafe("TwitchIsUserFollower", new object[] { userId, true }, 2) as bool? ?? false
public bool TwitchIsUserFollower(string userId) => InvokeSafe("TwitchIsUserFollower", new object[] { userId, true }, 2) as bool? ?? falseChecks if a user is following the channel on Twitch.
| Parameter | Description |
|---|---|
| userId | The user ID to check. |
Returns: True if following, false otherwise.
public bool TwitchIsUserSubscriber(string userId) => InvokeSafe("TwitchIsUserSubscriber", new object[] { userId, true }, 2) as bool? ?? false
public bool TwitchIsUserSubscriber(string userId) => InvokeSafe("TwitchIsUserSubscriber", new object[] { userId, true }, 2) as bool? ?? falseChecks if a user is subscribed to the channel on Twitch.
| Parameter | Description |
|---|---|
| userId | The user ID to check. |
Returns: True if subscribed, false otherwise.
public void ObsSetBrowserSource(string s, string o, string u)Sets the URL of an OBS Browser Source.
| Parameter | Description |
|---|---|
| s | The scene name. |
| o | The source name. |
| u | The URL to set. |
public object GetEventType() { return InvokeSafe("GetEventType", Array.Empty<object>(), 0); }Retrieves the event type that triggered the current action.
Returns: The event type object (platform specific).
public bool RunAction(string actionName, bool runImmediately = true)Runs a specified Streamer.bot action.
#pragma warning disable IDE0028 // Simplify collection initializationHandles loading and saving the JSON configuration file. Supports hot-reloading if the file changes on disk.
public static string GetRunMode(CPHAdapter adapter)Determines the current active RunMode (FileSystem, GlobalVar, ReadOnlyVar, Mirror). defaults to "FileSystem" if not set.
private string ReadConfigText(CPHAdapter adapter, bool forceDisk = false)Reads the raw configuration JSON string from the configured storage source.
| Parameter | Description |
|---|---|
| adapter | CPH adapter for accessing global variables. |
| forceDisk | If true, forces reading from disk regardless of run mode. |
Returns: The raw JSON string, or null if not found.
public void InvalidateCache() => _lastLoad = DateTime.MinValueForces the configuration to be reloaded from storage on the next request.
public void WriteConfigText(CPHAdapter adapter, string json)Synchronously writes configuration JSON to storage. Maintained for backward compatibility and initial setup.
public async Task WriteConfigTextAsync(CPHAdapter adapter, string json)Asynchronously writes configuration JSON to storage (Disk and/or GlobalVar).
private static void EnsureCaseInsensitive(GiveawayBotConfig c)Ensures that the Profiles dictionary in the config object uses case-insensitive keys. Also fixes up the Triggers dictionary within each profile.
| Parameter | Description |
|---|---|
| c | The configuration object to fix. |
private static void ValidateConfig(CPHAdapter adapter, GiveawayBotConfig c)Validates configuration values and clamps them to safe ranges. Also removes profiles with invalid names to prevent system errors.
public GiveawayBotConfig GetConfig(CPHAdapter adapter)Retrieves the current configuration object, managing caching and auto-reloading. Performs synchronization between disk and global variables based on RunMode.
public async Task<(bool Success, string Error)> ResetProfileAsync(CPHAdapter adapter, string profileName)
public async Task<(bool Success, string Error)> ResetProfileAsync(CPHAdapter adapter, string profileName)Resets a specific profile to its default settings.
public async Task<(bool success, string message, string path)> ExportProfileAsync(CPHAdapter adapter, string profileName)
public async Task<(bool success, string message, string path)> ExportProfileAsync(CPHAdapter adapter, string profileName)Exports a profile configuration to a JSON file.
public async Task<(bool success, string message)> ImportProfileAsync(CPHAdapter adapter, string source, string targetName)
public async Task<(bool success, string message)> ImportProfileAsync(CPHAdapter adapter, string source, string targetName)Imports a profile from a file or JSON string.
private static void SetStatus(CPHAdapter adapter, string s) => adapter.SetGlobalVar(GiveawayConstants.GlobalConfigStatus, s, true)
private static void SetStatus(CPHAdapter adapter, string s) => adapter.SetGlobalVar(GiveawayConstants.GlobalConfigStatus, s, true)Updates the configuration status global variable.
public string ValidateConfig(CPHAdapter adapter)Validates the current configuration for semantic errors (e.g., negative values). Returns a formatted validation status string.
private static string HandleValidationError(CPHAdapter adapter, string msg)Updates the configuration status global variable with an error message.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| msg | The error message to display. |
Returns: The error message returned as a string.
public void GenerateDefaultConfig(CPHAdapter adapter)Generates a default configuration file if none exists, or migrates an existing one. Keeps user profiles intact during migration.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
public async Task<(bool Success, string ErrorMessage)> CreateProfileAsync(CPHAdapter adapter, string name)
public async Task<(bool Success, string ErrorMessage)> CreateProfileAsync(CPHAdapter adapter, string name)Creates a new profile with default settings asynchronously. Persists changes to disk/global vars immediately.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| name | The name of the new profile. |
Returns: A tuple containing Success (bool) and ErrorMessage (string).
public async Task<(bool Success, string ErrorMessage, string BackupPath)> DeleteProfileAsync(CPHAdapter adapter, string name)
public async Task<(bool Success, string ErrorMessage, string BackupPath)> DeleteProfileAsync(CPHAdapter adapter, string name)Deletes a profile and its associated data asynchronously. Creates a comprehensive backup of the profile config and state before deletion.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| name | The name of the profile to ignore. |
Returns: A tuple containing Success (bool), ErrorMessage (string), and BackupPath (string).
public async Task<(bool Success, string ErrorMessage)> CloneProfileAsync(CPHAdapter adapter, string sourceProfile, string newProfileName)
public async Task<(bool Success, string ErrorMessage)> CloneProfileAsync(CPHAdapter adapter, string sourceProfile, string newProfileName)Clones an existing profile to a new profile asynchronously. Copies all settings and triggers but resets runtime state.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| sourceProfile | The name of the source profile to clone. |
| newProfileName | The name for the new profile. |
Returns: A tuple containing Success (bool) and ErrorMessage (string).
public async Task<(bool Success, string ErrorMessage)> UpdateProfileConfigAsync(CPHAdapter adapter, string profileName, string key, string value)
public async Task<(bool Success, string ErrorMessage)> UpdateProfileConfigAsync(CPHAdapter adapter, string profileName, string key, string value)Updates a specific configuration key for a profile asynchronously. Uses Reflection to support all properties of GiveawayProfileConfig dynamically.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| profileName | The name of the profile to update. |
| key | The configuration key (property name) to update. |
| value | The new value to set. |
Returns: A tuple containing Success (bool) and ErrorMessage (string).
public async Task<(bool Success, string ErrorMessage)> AddProfileTriggerAsync(CPHAdapter adapter, string profileName, string triggerSpec, string action)
public async Task<(bool Success, string ErrorMessage)> AddProfileTriggerAsync(CPHAdapter adapter, string profileName, string triggerSpec, string action)Adds or updates a trigger for a profile. Valid actions: Entry, Winner, Open, Close.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| profileName | The name of the profile. |
| triggerSpec | The trigger specification (e.g., "command:!join"). |
| action | The action to execute (Enter, Winner, Open, Close). |
Returns: A tuple containing Success (bool) and ErrorMessage (string).
public async Task<(bool Success, string ErrorMessage)> RemoveProfileTriggerAsync(CPHAdapter adapter, string profileName, string triggerSpec)
public async Task<(bool Success, string ErrorMessage)> RemoveProfileTriggerAsync(CPHAdapter adapter, string profileName, string triggerSpec)Removes a specific trigger from a profile.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| profileName | The name of the profile. |
| triggerSpec | The trigger specification to remove. |
Returns: A tuple containing Success (bool) and ErrorMessage (string).
private async Task BackupConfigAsync(CPHAdapter adapter)Creates a ZIP backup of the current configuration file in the 'backups' directory. Retains a configurable number of rolling backups.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
public static int LevenshteinDistance(string s, string t)Calculates the Levenshtein edit distance between two strings. Used for fuzzy matching configuration keys to suggest corrections.
| Parameter | Description |
|---|---|
| s | The first string. |
| t | The second string. |
Returns: The edit distance (number of operations).
private static void RunFuzzyCheck(CPHAdapter adapter, GiveawayBotConfig config)Performs a fuzzy check on the configuration object to detect potential typos in keys. Logs warnings and suggestions to Streamer.bot global variables.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| config | The configuration object to check. |
private static void CheckObj(CPHAdapter adapter, object obj, string path)Recursively checks an object's properties against its ExtensionData to find potential typos.
| Parameter | Description |
|---|---|
| adapter | CPH adapter for logging. |
| obj | The object to check. |
| path | Breadcrumb path for logging (e.g., "Profiles['Main']"). |
Persists the active state (entries, active status) of giveaways. Uses Streamer.bot Global Variables for persistence to survive restarts.
private static string GetStatePath(string p) =>Resolves the absolute file path for a profile's state JSON.
| Parameter | Description |
|---|---|
| p | The profile name. |
Returns: The absolute file path to the state file.
public static void SaveState(CPHAdapter adapter, string p, GiveawayState s, GlobalSettings globals, bool critical = false)
public static void SaveState(CPHAdapter adapter, string p, GiveawayState s, GlobalSettings globals, bool critical = false)Saves the giveaway state to disk and/or global variables based on persistence mode. Serializes the state object to JSON.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter for logging and global var access. |
| p | Profile name. |
| s | State object to save. |
| globals | Global settings containing persistence mode. |
| critical | If true, logs TRACE level confirmation of save. |
public static GiveawayState LoadState(CPHAdapter adapter, string p, GlobalSettings globals)Loads the giveaway state from disk or global variables. Prioritizes Global Variables in 'Mirror' mode if available.
| Parameter | Description |
|---|---|
| adapter | CPH Adapter for logging and global var access. |
| p | Profile name. |
| globals | Global settings containing persistence mode. |
Returns: The loaded GiveawayState or null if not found/error.
Robust local file logger for auditing and debugging. Writes line-delimited JSON for easy machine parsing.
public FileLogger(string basePath = null)Initializes the file logger with a base path.
| Parameter | Description |
|---|---|
| basePath | Base directory for logs. Defaults to 'Giveaway Bot/logs'. |
public void LogInfo(CPHAdapter adapter, string c, string m) => Log(adapter, "INFO", c, m)Logs an INFO message.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| c | Category. |
| m | Message. |
public void LogWarn(CPHAdapter adapter, string c, string m) => Log(adapter, "WARN", c, m)Logs a WARNING message.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| c | Category. |
| m | Message. |
public void LogError(CPHAdapter adapter, string c, string m, Exception e = null) => Log(adapter, "ERROR", c, $"{m} {e?.Message}")
public void LogError(CPHAdapter adapter, string c, string m, Exception e = null) => Log(adapter, "ERROR", c, $"{m} {e?.Message}")Logs an ERROR message with optional exception details.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| c | Category. |
| m | Message. |
| e | Exception (optional). |
public void LogDebug(CPHAdapter adapter, string c, string m) => Log(adapter, "DEBUG", c, m)Logs a DEBUG message.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| c | Category. |
| m | Message. |
public void LogTrace(CPHAdapter adapter, string c, string m) => Log(adapter, "TRACE", c, m)Logs a TRACE message.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| c | Category. |
| m | Message. |
public void LogVerbose(CPHAdapter adapter, string c, string m) => Log(adapter, "VERBOSE", c, m)Logs a VERBOSE message.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| c | Category. |
| m | Message. |
public void LogFatal(CPHAdapter adapter, string c, string m) => Log(adapter, "FATAL", c, m)Logs a FATAL message.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| c | Category. |
| m | Message. |
public static void ResetLoggingFlag() => _isLogging = falseResets the logging flag to allow new log entries.
private void Log(CPHAdapter adapter, string level, string category, string message)Internal method to handle the actual logging logic including file rotation and pruning.
private void PruneLogs(CPHAdapter adapter)Enforce log retention policies (age and size).
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
private void CheckForRotation(CPHAdapter adapter, string path)Checks if the current log file exceeds the size limit and rotates it if necessary.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| path | The path to the current log file. |
private static bool IsLogLevelEnabled(string configured, string current)Checks if the message level is enabled by the current configuration.
| Parameter | Description |
|---|---|
| configured | The configured log level. |
| current | The current message log level. |
Returns: True if the message should be logged, false otherwise.
Utility class for validating giveaway entries and detecting suspicious/bot accounts.
public static bool ValidateUsername(string username, string pattern)Validates a username against a regex pattern.
| Parameter | Description |
|---|---|
| username | The username to validate |
| pattern | Regex pattern (null/empty returns true) |
Returns: True if valid or pattern is disabled, false otherwise
public static bool HasSufficientEntropy(string text, double threshold = 2.5)Checks if a username has sufficient entropy to be considered "real". Uses Shannon entropy to detect keyboard smashing like "asdfgh", "zzzzzz", etc.
| Parameter | Description |
|---|---|
| text | The username to check |
| threshold | Entropy threshold (default 2.5) |
Returns: True if entropy is sufficient (appears legitimate), false if suspicious
public enum DumpFormatConfiguration format for exporting/dumping data.
Root configuration object for the Giveaway Bot. Matches the structure of the 'giveaway_config.json' file. contains global settings and a dictionary of profile-specific configurations.
public GiveawayBotConfig()Initializes a new instance of the GiveawayBotConfig class with a default "Main" profile.
}Extension data to capture any extra properties during JSON deserialization. Used for fuzzy matching to detect typos in the config file.
Global application settings affecting all profiles (logging, API keys, platform sync).
Configuration for a specific giveaway profile (e.g., "Main", "SubOnly"). Defines triggers, validation rules, rules, and integration settings.
public Dictionary<string, string> Triggers { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
public Dictionary<string, string> Triggers { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)Dictionary of event triggers mapped to actions. Key format: "type:value" (e.g., "command:!join"). Value: Action (Enter, Winner, Open, Close).
public GiveawayProfileConfig()Initializes a new profile with default command triggers.
Represents a rule for parsing messages from external bots.
Configuration settings for the Wheel of Names API v2 integration.
}Extension data to capture extra properties.
Maintains the active runtime state of a giveaway (entries, active status, history). Serialized to disk/global vars for persistence.
public Dictionary<string, Entry> Entries { get; } = new Dictionary<string, Entry>(StringComparer.OrdinalIgnoreCase)
public Dictionary<string, Entry> Entries { get; } = new Dictionary<string, Entry>(StringComparer.OrdinalIgnoreCase)Dictionary of user entries, keyed by User ID.
public bool IsSpamming(int limit, int windowSeconds = 60)Sliding window spam detection: counts entries in the last N seconds (default 60).
| Parameter | Description |
|---|---|
| limit | Max entries allowed in the window. |
| windowSeconds | Window size in seconds. |
Returns: True if spam is detected (count > limit).
/// <summary>Last time entries were successfully dumped.</summary>Queue of entries waiting to be dumped to disk.
Represents a single user entry in the giveaway.
Client for the WheelOfNames.com API v2. Used to create custom winner-picking wheels dynamically.
private static HttpClient CreateHttpClient()Create configured HttpClient with timeout and headers.
public WheelOfNamesClient(HttpMessageHandler handler = null)Initializes a new instance of the class.
| Parameter | Description |
|---|---|
| handler | Optional HTTP message handler for mocking/testing. |
private string GetRandomMessage(string rawMsg)Selects a random message variant from a pipe-delimited string.
| Parameter | Description |
|---|---|
| rawMsg | The raw message string containing variants separated by pipes. |
Returns: A single selected message variant.
public async Task<string> CreateWheel(CPHAdapter adapter, List<string> entries, string apiKeyVarName, WheelConfig config, bool validateKey = true)
public async Task<string> CreateWheel(CPHAdapter adapter, List<string> entries, string apiKeyVarName, WheelConfig config, bool validateKey = true)Creates a new wheel on WheelOfNames.com via the API v2.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter for logging. |
| entries | The list of names/entries to put on the wheel. |
| apiKeyVarName | The NAME of the Global Variable containing the API key. |
| config | The wheel configuration (title, description, settings). |
| validateKey | Whether to perform a pre-flight validation of the API key. |
Returns: The URL path of the created wheel (e.g., "/abc-123"), or null on failure.
public async Task<bool?> ValidateApiKey(CPHAdapter adapter, string apiKey)Validates a Wheel of Names API key by making a GET request to /api/v2/api-keys. This is a lightweight pre-flight check to verify key validity before creating wheels. Retrieves API key usage statistics: uid, calls count, creation date, last active date.
| Parameter | Description |
|---|---|
| adapter | CPH adapter for logging |
| apiKey | API key to validate |
Returns: True if the key is valid and active, False if invalid/revoked. Null if validation request fails (network issue, API down, etc.)
Orchestrates message delivery across multiple streaming platforms based on live status.
public MultiPlatformMessenger(GiveawayBotConfig config)Initializes a new instance of the MultiPlatformMessenger class.
| Parameter | Description |
|---|---|
| config | The main giveaway configuration. |
public void Register(IEventBus bus)Registers handlers for giveaway events to trigger notifications.
| Parameter | Description |
|---|---|
| bus | The event bus to subscribe to. |
private void OnWinnerDrawn(WinnerDrawnEvent evt)Handles the WinnerSelected event to broadcast the winner announcement.
| Parameter | Description |
|---|---|
| evt | The winner selected event data. |
private void OnWheelReady(WheelReadyEvent evt)Handles the WheelReady event to broadcast the wheel link.
| Parameter | Description |
|---|---|
| evt | The wheel ready event data. |
private void OnGiveawayStarted(GiveawayStartedEvent evt)Handles the GiveawayStarted event (notifications only, broadcast handled by logic).
private void OnGiveawayEnded(GiveawayEndedEvent evt)Handles the GiveawayEnded event (notifications only, broadcast handled by logic).
private void OnEntryAccepted(EntryAcceptedEvent evt)Handles the EntryAccepted event to send confirmation replies and toast notifications.
public void SendBroadcast(CPHAdapter adapter, string message, string sourcePlatform = "Twitch")Sends a message to one or more platforms based on their live status and configuration.
| Parameter | Description |
|---|---|
| adapter | CPH adapter context. |
| message | The message to broadcast. |
| sourcePlatform | The platform where the event originated (to prioritize reply). |
private static void SendMessageToPlatform(CPHAdapter adapter, string platform, string msg)Sends a message to a specific platform, appending the anti-loop token.
| Parameter | Description |
|---|---|
| adapter | CPH adapter context. |
| platform | Target platform (Twitch, YouTube, Kick). |
| msg | Message content. |
public void SendReply(CPHAdapter adapter, string msg, string platform, string userName, string messageId = null)
public void SendReply(CPHAdapter adapter, string msg, string platform, string userName, string messageId = null)Sends a message as a direct reply to a specific user using platform-specific reply features. For Twitch, uses threaded replies when msgId is available.
| Parameter | Description |
|---|---|
| adapter | CPH adapter context. |
| msg | Message content. |
| platform | Target platform (Twitch, YouTube, Kick). |
| userName | Username to reply to. |
| messageId | Message ID for threaded replies (Twitch msgId). |
private void SendDiscordNative(CPHAdapter adapter, string channelId, string message)Sends a message to a Discord channel via Streamer.bot native integration.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| channelId | The Discord channel ID. |
| message | The message content to send. |
private void SendDiscordWebhook(CPHAdapter adapter, string webhookUrl, string message)Sends a message via Discord Webhook.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| webhookUrl | The Discord webhook URL. |
| message | The message content to send. |
Controls OBS sources (BrowserSource) for displaying the giveaway wheel. Wraps CPH OBS methods.
public ObsController(GiveawayBotConfig config)Initializes a new instance of the class.
public void Register(IEventBus bus)Registers a handler for relevant giveaway events (WheelReady).
private void OnWheelReady(WheelReadyEvent evt)Handles the WheelReady event to update the OBS browser source with the new wheel URL.
public void SetBrowserSource(CPHAdapter adapter, string scene, string source, string url)Updates a Streamer.bot OBS Browser Source with a new URL (e.g., the Wheel of Names link).
| Parameter | Description |
|---|---|
| adapter | CPH Adapter for OBS calls. |
| scene | Name of the OBS scene. |
| source | Name of the Browser Source. |
| url | New URL to set. |
Container for user-specific metrics.
Service to check for updates from the official repository. Downloads updates to 'Giveaway Bot/updates/' as text files.
public static async Task CheckForUpdatesAsync(CPHAdapter adapter, string currentVersion, bool notifyIfUpToDate = false)
public static async Task CheckForUpdatesAsync(CPHAdapter adapter, string currentVersion, bool notifyIfUpToDate = false)Checks for updates and downloads them if available.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter context. |
| currentVersion | The current version string of the bot. |
| notifyIfUpToDate | If true, sends a notification even if no update is found. |
private static async Task<ReleaseInfo> GetLatestReleaseInfoAsync(CPHAdapter adapter)Retrieves the latest release information from GitHub via the API.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter for logging. |
Returns: A ReleaseInfo object containing tag name, name, and body; or null if failed.
private static async Task<string> DownloadUpdateAsync(CPHAdapter adapter, string tag, string expectedChecksum)
private static async Task<string> DownloadUpdateAsync(CPHAdapter adapter, string tag, string expectedChecksum)Downloads the raw C# file for the specified tag from GitHub.
| Parameter | Description |
|---|---|
| adapter | The CPH adapter for logging. |
| tag | The git tag to download (e.g., "v1.0.0"). |
Returns: The full path to the downloaded file, or null if failed.
public static bool ValidateChecksum(string content, string expectedChecksum, CPHAdapter adapter = null)
public static bool ValidateChecksum(string content, string expectedChecksum, CPHAdapter adapter = null)Validates the content against a SHA256 checksum.
| Parameter | Description |
|---|---|
| content | The content to verify. |
| expectedChecksum | The expected SHA256 hash. |
| adapter | CPH Adapter for logging. |
Returns: True if valid (or no checksum provided), False if mismatch.
public static string ExtractChecksum(string releaseBody)Extracts the SHA256 checksum from the release body text. Expected format: "SHA256: <64-char-hex-string>"
private static bool IsNewer(string remote, string local)Compares two version strings to determine if the remote version is newer.
| Parameter | Description |
|---|---|
| remote | The remote version string. |
| local | The local version string. |
Returns: True if remote is newer, otherwise false.