Skip to content

chore(release): v1.5.11 - #62

Merged
Sythsaz merged 6 commits into
mainfrom
chore/release-v1.5.11
Feb 11, 2026
Merged

chore(release): v1.5.11#62
Sythsaz merged 6 commits into
mainfrom
chore/release-v1.5.11

Conversation

@Sythsaz

@Sythsaz Sythsaz commented Feb 11, 2026

Copy link
Copy Markdown
Owner

Automated release for v1.5.11.

Updates version files and changelog.

Summary by Sourcery

Introduce a cross-profile metrics system and a unified event bus, and bump the bot to version 1.5.11.

New Features:

  • Add a metrics system with global, profile-level, and per-user analytics, including JSON persistence and aggregation helpers.
  • Introduce a unified, thread-safe event bus with strongly-typed giveaway events to decouple core logic from notifications and external integrations.

Bug Fixes:

  • Prevent collection modification errors during profile synchronization by iterating over a copied profiles list.

Enhancements:

  • Refine giveaway flow to publish richer events (e.g., winner drawn, entry accepted) and update messenger/OBS handlers to consume the new event shapes.
  • Update variable synchronization to iterate over a snapshot of profiles, improving robustness during configuration sync.
  • Adjust the version update script to more robustly update version strings in wiki markdown files.

Build:

  • Bump internal version constants, VERSION file, changelog, and release notes to v1.5.11.

Documentation:

  • Update changelog and release notes for v1.5.11.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@sourcery-ai

sourcery-ai Bot commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Introduces a new cross-profile metrics system and a unified, timestamped event bus in GiveawayBot, wires them into core giveaway flows (entries, draws, lifecycle), replaces the old event/metrics implementations, and bumps the version and release metadata to v1.5.11 while tightening a version-updating script and fixing a config sync concurrency issue.

Sequence diagram for entry handling with metrics and event bus

sequenceDiagram
    actor Viewer
    participant GiveawayManager
    participant MetricsService as Metrics
    participant CPHAdapter as CPH
    participant EventBus as Bus
    participant Messenger

    Viewer->>GiveawayManager: HandleEntry(CPH, config, platform, userId, userName, tickets)
    GiveawayManager->>CPH: Validate entry and state
    CPH-->>GiveawayManager: Validation result
    alt entry accepted
        GiveawayManager->>Metrics: RecordEntry(profileName, userId, CPH)
        Metrics->>CPH: GetGlobalVar EntriesTotal
        CPH-->>Metrics: currentEntries
        Metrics->>CPH: SetGlobalVar EntriesTotal + 1
        Metrics->>CPH: GetGlobalVar profile entries
        CPH-->>Metrics: profileEntries
        Metrics->>CPH: SetGlobalVar profile entries + 1
        Metrics->>CPH: GetUserVar user entries
        CPH-->>Metrics: userEntries
        Metrics->>CPH: SetUserVar user entries + 1

        GiveawayManager->>Bus: Publish EntryAcceptedEvent(CPH, profileName, userId, userName, tickets)
        Bus->>Messenger: Invoke OnEntryAccepted(evt)
        Messenger->>CPH: Loc.Get EntryAccepted message
        Messenger->>CPH: SendBroadcast acceptedMsg, profileName
        opt toast enabled
            Messenger->>CPH: ShowToastNotification New Entry userName
        end
    else entry rejected
        GiveawayManager->>Bus: Publish EntryRejectedEvent(...)
        Bus->>Messenger: Invoke OnEntryRejected(evt)
    end
Loading

Sequence diagram for winner draw with metrics, event bus, and notifications

