-
-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
Auto-generated from source code comments.
- IGiveawayCPH
- Loc
- GiveawayManager
- TriggerResult
- TriggerInspector
- PersistenceService
- FileLogger
- EntryValidator
- GiveawayBotConfig
- GlobalSettings
- GiveawayProfileConfig
- BotListenerRule
- WheelConfig
- GiveawayState
- Entry
- WheelOfNamesClient
- MultiPlatformMessenger
- ObsController
- MetricsContainer
- IEventBus
- IGiveawayEvent
- GiveawayEventBus
- GiveawayStartedEvent
- GiveawayEndedEvent
- WinnerSelectedEvent
- EntryAcceptedEvent
- WheelReadyEvent
- UserMetricSet
- UpdateService
Interface wrapper for Streamer.bot's
CPHobject. Allows us to mock the CPH interaction for unit testing outside of Streamer.bot.
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.
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. |
private void MigrateSecurity(CPHAdapter adapter)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. |
private void AutoEncryptApiKey(CPHAdapter adapter)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).
| Parameter | Description |
|---|---|
| adapter | CPH Adapter for user notification. |
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.
public static string DecryptSecret(string secret)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.
private static List<string> ResolveBotList(CPHAdapter adapter, List<string> allowedBots)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.
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. |
| u | The user's ID (e.g., Twitch User ID). |
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).
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.
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.
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).
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.
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.
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.
private async Task CheckForConfigUpdates(CPHAdapter adapter, bool fullSync = true)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.
private async Task<bool> HandleEntry(CPHAdapter adapter, GiveawayProfileConfig config, GiveawayState state, string profileName, string explicitUserId = null, string explicitUserName = null)
private async Task<bool> HandleEntry(CPHAdapter adapter, GiveawayProfileConfig config, GiveawayState state, string profileName, string explicitUserId = null, string explicitUserName = null)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.
private async Task<bool> HandleStart(CPHAdapter adapter, GiveawayProfileConfig config, GiveawayState state, string profileName, string platform)
private async Task<bool> HandleStart(CPHAdapter adapter, GiveawayProfileConfig config, GiveawayState state, string profileName, string platform)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.
private async Task<bool> HandleEnd(CPHAdapter adapter, GiveawayProfileConfig config, GiveawayState state, string profileName, string platform, bool bypassAuth = false)
private async Task<bool> HandleEnd(CPHAdapter adapter, GiveawayProfileConfig config, GiveawayState state, string profileName, string platform, bool bypassAuth = false)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.
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.
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("Giveaway Global Config Status", s, true)
private static void SetStatus(CPHAdapter adapter, string s) => adapter.SetGlobalVar("Giveaway Global Config Status", 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.
public void GenerateDefaultConfig(CPHAdapter adapter)Generates a default configuration file if none exists, or migrates an existing one. Keeps user profiles intact during migration.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
public void LogWarn(CPHAdapter adapter, string c, string m) => Log(adapter, "WARN", c, m)Logs a WARNING 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.
public void LogDebug(CPHAdapter adapter, string c, string m) => Log(adapter, "DEBUG", c, m)Logs a DEBUG message.
public void LogTrace(CPHAdapter adapter, string c, string m) => Log(adapter, "TRACE", c, m)Logs a TRACE message.
public void LogVerbose(CPHAdapter adapter, string c, string m) => Log(adapter, "VERBOSE", c, m)Logs a VERBOSE message.
public void LogFatal(CPHAdapter adapter, string c, string m) => Log(adapter, "FATAL", c, m)Logs a FATAL message.
public static void ResetLoggingFlag() => _isLogging = falseResets the logging flag to allow new log entries.
private void PruneLogs(CPHAdapter adapter)Enforce log retention policies (age and size).
private void CheckForRotation(CPHAdapter adapter, string path)Checks if the current log file exceeds the size limit and rotates it if necessary.
private static bool IsLogLevelEnabled(string configured, string current)Checks if the message level is enabled by the current configuration.
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).
/// <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.
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 void Register(IEventBus bus)Registers handlers for giveaway events to trigger notifications.
| Parameter | Description |
|---|---|
| bus | The event bus to subscribe to. |
private void OnWinnerSelected(WinnerSelectedEvent 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.
private void SendDiscordWebhook(CPHAdapter adapter, string webhookUrl, string message)Sends a message via Discord Webhook.
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 all bot metrics and statistics. Serialized to JSON for data persistence.
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 data. |
Base interface for all giveaway events.
CPHAdapter Adapter { get; }The CPH adapter context.
string ProfileName { get; }The name of the giveaway profile.
GiveawayState State { get; }The current state of the giveaway.
string Source { get; }The source platform or trigger.
Thread-safe Event Bus implementation.
public 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. |
public void Unsubscribe<T>(Action<T> handler) where T : IGiveawayEventUnsubscribes a handler from a specific event type.
| Parameter | Description |
|---|---|
| handler | The handler to remove. |
public void Publish<T>(T evt) where T : IGiveawayEventPublishes an event to all subscribed handlers.
| Parameter | Description |
|---|---|
| evt | The event data. |
public CPHAdapter Adapter { get; }The CPH adapter context.
public string ProfileName { get; }The name of the giveaway profile.
public GiveawayState State { get; }The current state of the giveaway.
public string Source { get; }The source platform or trigger.
protected GiveawayEventBase(CPHAdapter adapter, string profileName, GiveawayState state, string source)
protected GiveawayEventBase(CPHAdapter adapter, string profileName, GiveawayState state, string source)Initializes a new instance of the class.
| Parameter | Description |
|---|---|
| adapter | CPH adapter context. |
| profileName | Name of the giveaway profile. |
| state | Current giveaway state. |
| source | Source platform/trigger. |
Event triggered when a giveaway is started/opened.
public GiveawayStartedEvent(CPHAdapter adapter, string profileName, GiveawayState state, string source) : base(adapter, profileName, state, source) { }
public GiveawayStartedEvent(CPHAdapter adapter, string profileName, GiveawayState state, string source) : base(adapter, profileName, state, source) { }Initializes a new instance of the class.
Event triggered when a giveaway is ended/closed.
public GiveawayEndedEvent(CPHAdapter adapter, string profileName, GiveawayState state, string source) : base(adapter, profileName, state, source) { }
public GiveawayEndedEvent(CPHAdapter adapter, string profileName, GiveawayState state, string source) : base(adapter, profileName, state, source) { }Initializes a new instance of the class.
Event triggered when a winner is selected.
public Entry Winner { get; }The winning entry.
public WinnerSelectedEvent(CPHAdapter adapter, string profileName, GiveawayState state, Entry winner, string source) : base(adapter, profileName, state, source)
public WinnerSelectedEvent(CPHAdapter adapter, string profileName, GiveawayState state, Entry winner, string source) : base(adapter, profileName, state, source)Initializes a new instance of the class.
Event triggered when a valid entry is accepted.
public Entry Entry { get; }The accepted entry details.
public string MessageId { get; }Twitch Message ID for threading (optional).
public EntryAcceptedEvent(CPHAdapter adapter, string profileName, GiveawayState state, Entry entry, string source, string messageId = null) : base(adapter, profileName, state, source)
public EntryAcceptedEvent(CPHAdapter adapter, string profileName, GiveawayState state, Entry entry, string source, string messageId = null) : base(adapter, profileName, state, source)Initializes a new instance of the class.
Event triggered when a Wheel of Names link is generated and ready.
public string Url { get; }The URL of the generated wheel.
public WheelReadyEvent(CPHAdapter adapter, string profileName, GiveawayState state, string url, string source) : base(adapter, profileName, state, source)
public WheelReadyEvent(CPHAdapter adapter, string profileName, GiveawayState state, string url, string source) : base(adapter, profileName, state, source)Initializes a new instance of the class.
Container for user-specific metrics.
public MetricsService()Initializes a new instance of the MetricsService. Sets the path to the metrics storage file.
public void SaveMetrics(CPHAdapter adapter, MetricsContainer metrics)Saves metrics data to a JSON file.
| Parameter | Description |
|---|---|
| adapter | CPH adapter for logging. |
| metrics | The metrics container to save. |
public MetricsContainer LoadMetrics(CPHAdapter adapter)Loads metrics data from the JSON file.
| Parameter | Description |
|---|---|
| adapter | CPH adapter for logging. |
Returns: The loaded MetricsContainer, or a new empty one if load fails.
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.
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)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.
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.