0

我目前正在开发一个小小的 twitch.tv 聊天机器人。我知道,大约有一千个,但我想创建自己的,只是为了有一个项目——所以这不是重点。

我想知道,如何计算用户的观看时间。就像 streamelements.com 使用他们的!watchtime聊天命令一样。我没有找到任何 API 端点来获取当前正在查看流的用户。唯一找到的是https://dev.twitch.tv/docs/api/reference#get-streams中的当前观看次数,但无法链接到特定用户。

有人有什么想法吗?

4

1 回答 1

1

没有 API 端点可以直接执行此操作。但是,我最近用 PHP 做了类似的事情,不需要 Twitch API 凭证。我工作的频道使用 NightBot,所以我将尝试简要解释它是如何使用它的,以便您可以随心所欲地实施它。免责声明:我是 PHP 新手,所以它可能可以改进;此外,使用 Twitch API 中的命令可能会改进代码。

该文件名为“watchtime.php”。在更新请求时,它会获取聊天并将更新之间的时间差添加到每个用户的观看时间。在获取请求时,它会使用保存的观看时间并以天、小时、分钟和秒为单位进行解析。

要更新频道的数据库,您必须使用请求 https://path/to/watchtime.php?action=update&channel=target 的调度程序或循环,其中“target”是频道名称。请求之间的间隔必须小于 10 分钟。但是,如果只有频道正在流式传输,请确保执行请求。每个循环周期,脚本都会请求 Twitch TMI 获取聊天记录(例如 Ludwig https://tmi.twitch.tv/group/user/ludwig/chatters),然后将更新之间的时间差添加到每个聊天记录中. 我将值存储在 JSON 中;对于您的聊天机器人,我建议实施一个真实的数据库。如果更新中没有错误,则响应文本将为“OK”。

为了从 NightBot 获取观看时间,我使用了命令 $(urlfetch https://path/to/watchtime.php?action=get&channel=$(channel)&user=$(user)&time=$(time)),其中 $(urlfetch url) 返回一个 url 的输出,$(channel) 是频道名称,$(user) 是用户名,$(time) 是当前时间(它对 PHP 没有用,但它用于绕过 NightBot 中的查询缓存)。但是,我只计算观众和 VIP 的观看时间;对于一个模组,它会返回一个错误(可以更改)。

这是PHP代码:

<?php
if (!array_key_exists('channel', $_REQUEST)) {
    echo 'Empty channel';
    return;
}
if (!array_key_exists('action', $_REQUEST)) {
    echo 'Empty action (get/update)';
    return;
}

$channel = $_REQUEST['channel'];   // Channel username
$file = "{$channel}.watchtime.json";    // File with watchtime

// Open json and collect data
if (file_exists($file)) {
    $data = json_decode(file_get_contents($file), true);
} else {
    $data = [];
}
 if ($_REQUEST['action'] == 'update') {
    // Update watchtime (watchtime.php?channel=streamer&action=update)
    // Do an update only when the target is streaming!
    // You can also insert here a API call to verify it.

    $now = time();  // Epoch time
    if (array_key_exists('$', $data) && $now - $data['$'] < 600) {
        // Increment if only the last update has been made in less than 10 min.
        // This prevents increments when the stream is first loaded.

        // Fetch chatters
        $url = "http://tmi.twitch.tv/group/user/{$channel}/chatters";  // Don't use https here
        $users = json_decode(file_get_contents($url), true)['chatters'];

        // Lazy way to find if the stream is off
        if (empty($users['broadcaster'])) {
            echo 'Empty broadcaster';
            return;
        }

        // This script selects only vips ans viewers, mods watchtimes are not counted.
        $chatters = array_merge($users['vips'], $users['viewers']);
        // Increment watchtime
        $passed = $now - $data['$'];  // Time passed since last update
        foreach ($chatters as $viewer) {
            if (!array_key_exists($viewer, $data))
                $data[$viewer] = 0;
            $data[$viewer] += $passed;
        }
    }
    $data['$'] = $now;  // Store the epoch time of the update
    file_put_contents($file, json_encode($data));    // Save data
    echo "OK";

} elseif ($_REQUEST['action'] == 'get') {
    // Get watchtime of an user (watchtime.php?channel=streamer&action=get&user=username)

    if (empty($data)) {
        echo 'Empty watchtime, update it first!';
        return;
    }
    if (!array_key_exists('user', $_REQUEST)) {
        echo 'Empty username';
        return;
    }
    define("username", $_REQUEST['user']);
    if (array_key_exists(username, $data)) {
        $passed = time() - $data['$'];
        if ($passed > 600)
            $passed  = 0;
        // Both $data[username] and $passed are integers
        $s = $data[username] + $passed;

        // Parsing seconds to days, hours, mins, secs
        $m = intdiv($s, 60);
        $s -= $m * 60;
        $h = intdiv($m, 60);
        $m -= $h * 60;
        $d = intdiv($h, 24);
        $h -= $d * 24;

        // Show times if only they are greater than zeros
        $args = [];
        if ($d > 0) array_push($args, "{$d} days");
        if ($h > 0) array_push($args, "{$h} hours");
        if ($m > 0) array_push($args, "{$m} minutes");
        if ($s > 0) array_push($args, "{$s} seconds");

        echo username . ' watched  the stream for ' . implode(', ', $args) . '!';
    } else echo 'Invalid username "' . username . '": moderator, too new or nonexistent';
}

于 2021-04-28T10:37:20.717 回答