sequenceDiagram
    actor Moderator
    participant GiveawayManager
    participant MetricsService as Metrics
    participant CPHAdapter as CPH
    participant EventBus as Bus
    participant Messenger
    participant ObsController as Obs

    Moderator->>GiveawayManager: HandleDraw(CPH, config, platform)
    GiveawayManager->>CPH: Permission and state checks
    CPH-->>GiveawayManager: Checks ok

    GiveawayManager->>Metrics: RecordDraw(profileName, CPH)
    Metrics->>CPH: GetGlobalVar DrawsTotal
    CPH-->>Metrics: draws
    Metrics->>CPH: SetGlobalVar DrawsTotal + 1

    GiveawayManager->>GiveawayManager: Select winner
    alt winner selected
        GiveawayManager->>GiveawayManager: _cachedMetrics.WinnerDrawAttempts++
        GiveawayManager->>GiveawayManager: _cachedMetrics.WinnerDrawSuccesses++
        GiveawayManager->>Metrics: RecordWin(profileName, winnerId, CPH)
        Metrics->>CPH: GetGlobalVar WinsTotal
        CPH-->>Metrics: wins
        Metrics->>CPH: SetGlobalVar WinsTotal + 1
        Metrics->>CPH: GetGlobalVar profile wins
        CPH-->>Metrics: profileWins
        Metrics->>CPH: SetGlobalVar profile wins + 1
        Metrics->>CPH: GetUserVar user wins
        CPH-->>Metrics: userWins
        Metrics->>CPH: SetUserVar user wins + 1

        GiveawayManager->>Bus: Publish WinnerDrawnEvent(CPH, profileName, state, winnerName, winnerId)
        Bus->>Messenger: Invoke OnWinnerDrawn(evt)
        Messenger->>CPH: ShowToastNotification Giveaway Winner
        Messenger->>CPH: SendBroadcast winner message, profileName
        opt discord configured
            Messenger->>CPH: SendDiscordMessage winnerName
        end
    else no entries
        GiveawayManager->>CPH: Log no entries
    end

    opt wheel of names integration
        GiveawayManager->>Bus: Publish WheelReadyEvent(CPH, profileName, state, wheelUrl, platform)
        Bus->>Messenger: Invoke OnWheelReady(evt)
        Messenger->>CPH: SendBroadcast Wheel Ready wheelUrl, platform
        Bus->>Obs: Invoke OnWheelReady(evt)
        Obs->>CPH: SetBrowserSource scene, source, wheelUrl
    end
Loading

Class diagram for the new metrics system

classDiagram
    direction LR

    class MetricsContainer {
        +long EntriesTotal
        +long WinsTotal
        +long DrawsTotal
        +Dictionary~string, ProfileMetrics~ Profiles
        +Dictionary~string, long~ GlobalMetrics
        +Dictionary~string, UserMetricSet~ UserMetrics
        +DateTime LastUpdated
        +int MessageIdCacheSize
        +int MessageIdCleanupCount
        +int LoopDetectedCount
        +int LoopDetectedByMsgId
        +int LoopDetectedByToken
        +int LoopDetectedByBotFlag
        +int ConfigReloadCount
        +int FileIOErrors
        +long TotalEntryProcessingMs
        +int EntriesProcessedCount
        +int WinnerDrawAttempts
        +int WinnerDrawSuccesses
        +long WheelApiTotalMs
        +int WheelApiCalls
        +int ApiErrors
        +int WheelApiErrors
        +int WheelApiInvalidKeys
        +int WheelApiTimeouts
        +int WheelApiNetworkErrors
        +MetricsContainer()
        +string ToJson()
        +static MetricsContainer FromGlobalVars(CPHAdapter adapter)
    }

    class ProfileMetrics {
        +string ProfileName
        +long Entries
        +long Wins
        +long Draws
    }

    class UserMetrics {
        +string UserId
        +long EntriesTotal
        +long WinsTotal
    }

    class UserMetricSet {
        +Dictionary~string, long~ Metrics
    }

    class MetricsService {
        -string _path
        +MetricsService()
        +MetricsContainer GetGlobalMetrics(CPHAdapter adapter)
        +ProfileMetrics GetProfileMetrics(string profileName, CPHAdapter adapter)
        +UserMetrics GetUserMetrics(string userId, CPHAdapter adapter)
        +void RecordEntry(string profileName, string userId, CPHAdapter adapter)
        +void RecordWin(string profileName, string userId, CPHAdapter adapter)
        +void RecordDraw(string profileName, CPHAdapter adapter)
        +void SaveMetrics(CPHAdapter adapter, MetricsContainer metrics)
        +MetricsContainer LoadMetrics(CPHAdapter adapter)
    }

    class GiveawayManager {
        +const string Version
        +Dictionary~string, GiveawayState~ States
        +MetricsService Metrics
        +MetricsContainer _cachedMetrics
        +void SyncAllVariables(CPHAdapter adapter)
        +Task~bool~ HandleEntry(CPHAdapter adapter, GiveawayProfileConfig config, string platform, string userId, string userName, int tickets)
        +Task~bool~ HandleDraw(CPHAdapter adapter, GiveawayProfileConfig config, string platform)
        +Task~bool~ HandleStart(CPHAdapter adapter, GiveawayProfileConfig config, string platform)
        +Task~bool~ HandleEnd(CPHAdapter adapter, GiveawayProfileConfig config, string platform)
    }

    class CPHAdapter {
        +T GetGlobalVar~T~(string name, bool persisted)
        +void SetGlobalVar(string name, object value, bool persisted)
        +T GetUserVar~T~(string userId, string name, bool persisted)
        +void SetUserVar(string userId, string name, object value, bool persisted)
        +void LogDebug(string message)
        +void LogTrace(string message)
        +void LogError(string message)
    }

    MetricsContainer "1" o-- "*" ProfileMetrics : profiles
    MetricsContainer "1" o-- "*" UserMetricSet : userMetrics
    MetricsService --> MetricsContainer : uses
    MetricsService --> ProfileMetrics : returns
    MetricsService --> UserMetrics : returns
    MetricsContainer --> CPHAdapter : FromGlobalVars
    MetricsService --> CPHAdapter : persistence
    GiveawayManager "1" o-- "1" MetricsService : Metrics
    GiveawayManager "1" o-- "1" MetricsContainer : cachedMetrics
Loading

Class diagram for the unified event bus and giveaway events

classDiagram
    direction LR

    class IEventBus {
        <<interface>>
        +void Subscribe~T~(Action~T~ handler)
        +void Unsubscribe~T~(Action~T~ handler)
        +void Publish~T~(T evt)
    }

    class IGiveawayEvent {
        <<interface>>
        +CPHAdapter Adapter
        +string ProfileName
        +DateTime Timestamp
    }

    class EventBus {
        -Dictionary~Type, List~Delegate~~ _subscribers
        -object _lock
        +EventBus()
        +void Subscribe~T~(Action~T~ handler)
        +void Unsubscribe~T~(Action~T~ handler)
        +void Publish~T~(T evt)
    }

    class GiveawayStartedEvent {
        +CPHAdapter Adapter
        +string ProfileName
        +DateTime Timestamp
        +GiveawayState State
        +GiveawayStartedEvent(CPHAdapter adapter, string profileName, GiveawayState state)
    }

    class GiveawayEndedEvent {
        +CPHAdapter Adapter
        +string ProfileName
        +DateTime Timestamp
        +GiveawayState State
        +GiveawayEndedEvent(CPHAdapter adapter, string profileName, GiveawayState state)
    }

    class WinnerDrawnEvent {
        +CPHAdapter Adapter
        +string ProfileName
        +DateTime Timestamp
        +GiveawayState State
        +string WinnerName
        +string WinnerId
        +WinnerDrawnEvent(CPHAdapter adapter, string profileName, GiveawayState state, string winnerName, string winnerId)
    }

    class WheelReadyEvent {
        +CPHAdapter Adapter
        +string ProfileName
        +DateTime Timestamp
        +GiveawayState State
        +string WheelUrl
        +string Platform
        +WheelReadyEvent(CPHAdapter adapter, string profileName, GiveawayState state, string wheelUrl, string platform)
    }

    class EntryAcceptedEvent {
        +CPHAdapter Adapter
        +string ProfileName
        +DateTime Timestamp
        +string UserId
        +string UserName
        +int TicketCount
        +EntryAcceptedEvent(CPHAdapter adapter, string profileName, string userId, string userName, int ticketCount)
    }

    class EntryRejectedEvent {
        +CPHAdapter Adapter
        +string ProfileName
        +DateTime Timestamp
        +string UserId
        +string UserName
        +string Reason
        +EntryRejectedEvent(CPHAdapter adapter, string profileName, string userId, string userName, string reason)
    }

    class ToastNotificationEvent {
        +CPHAdapter Adapter
        +string ProfileName
        +DateTime Timestamp
        +string Title
        +string Message
        +ToastNotificationEvent(CPHAdapter adapter, string profileName, string title, string message)
    }

    class ChatMessageEvent {
        +CPHAdapter Adapter
        +string ProfileName
        +DateTime Timestamp
        +string Message
        +string Platform
        +ChatMessageEvent(CPHAdapter adapter, string profileName, string message, string platform)
    }

    class ObsUpdateEvent {
        +CPHAdapter Adapter
        +string ProfileName
        +DateTime Timestamp
        +string Scene
        +string Source
        +string Url
        +ObsUpdateEvent(CPHAdapter adapter, string profileName, string scene, string source, string url)
    }

    class MetricsUpdatedEvent {
        +CPHAdapter Adapter
        +string ProfileName
        +DateTime Timestamp
        +string MetricName
        +long Value
        +MetricsUpdatedEvent(CPHAdapter adapter, string profileName, string metricName, long value)
    }

    class ConfigReloadedEvent {
        +CPHAdapter Adapter
        +string ProfileName
        +DateTime Timestamp
        +ConfigReloadedEvent(CPHAdapter adapter, string profileName)
    }

    class GiveawayManager {
        +IEventBus Bus
        +void Initialize(CPHAdapter adapter)
        +Task~bool~ HandleStart(CPHAdapter adapter, GiveawayProfileConfig config, string platform)
        +Task~bool~ HandleEnd(CPHAdapter adapter, GiveawayProfileConfig config, string platform)
        +Task~bool~ HandleEntry(CPHAdapter adapter, GiveawayProfileConfig config, string platform, string userId, string userName, int tickets)
        +Task~bool~ HandleDraw(CPHAdapter adapter, GiveawayProfileConfig config, string platform)
    }

    class Messenger {
        +MessengerConfig Config
        +void Register(IEventBus bus)
        -void OnWinnerDrawn(WinnerDrawnEvent evt)
        -void OnWheelReady(WheelReadyEvent evt)
        -void OnGiveawayStarted(GiveawayStartedEvent evt)
        -void OnGiveawayEnded(GiveawayEndedEvent evt)
        -void OnEntryAccepted(EntryAcceptedEvent evt)
    }

    class ObsController {
        +void Register(IEventBus bus)
        -void OnWheelReady(WheelReadyEvent evt)
    }

    IEventBus <|.. EventBus
    IGiveawayEvent <|.. GiveawayStartedEvent
    IGiveawayEvent <|.. GiveawayEndedEvent
    IGiveawayEvent <|.. WinnerDrawnEvent
    IGiveawayEvent <|.. WheelReadyEvent
    IGiveawayEvent <|.. EntryAcceptedEvent
    IGiveawayEvent <|.. EntryRejectedEvent
    IGiveawayEvent <|.. ToastNotificationEvent
    IGiveawayEvent <|.. ChatMessageEvent
    IGiveawayEvent <|.. ObsUpdateEvent
    IGiveawayEvent <|.. MetricsUpdatedEvent
    IGiveawayEvent <|.. ConfigReloadedEvent

    EventBus "1" o-- "*" IGiveawayEvent : publishes
    GiveawayManager "1" o-- "1" IEventBus : Bus
    Messenger ..> IEventBus : subscribes
    ObsController ..> IEventBus : subscribes
Loading

File-Level Changes

Change Details Files
Add rich metrics models and a metrics service that support global/profile/user analytics and JSON persistence, and wire them into giveaway entry and draw flows.
  • Introduce MetricsContainer with aggregate counts (entries, wins, draws), per-profile metrics, legacy diagnostic fields, and JSON serialization helpers.
  • Add ProfileMetrics and UserMetrics models for per-profile and per-user statistics.
  • Extend MetricsService to expose read APIs for global/profile/user metrics and to record entries, wins, and draws while retaining JSON save/load for diagnostics.
  • Invoke MetricsService.RecordEntry, RecordDraw, and RecordWin in HandleEntry and HandleDraw to track cross-profile analytics.
GiveawayBot.cs
Replace the bespoke GiveawayEventBus and event hierarchy with a simplified, timestamped EventBus and a flatter set of concrete event types, updating publisher and subscriber code accordingly.
  • Define a new IGiveawayEvent shape that carries adapter, profile name, and creation timestamp instead of inheriting from GiveawayEventBase.
  • Implement a thread-safe EventBus that isolates handler exceptions and replaces GiveawayEventBus in GiveawayManager initialization.
  • Add specific event classes for giveaway lifecycle, entries, winners, wheel readiness, notifications, metrics updates, chat/OBS actions, and config reloads, using simpler payloads (e.g., WinnerDrawnEvent with winner name/id, EntryAcceptedEvent with user/ticket info).
  • Update all event publication sites (start, end, entry accepted, winner drawn, wheel ready) and Messenger/OBS handlers to use the new event types and properties, including renaming WinnerSelectedEvent handling to WinnerDrawnEvent and adjusting message/Discord logic.
  • Remove the old MetricsContainer models, GiveawayEventBus, IGiveawayEvent/GiveawayEventBase hierarchy, and the previous MetricsService definition that only handled persistence.
