Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  status.ts

  Sprache: JAVA
 

/**
 * Twitch status issues collector.
 *
 * Detects and reports configuration issues for Twitch accounts.
 */


import type { ChannelStatusIssue } from "openclaw/plugin-sdk/channel-contract";
import { getAccountConfig } from "./config.js";
import { resolveTwitchToken } from "./token.js";
import type { ChannelAccountSnapshot } from "./types.js";
import { isAccountConfigured } from "./utils/twitch.js";

/**
 * Collect status issues for Twitch accounts.
 *
 * Analyzes account snapshots and detects configuration problems,
 * authentication issues, and other potential problems.
 *
 * @param accounts - Array of account snapshots to analyze
 * @param getCfg - Optional function to get full config for additional checks
 * @returns Array of detected status issues
 *
 * @example
 * const issues = collectTwitchStatusIssues(accountSnapshots);
 * if (issues.length > 0) {
 *   console.warn("Twitch configuration issues detected:");
 *   issues.forEach(issue => console.warn(`- ${issue.message}`));
 * }
 */

export function collectTwitchStatusIssues(
  accounts: ChannelAccountSnapshot[],
  getCfg?: () => unknown,
): ChannelStatusIssue[] {
  const issues: ChannelStatusIssue[] = [];

  for (const entry of accounts) {
    const accountId = entry.accountId;

    if (!accountId) {
      continue;
    }

    let account: ReturnType<typeof getAccountConfig> | null = null;
    let cfg: Parameters<typeof resolveTwitchToken>[0] | undefined;
    if (getCfg) {
      try {
        cfg = getCfg() as {
          channels?: { twitch?: { accounts?: Record<string, unknown> } };
        };
        account = getAccountConfig(cfg, accountId);
      } catch {
        // Ignore config access errors
      }
    }

    if (!entry.configured) {
      issues.push({
        channel: "twitch",
        accountId,
        kind: "config",
        message: "Twitch account is not properly configured",
        fix: "Add required fields: username, accessToken, and clientId to your account configuration",
      });
      continue;
    }

    if (entry.enabled === false) {
      issues.push({
        channel: "twitch",
        accountId,
        kind: "config",
        message: "Twitch account is disabled",
        fix: "Set enabled: true in your account configuration to enable this account",
      });
      continue;
    }

    if (account && account.username && account.accessToken && !account.clientId) {
      issues.push({
        channel: "twitch",
        accountId,
        kind: "config",
        message: "Twitch client ID is required",
        fix: "Add clientId to your Twitch account configuration (from Twitch Developer Portal)",
      });
    }

    const tokenResolution = cfg
      ? resolveTwitchToken(cfg as Parameters<typeof resolveTwitchToken>[0], { accountId })
      : { token: "", source: "none" };
    if (account && isAccountConfigured(account, tokenResolution.token)) {
      if (account.accessToken?.startsWith("oauth:")) {
        issues.push({
          channel: "twitch",
          accountId,
          kind: "config",
          message: "Token contains 'oauth:' prefix (will be stripped)",
          fix: "The 'oauth:' prefix is optional. You can use just the token value, or keep it as-is (it will be normalized automatically).",
        });
      }

      if (account.clientSecret && !account.refreshToken) {
        issues.push({
          channel: "twitch",
          accountId,
          kind: "config",
          message: "clientSecret provided without refreshToken",
          fix: "For automatic token refresh, provide both clientSecret and refreshToken. Otherwise, clientSecret is not needed.",
        });
      }

      if (account.allowFrom && account.allowFrom.length === 0) {
        issues.push({
          channel: "twitch",
          accountId,
          kind: "config",
          message: "allowFrom is configured but empty",
          fix: "Either add user IDs to allowFrom, remove the allowFrom field, or use allowedRoles instead.",
        });
      }

      if (
        account.allowedRoles?.includes("all") &&
        account.allowFrom &&
        account.allowFrom.length > 0
      ) {
        issues.push({
          channel: "twitch",
          accountId,
          kind: "intent",
          message: "allowedRoles is set to 'all' but allowFrom is also configured",
          fix: "When allowedRoles is 'all', the allowFrom list is not needed. Remove allowFrom or set allowedRoles to specific roles.",
        });
      }
    }

    if (entry.lastError) {
      issues.push({
        channel: "twitch",
        accountId,
        kind: "runtime",
        message: `Last error: ${entry.lastError}`,
        fix: "Check your token validity and network connection. Ensure the bot has the required OAuth scopes.",
      });
    }

    if (
      entry.configured &&
      !entry.running &&
      !entry.lastStartAt &&
      !entry.lastInboundAt &&
      !entry.lastOutboundAt
    ) {
      issues.push({
        channel: "twitch",
        accountId,
        kind: "runtime",
        message: "Account has never connected successfully",
        fix: "Start the Twitch gateway to begin receiving messages. Check logs for connection errors.",
      });
    }

    if (entry.running && entry.lastStartAt) {
      const uptime = Date.now() - entry.lastStartAt;
      const daysSinceStart = uptime / (1000 * 60 * 60 * 24);
      if (daysSinceStart > 7) {
        issues.push({
          channel: "twitch",
          accountId,
          kind: "runtime",
          message: `Connection has been running for ${Math.floor(daysSinceStart)} days`,
          fix: "Consider restarting the connection periodically to refresh the connection. Twitch tokens may expire after long periods.",
        });
      }
    }
  }

  return issues;
}

Messung V0.5 in Prozent
C=95 H=95 G=94

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-05-26) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge