如何获得 Twitch 观看时间(如流元素)

How to get Twitch watchtime (like streamelements)

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

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

有人知道吗?

没有 API 端点可以直接执行此操作。 然而,我最近用 PHP 做了类似的事情,不需要 Twitch API 凭证。我工作的频道使用 NightBot,因此我将尝试简要说明它如何使用它,以便您可以根据需要实施它。 免责声明:我是 PHP 的新手,所以它可能可以改进;此外,使用来自 Twitch API 的命令可能可以完善代码。

文件名为 'watchtime.php'。根据更新请求,它获取聊天记录并将更新之间的时间差添加到每个用户的观看时间中。在 get 请求中,它获取保存的手表时间并以天、小时、分钟和秒为单位解析它。

要更新频道的数据库,您必须使用请求 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) returns一个url的输出,$(channel)是频道名,$(user)是用户名,$(time)是当前时间(对PHP没用,但在NightBot中用来绕过查询缓存)。 但是,我只计算观众和 VIP 的观看时间;对于 mod,它将 return 出错(可以更改)。

这是 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';
}