GiveawayBot.cs
Fix a collection-modified exception during config sync by iterating over a snapshot of the profiles collection.
  • Change the SyncAllVariables loop to iterate over GlobalConfig.Profiles.ToList() instead of the live collection to avoid concurrent modification.
  • Document the stability fix in the changelog under the Fixed section for v1.5.11.
GiveawayBot.cs
CHANGELOG.md
Update versioning and release metadata to v1.5.11 and adjust tooling and documentation accordingly.
  • Bump GiveawayManager.Version constant to 1.5.11 and update the VERSION file.
  • Add a 1.5.11 section to CHANGELOG.md capturing metrics/event bus additions, refactoring, infra changes, and fixes.
  • Update RELEASE_NOTES.md header to v1.5.11.
  • Loosen the wiki version replacement regex in update-version.ps1 to handle headings with multiple asterisks around "Version".
  • Add/modify ancillary project/config files (.editorconfig, StreamerBot.csproj, TEST_STARTED.txt, test_debug.log) as part of the release artifacts.
GiveawayBot.cs
CHANGELOG.md
RELEASE_NOTES.md
tools/update-version.ps1
.editorconfig
StreamerBot.csproj
VERSION
TEST_STARTED.txt
test_debug.log

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • The new UserMetricSet/MetricsService definitions appear duplicated and partially inlined into the MetricsService class (note the stray // ADD THESE METHODS TO MetricsService CLASS comment and _path field), which will likely cause type/brace/structure issues—please consolidate these into a single, clean definition in one region.
  • The refactor of EntryAcceptedEvent/WinnerDrawnEvent drops the Source/platform and message/threading data and then reuses ProfileName as the broadcast target (e.g., SendBroadcast(..., evt.ProfileName)), which changes behavior from the previous platform-aware implementation—consider explicitly carrying the platform and any needed message metadata in the new events instead of overloading profile name.
  • Files TEST_STARTED.txt and test_debug.log look like temporary/debug artifacts and probably should not be committed; consider removing them from the repository.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `UserMetricSet`/`MetricsService` definitions appear duplicated and partially inlined into the `MetricsService` class (note the stray `// ADD THESE METHODS TO MetricsService CLASS` comment and `_path` field), which will likely cause type/brace/structure issues—please consolidate these into a single, clean definition in one region.
- The refactor of `EntryAcceptedEvent`/`WinnerDrawnEvent` drops the `Source`/platform and message/threading data and then reuses `ProfileName` as the broadcast target (e.g., `SendBroadcast(..., evt.ProfileName)`), which changes behavior from the previous platform-aware implementation—consider explicitly carrying the platform and any needed message metadata in the new events instead of overloading profile name.
- Files `TEST_STARTED.txt` and `test_debug.log` look like temporary/debug artifacts and probably should not be committed; consider removing them from the repository.

## Individual Comments

### Comment 1
<location> `GiveawayBot.cs:482-491` </location>
<code_context>
+        adapter.SetGlobalVar(profileKey, profileDraws + 1, true);
+    }
+
+    /// <summary>
+/// Legacy diagnostic metric set for a user (backward compatibility).
+/// </summary>
+public class UserMetricSet
+{
+    public Dictionary<string, long> Metrics { get; set; } = new Dictionary<string, long>();
</code_context>

<issue_to_address>
**issue (bug_risk):** UserMetricSet is now nested inside MetricsService but still referenced as a top-level type, which will not compile.

Earlier in the file, `MetricsContainer` exposes `Dictionary<string, UserMetricSet> UserMetrics`, assuming `UserMetricSet` is a top-level type. If `UserMetricSet` is nested inside `MetricsService`, it must be referenced as `MetricsService.UserMetricSet`, and it won’t be in scope at the `MetricsContainer` declaration. This will not compile. Either keep `UserMetricSet` as a top-level class or update all references (and type ordering) to use the nested type correctly.
</issue_to_address>

### Comment 2
<location> `GiveawayBot.cs:9050` </location>
<code_context>
                  if (!string.IsNullOrEmpty(msg))
                  {
-                     SendBroadcast(evt.Adapter, msg, evt.Source);
+                     SendBroadcast(evt.Adapter, msg, evt.ProfileName);
                  }

</code_context>

<issue_to_address>
**issue (bug_risk):** Using ProfileName as the broadcast "platform" alters the semantics from the previous implementation and is likely incorrect.

In the old flow, `OnWinnerSelected` passed `evt.Source` (the platform/trigger) into `SendBroadcast`, but the refactor now passes `evt.ProfileName`. Unless `SendBroadcast` has been updated to treat this argument as a profile name, this risks misrouting broadcasts or breaking multi‑platform behavior. Please add a platform field to `WinnerDrawnEvent` (analogous to `Source`) and pass that through instead.
</issue_to_address>

### Comment 3
<location> `GiveawayBot.cs:9123` </location>
<code_context>
-                 // Reply directly to the user with platform-specific threading
-                 SendReply(evt.Adapter, acceptedMsg, evt.Source, evt.Entry.UserName, evt.MessageId);
+                 // Broadcast confirmation
+                 SendBroadcast(evt.Adapter, acceptedMsg, evt.ProfileName);

                  // Handle Toast notification
</code_context>

<issue_to_address>
**question (bug_risk):** EntryAccepted handling switched from a targeted reply to a profile-based broadcast and dropped platform information.

Previously, replying via `SendReply` used the platform and message ID to keep responses scoped and threaded; the new `SendBroadcast` call will send this to all listeners and loses that context. If this broader visibility isn’t explicitly desired, consider restoring `Platform` (and optionally `MessageId`) on `EntryAcceptedEvent` and continuing to call `SendReply`. If the broadcast is intentional, please double‑check that `ProfileName` is the correct third parameter for `SendBroadcast`, as this may not match its expected API.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread GiveawayBot.cs
Comment thread GiveawayBot.cs Outdated
Comment thread GiveawayBot.cs Outdated
Signed-off-by: Sythsaz <53737244+Sythsaz@users.noreply.github.com>
Signed-off-by: Sythsaz <53737244+Sythsaz@users.noreply.github.com>
@Sythsaz Sythsaz self-assigned this Feb 11, 2026
@Sythsaz Sythsaz added bug Something isn't working enhancement New feature or request labels Feb 11, 2026
@Sythsaz
Sythsaz merged commit 9d3859a into main Feb 11, 2026
14 checks passed
@Sythsaz
Sythsaz deleted the chore/release-v1.5.11 branch February 11, 2026 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant