ForcePilot/backend/package/yuxi/channel/extensions/twitch/status.py

125 lines
4.6 KiB
Python
Raw Normal View History

import time
from yuxi.channel.extensions.twitch.config import (
TwitchConfig,
get_account_config,
is_account_configured,
list_account_ids,
)
from yuxi.channel.extensions.twitch.types import TwitchRole
from yuxi.channel.protocols import ChannelStatusIssue
def collect_twitch_status_issues(
config: TwitchConfig,
runtime_snapshots: dict[str, object],
) -> list[ChannelStatusIssue]:
issues = []
account_ids = list_account_ids(config)
if not account_ids:
account_ids = ["default"]
for aid in account_ids:
account = get_account_config(config, aid)
if not is_account_configured(account):
issues.append(
ChannelStatusIssue(
channel="twitch",
account_id=aid,
kind="unconfigured",
message=f"Twitch account '{aid}' is not configured",
fix="Provide username, access_token, and channel in config",
)
)
continue
if not account.enabled:
issues.append(
ChannelStatusIssue(
channel="twitch",
account_id=aid,
kind="disabled",
message=f"Twitch account '{aid}' is disabled",
)
)
continue
has_client_id = bool(account.client_id)
if not has_client_id:
issues.append(
ChannelStatusIssue(
channel="twitch",
account_id=aid,
kind="missing_client_id",
message=f"Twitch account '{aid}' is missing client_id",
fix="Add a Twitch Client ID for Helix API access",
)
)
if account.allow_from is not None and len(account.allow_from) == 0:
issues.append(
ChannelStatusIssue(
channel="twitch",
account_id=aid,
kind="empty_allowlist",
message=f"Twitch account '{aid}' has empty allow_from, which rejects all users",
fix="Add user IDs to allow_from or remove it to use open/role mode",
)
)
if TwitchRole.ALL in account.allowed_roles and account.allow_from:
issues.append(
ChannelStatusIssue(
channel="twitch",
account_id=aid,
kind="conflicting_access_control",
message=f"Twitch account '{aid}' has both allowed_roles='all' and non-empty allow_from",
fix="Choose one access control mode: either allow_from or allowed_roles, not both",
)
)
snapshot = runtime_snapshots.get(f"twitch:{aid}")
if snapshot is not None:
last_error = getattr(snapshot, "last_error", None)
if last_error:
issues.append(
ChannelStatusIssue(
channel="twitch",
account_id=aid,
kind="runtime_error",
message=f"Twitch account '{aid}' runtime error: {last_error}",
fix="Check logs and restart the channel",
)
)
running = getattr(snapshot, "running", False) or getattr(snapshot, "state", None) == "running"
last_start_at = getattr(snapshot, "last_start_at", None)
last_inbound_at = getattr(snapshot, "last_inbound_at", None)
if not running and not last_start_at and not last_inbound_at:
issues.append(
ChannelStatusIssue(
channel="twitch",
account_id=aid,
kind="never_connected",
message=f"Twitch account '{aid}' has never successfully connected",
)
)
if running and last_start_at:
uptime_seconds = time.time() - last_start_at
if uptime_seconds > 7 * 24 * 3600:
issues.append(
ChannelStatusIssue(
channel="twitch",
account_id=aid,
kind="long_uptime",
message=f"Twitch account '{aid}' has been running for over 7 days",
fix="Consider restarting the channel to refresh the IRC connection",
)
)
return issues