Documentation
¶
Overview ¶
Package model defines pure data types for all Twitch miner entities. These types have no external dependencies and are safe for concurrent use where documented.
Index ¶
- func GetPredictionWindow(settings *BetSettings, predictionWindowSeconds float64) float64
- func LookupGameSlug(gameID string) string
- func Percentage(a, b int) int
- func RegisterGameSlug(gameID, slug string)
- func ShouldJoinChat(presence ChatPresence, isOnline bool) bool
- type Bet
- type BetDecision
- type BetSettings
- type Campaign
- type ChatPresence
- type CommunityGoal
- type Condition
- type DelayMode
- type Drop
- type Event
- type EventPrediction
- type FilterCondition
- type FollowersOrder
- type GameInfo
- type HistoryEntry
- type Message
- type MessageType
- type Outcome
- type OutcomeKey
- type PointsMultiplier
- type PredictionResult
- type Priority
- type PubSubTopic
- type PubSubTopicType
- type Raid
- type Strategy
- type Stream
- func (s *Stream) GameDisplayName() string
- func (s *Stream) GameID() string
- func (s *Stream) GameName() string
- func (s *Stream) GameSlug() string
- func (s *Stream) InitWatchStreak()
- func (s *Stream) IsMinuteWatchStalled(threshold time.Duration) bool
- func (s *Stream) MarkUpdated()
- func (s *Stream) String() string
- func (s *Stream) Update(broadcastID, title string, game *GameInfo, tags []Tag, viewersCount int, ...)
- func (s *Stream) UpdateElapsed() time.Duration
- func (s *Stream) UpdateMinuteWatched()
- func (s *Stream) UpdateRequired() bool
- type Streamer
- func (s *Streamer) DeleteCommunityGoal(goalID string)
- func (s *Streamer) DropsCondition() bool
- func (s *Streamer) HasPointsMultiplier() bool
- func (s *Streamer) MarshalJSON() ([]byte, error)
- func (s *Streamer) ResolveCategory() string
- func (s *Streamer) SetOffline()
- func (s *Streamer) SetOnline()
- func (s *Streamer) StreamUpElapsed() bool
- func (s *Streamer) String() string
- func (s *Streamer) TotalPointsMultiplier() float64
- func (s *Streamer) UpdateCommunityGoal(goal *CommunityGoal)
- func (s *Streamer) UpdateHistory(reasonCode string, earned int, counter int)
- type StreamerSettings
- type Tag
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GetPredictionWindow ¶
func GetPredictionWindow(settings *BetSettings, predictionWindowSeconds float64) float64
GetPredictionWindow calculates the actual delay before placing a bet based on settings.
func LookupGameSlug ¶
LookupGameSlug returns the slug for a game ID, or "" if not found.
func Percentage ¶
Percentage calculates the integer percentage of a/b. Delegates to utils.Percentage for the canonical implementation.
func RegisterGameSlug ¶
func RegisterGameSlug(gameID, slug string)
RegisterGameSlug records a game ID → slug mapping in the global registry. Both gameID and slug must be non-empty; empty values are silently ignored.
func ShouldJoinChat ¶
func ShouldJoinChat(presence ChatPresence, isOnline bool) bool
ShouldJoinChat returns whether the miner should join chat for the given presence setting and online state.
Types ¶
type Bet ¶
type Bet struct {
Outcomes []Outcome `json:"outcomes"`
Decision BetDecision `json:"decision"`
TotalUsers int `json:"total_users"`
TotalPoints int `json:"total_points"`
Settings *BetSettings `json:"-"`
}
Bet holds the state of a prediction bet calculation.
func NewBet ¶
func NewBet(outcomes []Outcome, settings *BetSettings) *Bet
NewBet creates a new Bet from a list of outcomes and settings.
func (*Bet) Calculate ¶
func (b *Bet) Calculate(balance int) BetDecision
Calculate determines which outcome to bet on and how much to bet.
func (*Bet) Skip ¶
Skip checks the filter condition and returns whether the bet should be skipped and the compared value.
func (*Bet) UpdateOutcomes ¶
UpdateOutcomes refreshes outcome statistics from new data.
type BetDecision ¶
type BetDecision struct {
Choice int `json:"choice"`
Amount int `json:"amount"`
OutcomeID string `json:"id"`
}
BetDecision holds the result of a bet calculation.
type BetSettings ¶
type BetSettings struct {
Strategy Strategy `json:"strategy" yaml:"strategy"`
Percentage int `json:"percentage" yaml:"percentage"`
PercentageGap int `json:"percentage_gap" yaml:"percentage_gap"`
MaxPoints int `json:"max_points" yaml:"max_points"`
MinimumPoints int `json:"minimum_points" yaml:"minimum_points"`
StealthMode bool `json:"stealth_mode" yaml:"stealth_mode"`
FilterCondition *FilterCondition `json:"filter_condition,omitempty" yaml:"filter_condition"`
Delay float64 `json:"delay" yaml:"delay"`
DelayMode DelayMode `json:"delay_mode" yaml:"delay_mode"`
}
BetSettings holds configuration for automatic prediction betting.
func DefaultBetSettings ¶
func DefaultBetSettings() *BetSettings
DefaultBetSettings returns BetSettings with default values.
func (*BetSettings) String ¶
func (bs *BetSettings) String() string
String returns a human-readable representation of the bet settings.
type Campaign ¶
type Campaign struct {
ID string `json:"id"`
Game *GameInfo `json:"game,omitempty"`
Name string `json:"name"`
Status string `json:"status"`
IsInInventory bool `json:"in_inventory"`
EndAt time.Time `json:"end_at"`
StartAt time.Time `json:"start_at"`
IsWithinTimeWindow bool `json:"dt_match"`
Drops []*Drop `json:"drops,omitempty"`
Channels []string `json:"channels,omitempty"`
}
Campaign represents a Twitch drop campaign.
func NewCampaign ¶
func NewCampaign(id, name, status string, game *GameInfo, startAt, endAt time.Time, channels []string) *Campaign
NewCampaign creates a Campaign from raw API data.
func (*Campaign) ClearDrops ¶
func (c *Campaign) ClearDrops()
ClearDrops removes drops that are outside the time window or already claimed.
type ChatPresence ¶
type ChatPresence int
ChatPresence controls when the miner joins a streamer's IRC chat.
const ( // ChatAlways means always stay in chat. ChatAlways ChatPresence = iota // ChatNever means never join chat. ChatNever // ChatOnline means join chat only when the streamer is online. ChatOnline // ChatOffline means join chat only when the streamer is offline. ChatOffline )
func ParseChatPresence ¶
func ParseChatPresence(s string) ChatPresence
ParseChatPresence converts a string to a ChatPresence value.
func (ChatPresence) String ¶
func (c ChatPresence) String() string
String returns the string representation of a ChatPresence value.
type CommunityGoal ¶
type CommunityGoal struct {
GoalID string `json:"goal_id"`
Title string `json:"title"`
IsInStock bool `json:"is_in_stock"`
PointsContributed int `json:"points_contributed"`
AmountNeeded int `json:"amount_needed"`
PerStreamUserMaxContribution int `json:"per_stream_user_maximum_contribution"`
Status string `json:"status"`
}
CommunityGoal represents a channel community goal.
func CommunityGoalFromGQL ¶
func CommunityGoalFromGQL(data map[string]any) *CommunityGoal
CommunityGoalFromGQL creates a CommunityGoal from a GQL response map.
func CommunityGoalFromPubSub ¶
func CommunityGoalFromPubSub(data map[string]any) *CommunityGoal
CommunityGoalFromPubSub creates a CommunityGoal from a PubSub message map.
func NewCommunityGoal ¶
func NewCommunityGoal(goalID, title string, isInStock bool, pointsContributed, amountNeeded, perStreamMax int, status string) *CommunityGoal
NewCommunityGoal creates a new CommunityGoal.
func (*CommunityGoal) AmountLeft ¶
func (cg *CommunityGoal) AmountLeft() int
AmountLeft returns the remaining points needed to complete the goal.
func (*CommunityGoal) Equal ¶
func (cg *CommunityGoal) Equal(other *CommunityGoal) bool
Equal returns true if two community goals have the same ID.
func (*CommunityGoal) String ¶
func (cg *CommunityGoal) String() string
String returns a human-readable representation of the community goal.
type Condition ¶
type Condition int
Condition defines a comparison operator for filter conditions.
func ParseCondition ¶
ParseCondition converts a string to a Condition value.
type DelayMode ¶
type DelayMode int
DelayMode defines how the prediction delay is calculated.
func ParseDelayMode ¶
ParseDelayMode converts a string to a DelayMode value.
type Drop ¶
type Drop struct {
ID string `json:"id"`
Name string `json:"name"`
Benefit string `json:"benefit"`
MinutesRequired int `json:"minutes_required"`
HasPreconditionsMet *bool `json:"has_preconditions_met,omitempty"`
CurrentMinutesWatched int `json:"current_minutes_watched"`
DropInstanceID string `json:"drop_instance_id,omitempty"`
IsClaimed bool `json:"is_claimed"`
IsClaimable bool `json:"is_claimable"`
IsPrintable bool `json:"is_printable"`
IsSynthetic bool `json:"is_synthetic"`
PercentageProgress int `json:"percentage_progress"`
EndAt time.Time `json:"end_at"`
StartAt time.Time `json:"start_at"`
IsWithinTimeWindow bool `json:"dt_match"`
}
Drop represents a single time-based drop within a campaign.
func NewDrop ¶
func NewDrop(id, name string, benefits []string, minutesRequired int, startAt, endAt time.Time) *Drop
NewDrop creates a Drop from raw API data.
func (*Drop) ProgressBar ¶
ProgressBar returns a text-based progress bar for the drop.
type Event ¶
type Event string
Event represents a miner event type for notification filtering and logging.
const ( EventStreamerOnline Event = "STREAMER_ONLINE" EventStreamerOffline Event = "STREAMER_OFFLINE" EventGainForRaid Event = "GAIN_FOR_RAID" EventGainForClaim Event = "GAIN_FOR_CLAIM" EventGainForWatch Event = "GAIN_FOR_WATCH" EventGainForWatchStreak Event = "GAIN_FOR_WATCH_STREAK" EventBetWin Event = "BET_WIN" EventBetLose Event = "BET_LOSE" EventBetRefund Event = "BET_REFUND" EventBetFilters Event = "BET_FILTERS" EventBetGeneral Event = "BET_GENERAL" EventBetFailed Event = "BET_FAILED" EventBetStart Event = "BET_START" EventBonusClaim Event = "BONUS_CLAIM" EventMomentClaim Event = "MOMENT_CLAIM" EventJoinRaid Event = "JOIN_RAID" EventDropClaim Event = "DROP_CLAIM" EventDropClaimAvailable Event = "DROP_CLAIM_AVAILABLE" EventDropStatus Event = "DROP_STATUS" EventChatMention Event = "CHAT_MENTION" EventGiftedSub Event = "GIFTED_SUB" EventMinerStarted Event = "MINER_STARTED" EventMinerStopped Event = "MINER_STOPPED" EventMinerCrashed Event = "MINER_CRASHED" EventAccountConfigReloaded Event = "ACCOUNT_CONFIG_RELOADED" EventDropMilestone Event = "DROP_MILESTONE" EventTest Event = "TEST" )
All supported miner events.
func ParseEvent ¶
ParseEvent converts a string to an Event. Returns empty string if invalid.
type EventPrediction ¶
type EventPrediction struct {
Mu sync.Mutex `json:"-"`
Streamer *Streamer `json:"-"`
EventID string `json:"event_id"`
Title string `json:"title"`
CreatedAt time.Time `json:"created_at"`
PredictionWindowSeconds float64 `json:"prediction_window_seconds"`
Status string `json:"status"`
Result PredictionResult `json:"result"`
ScheduledFor time.Time `json:"scheduled_for"`
BetConfirmed bool `json:"bet_confirmed"`
BetPlaced bool `json:"bet_placed"`
BetSkipped bool `json:"bet_skipped"`
PlacementInFlight bool `json:"placement_in_flight"`
PlacementAttempts int `json:"placement_attempts"`
LastAttemptAt time.Time `json:"last_attempt_at"`
LastFailedReason string `json:"last_failed_reason"`
Bet *Bet `json:"bet"`
}
EventPrediction represents an active prediction event on a channel.
func NewEventPrediction ¶
func NewEventPrediction( streamer *Streamer, eventID, title string, createdAt time.Time, predictionWindowSeconds float64, status string, outcomes []Outcome, ) *EventPrediction
NewEventPrediction creates a new EventPrediction.
func (*EventPrediction) ClosingBetAfter ¶
func (ep *EventPrediction) ClosingBetAfter(timestamp time.Time) float64
ClosingBetAfter returns the seconds remaining until the prediction window closes.
func (*EventPrediction) Elapsed ¶
func (ep *EventPrediction) Elapsed(timestamp time.Time) float64
Elapsed returns the seconds elapsed since the prediction was created.
func (*EventPrediction) ParseResult ¶
func (ep *EventPrediction) ParseResult(resultType string, pointsWon int) map[string]int
ParseResult processes a prediction result and returns the points breakdown.
func (*EventPrediction) String ¶
func (ep *EventPrediction) String() string
String returns a human-readable representation of the event prediction.
type FilterCondition ¶
type FilterCondition struct {
By OutcomeKey `json:"by" yaml:"by"`
Where Condition `json:"where" yaml:"where"`
Value float64 `json:"value" yaml:"value"`
}
FilterCondition defines a condition for filtering predictions before betting.
func (*FilterCondition) String ¶
func (fc *FilterCondition) String() string
String returns a human-readable representation of the filter condition.
type FollowersOrder ¶
type FollowersOrder int
FollowersOrder defines the sort order for followed channels.
const ( // FollowersOrderASC sorts followers in ascending order. FollowersOrderASC FollowersOrder = iota // FollowersOrderDESC sorts followers in descending order. FollowersOrderDESC )
func ParseFollowersOrder ¶
func ParseFollowersOrder(s string) FollowersOrder
ParseFollowersOrder converts a string to a FollowersOrder value.
func (FollowersOrder) String ¶
func (fo FollowersOrder) String() string
String returns the string representation of a FollowersOrder.
type GameInfo ¶
type GameInfo struct {
ID string `json:"id"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
Slug string `json:"slug,omitempty"`
}
GameInfo holds game/category metadata from the Twitch API.
type HistoryEntry ¶
HistoryEntry tracks cumulative points earned for a specific reason code.
type Message ¶
type Message struct {
Topic string `json:"topic"`
TopicUser string `json:"topic_user"`
RawMessage map[string]any `json:"message"`
Type MessageType `json:"type"`
Data map[string]any `json:"data,omitempty"`
Timestamp time.Time `json:"timestamp"`
ChannelID string `json:"channel_id"`
Identifier string `json:"identifier"`
}
Message represents a parsed PubSub message.
func ParseMessage ¶
ParseMessage creates a Message from raw PubSub data.
type MessageType ¶
type MessageType string
MessageType represents the type of a PubSub message for notification routing.
const ( // Points-related messages MsgTypePointsEarned MessageType = "points-earned" MsgTypePointsSpent MessageType = "points-spent" MsgTypeClaimAvailable MessageType = "claim-available" MsgTypeClaimClaimed MessageType = "claim-claimed" // Prediction messages MsgTypePredictionEvent MessageType = "event-created" MsgTypePredictionUpdate MessageType = "event-updated" MsgTypePredictionLocked MessageType = "event-locked" MsgTypePredictionResult MessageType = "event-end" // Stream messages MsgTypeStreamUp MessageType = "stream-up" MsgTypeStreamDown MessageType = "stream-down" MsgTypeViewCount MessageType = "viewcount" // Raid messages MsgTypeRaidUpdate MessageType = "raid_update_v2" MsgTypeRaidGo MessageType = "raid_go_v2" MsgTypeRaidCancel MessageType = "raid_cancel_v2" // Moment messages MsgTypeMomentAvailable MessageType = "active" // Community goal messages MsgTypeGoalContribution MessageType = "community-goal-contribution" MsgTypeGoalUpdated MessageType = "community-goal-updated" )
Message types for PubSub events.
type Outcome ¶
type Outcome struct {
ID string `json:"id"`
Title string `json:"title"`
Color string `json:"color"`
TotalUsers int `json:"total_users"`
TotalPoints int `json:"total_points"`
TopPoints int `json:"top_points"`
PercentageUsers float64 `json:"percentage_users"`
Odds float64 `json:"odds"`
OddsPercentage float64 `json:"odds_percentage"`
}
Outcome represents a single prediction outcome with computed statistics.
type OutcomeKey ¶
type OutcomeKey string
OutcomeKey defines the keys used to access outcome statistics.
const ( // OutcomeKeyPercentageUsers is the percentage of users who voted for this outcome. OutcomeKeyPercentageUsers OutcomeKey = "percentage_users" // OutcomeKeyOddsPercentage is the odds expressed as a percentage. OutcomeKeyOddsPercentage OutcomeKey = "odds_percentage" // OutcomeKeyOdds is the raw odds multiplier. OutcomeKeyOdds OutcomeKey = "odds" // OutcomeKeyTopPoints is the highest individual bet on this outcome. OutcomeKeyTopPoints OutcomeKey = "top_points" // OutcomeKeyTotalUsers is the total number of users who bet on this outcome. OutcomeKeyTotalUsers OutcomeKey = "total_users" // OutcomeKeyTotalPoints is the total points bet on this outcome. OutcomeKeyTotalPoints OutcomeKey = "total_points" // OutcomeKeyDecisionUsers is a virtual key for filter conditions. OutcomeKeyDecisionUsers OutcomeKey = "decision_users" // OutcomeKeyDecisionPoints is a virtual key for filter conditions. OutcomeKeyDecisionPoints OutcomeKey = "decision_points" )
type PointsMultiplier ¶
type PointsMultiplier struct {
Factor float64 `json:"factor"`
}
PointsMultiplier represents an active channel points multiplier.
type PredictionResult ¶
type PredictionResult struct {
ResultString string `json:"string"`
Type string `json:"type"`
Gained int `json:"gained"`
}
PredictionResult holds the result of a resolved prediction.
type Priority ¶
type Priority int
Priority defines the watch priority strategy for selecting which streamers to watch.
const ( // PriorityOrder uses the order defined in the config file. PriorityOrder Priority = iota // PriorityStreak prioritizes streamers where a watch streak bonus is pending. PriorityStreak // PriorityDrops prioritizes streamers with active drop campaigns. PriorityDrops // PrioritySubscribed prioritizes subscribed channels. PrioritySubscribed // PriorityPointsAscending prioritizes streamers with the fewest points. PriorityPointsAscending // PriorityPointsDescending prioritizes streamers with the most points. PriorityPointsDescending // PriorityEndingSoonest prioritizes campaigns ending soonest. PriorityEndingSoonest // PriorityLowAvailabilityFirst prioritizes campaigns with the lowest availability. PriorityLowAvailabilityFirst )
func ParsePriority ¶
ParsePriority converts a string to a Priority value.
type PubSubTopic ¶
type PubSubTopic struct {
TopicType PubSubTopicType `json:"topic_type"`
UserID string `json:"user_id,omitempty"`
Streamer *Streamer `json:"-"`
}
PubSubTopic represents a PubSub subscription topic.
func NewStreamerTopic ¶
func NewStreamerTopic(topicType PubSubTopicType, streamer *Streamer) *PubSubTopic
NewStreamerTopic creates a PubSubTopic scoped to a specific streamer's channel.
func NewUserTopic ¶
func NewUserTopic(topicType PubSubTopicType, userID string) *PubSubTopic
NewUserTopic creates a PubSubTopic scoped to the authenticated user.
func (*PubSubTopic) IsUserTopic ¶
func (pt *PubSubTopic) IsUserTopic() bool
IsUserTopic returns true if this topic is scoped to the user (not a streamer).
func (*PubSubTopic) String ¶
func (pt *PubSubTopic) String() string
String returns the full topic string in the format "topic_name.id".
type PubSubTopicType ¶
type PubSubTopicType int
PubSubTopicType identifies the category of a PubSub topic.
const ( // PubSubTopicVideoPlayback tracks stream up/down and viewer count. PubSubTopicVideoPlayback PubSubTopicType = iota // PubSubTopicCommunityPoints tracks channel points events. PubSubTopicCommunityPoints // PubSubTopicPredictions tracks prediction events on a channel. PubSubTopicPredictions // PubSubTopicPredictionsUser tracks the user's own prediction events. PubSubTopicPredictionsUser // PubSubTopicRaid tracks raid events. PubSubTopicRaid // PubSubTopicCommunityMoments tracks community moment events. PubSubTopicCommunityMoments // PubSubTopicCommunityGoals tracks community goal events. PubSubTopicCommunityGoals )
func (PubSubTopicType) String ¶
func (t PubSubTopicType) String() string
String returns the Twitch topic string prefix for this topic type.
type Strategy ¶
type Strategy int
Strategy defines the prediction betting strategy.
const ( // StrategyMostVoted bets on the outcome with the most voters. StrategyMostVoted Strategy = iota // StrategyHighOdds bets on the outcome with the highest odds. StrategyHighOdds // StrategyPercentage bets on the outcome with the highest odds percentage. StrategyPercentage // StrategySmartMoney bets on the outcome with the highest top predictor points. StrategySmartMoney // StrategySmart uses a hybrid approach: high odds if close, most voted otherwise. StrategySmart // StrategyNumber1 always bets on outcome index 0. StrategyNumber1 // StrategyNumber2 always bets on outcome index 1. StrategyNumber2 // StrategyNumber3 always bets on outcome index 2. StrategyNumber3 // StrategyNumber4 always bets on outcome index 3. StrategyNumber4 // StrategyNumber5 always bets on outcome index 4. StrategyNumber5 // StrategyNumber6 always bets on outcome index 5. StrategyNumber6 // StrategyNumber7 always bets on outcome index 6. StrategyNumber7 // StrategyNumber8 always bets on outcome index 7. StrategyNumber8 )
func ParseStrategy ¶
ParseStrategy converts a string to a Strategy value.
type Stream ¶
type Stream struct {
BroadcastID string `json:"broadcast_id,omitempty"`
Title string `json:"title,omitempty"`
Game *GameInfo `json:"game,omitempty"`
Tags []Tag `json:"tags,omitempty"`
HasDropsTag bool `json:"drops_tags"`
Campaigns []Campaign `json:"campaigns,omitempty"`
CampaignIDs []string `json:"campaign_ids,omitempty"`
ViewersCount int `json:"viewers_count"`
SpadeURL string `json:"spade_url,omitempty"`
Payload map[string]any `json:"payload,omitempty"`
IsWatchStreakMissing bool `json:"watch_streak_missing"`
MinuteWatched float64 `json:"minute_watched"`
LastMinuteCreditedAt time.Time `json:"last_minute_credited_at,omitempty"`
StalledCooldownUntil time.Time `json:"stalled_cooldown_until,omitempty"`
// contains filtered or unexported fields
}
Stream represents the current state of a live broadcast.
func (*Stream) GameDisplayName ¶
GameDisplayName returns the game's display name, or empty string if no game is set.
func (*Stream) GameName ¶
GameName returns the game's internal name, or empty string if no game is set.
func (*Stream) GameSlug ¶
GameSlug returns the game's URL-friendly slug from the Twitch API. It checks the direct API field first, then falls back to the global game slug registry (populated by the category watcher). No string normalization is performed — slugs must come from the Twitch API.
func (*Stream) InitWatchStreak ¶
func (s *Stream) InitWatchStreak()
InitWatchStreak resets the watch streak tracking state.
func (*Stream) IsMinuteWatchStalled ¶ added in v1.24.6
IsMinuteWatchStalled returns true when the last successful minute-watched credit is older than the given threshold. A zero LastMinuteCreditedAt (never credited) is not considered stalled — the streamer is simply new.
func (*Stream) MarkUpdated ¶
func (s *Stream) MarkUpdated()
MarkUpdated sets lastUpdate to the current time without changing other fields. This is useful when a stream is discovered via an external source (e.g. category watcher) and we want to prevent UpdateRequired() from immediately returning true.
func (*Stream) Update ¶
func (s *Stream) Update(broadcastID, title string, game *GameInfo, tags []Tag, viewersCount int, dropID string)
Update refreshes the stream information with new data.
func (*Stream) UpdateElapsed ¶
UpdateElapsed returns the duration since the last stream info update.
func (*Stream) UpdateMinuteWatched ¶
func (s *Stream) UpdateMinuteWatched()
UpdateMinuteWatched increments the minute-watched counter based on elapsed time.
func (*Stream) UpdateRequired ¶
UpdateRequired returns true if the stream info needs refreshing (>= 120s since last update).
type Streamer ¶
type Streamer struct {
Mu sync.RWMutex `json:"-"`
Username string `json:"username"`
ChannelID string `json:"channel_id"`
DisplayName string `json:"display_name,omitempty"`
AccountUsername string `json:"-"` // The miner account that owns this streamer
Settings *StreamerSettings `json:"settings,omitempty"`
IsOnline bool `json:"is_online"`
IsCategoryWatched bool `json:"is_category_watched"`
CategorySlug string `json:"category_slug,omitempty"`
IsTeamWatched bool `json:"is_team_watched"`
TeamName string `json:"team_name,omitempty"`
StreamUpAt time.Time `json:"stream_up_at"`
OnlineAt time.Time `json:"online_at"`
OfflineAt time.Time `json:"offline_at"`
ChannelPoints int `json:"channel_points"`
CommunityGoals map[string]*CommunityGoal `json:"community_goals,omitempty"`
ViewerIsMod bool `json:"viewer_is_mod"`
ActiveMultipliers []PointsMultiplier `json:"active_multipliers,omitempty"`
Stream *Stream `json:"stream"`
Raid *Raid `json:"raid,omitempty"`
History map[string]*HistoryEntry `json:"history,omitempty"`
StreamerURL string `json:"streamer_url"`
}
Streamer represents a Twitch channel being watched by the miner. Fields that may be accessed concurrently are protected by Mu.
func NewStreamer ¶
NewStreamer creates a new Streamer with sensible defaults.
func (*Streamer) DeleteCommunityGoal ¶
DeleteCommunityGoal removes a community goal by ID.
func (*Streamer) DropsCondition ¶
DropsCondition returns true if the streamer qualifies for drops collection.
func (*Streamer) HasPointsMultiplier ¶
HasPointsMultiplier returns true if the viewer has active points multipliers.
func (*Streamer) MarshalJSON ¶
MarshalJSON implements custom JSON marshaling to handle the mutex.
func (*Streamer) ResolveCategory ¶
ResolveCategory returns the best available category identifier for this streamer. It checks CategorySlug first, then the API-provided game slug (including the global registry lookup), then falls back to the game's display name. Returns "unknown" only if no category information is available at all. Must be called with Mu held (at least RLock).
func (*Streamer) SetOffline ¶
func (s *Streamer) SetOffline()
SetOffline marks the streamer as offline. Must be called with Mu held.
func (*Streamer) SetOnline ¶
func (s *Streamer) SetOnline()
SetOnline marks the streamer as online. Must be called with Mu held.
When the streamer returns after a short offline gap (< 30 min), the streak resolution state from the previous segment is carried over. If the streak was already resolved before going offline, it stays resolved — Twitch counts short restarts as the same stream.
func (*Streamer) StreamUpElapsed ¶
StreamUpElapsed returns true if enough time has passed since the last stream-up event.
func (*Streamer) TotalPointsMultiplier ¶
TotalPointsMultiplier returns the sum of all active multiplier factors.
func (*Streamer) UpdateCommunityGoal ¶
func (s *Streamer) UpdateCommunityGoal(goal *CommunityGoal)
UpdateCommunityGoal adds or updates a community goal for this streamer.
type StreamerSettings ¶
type StreamerSettings struct {
MakePredictions bool `json:"make_predictions" yaml:"make_predictions"`
FollowRaid bool `json:"follow_raid" yaml:"follow_raid"`
ClaimDrops bool `json:"claim_drops" yaml:"claim_drops"`
ClaimMoments bool `json:"claim_moments" yaml:"claim_moments"`
WatchStreak bool `json:"watch_streak" yaml:"watch_streak"`
CommunityGoalsEnabled bool `json:"community_goals" yaml:"community_goals"`
DropsOnly bool `json:"drops_only" yaml:"drops_only"`
Bet *BetSettings `json:"bet,omitempty" yaml:"bet"`
Chat ChatPresence `json:"chat" yaml:"chat"`
}
StreamerSettings holds per-streamer feature toggles and bet configuration.
func DefaultStreamerSettings ¶
func DefaultStreamerSettings() *StreamerSettings
DefaultStreamerSettings returns StreamerSettings with default values.