Skip to content

Instantly share code, notes, and snippets.

@AzureFlow
Created August 22, 2020 02:55
Show Gist options
  • Save AzureFlow/6bdf776f4bcdaa765f3dee357063edde to your computer and use it in GitHub Desktop.
Save AzureFlow/6bdf776f4bcdaa765f3dee357063edde to your computer and use it in GitHub Desktop.
A simple chat downloader for Twitch VODs
<?php
//Get a Client-ID here: https://dev.twitch.tv/docs/v5#getting-a-client-id
define('CLIENT_ID', '<INSERT CLIENT_ID>');
//$blacklistUsers = array('Nightbot', 'StreamElements');
if(isset($argv[1]))
{
$vodURL = $argv[1];
if(filter_var($vodURL, FILTER_VALIDATE_URL))
{
$parse = parse_url($vodURL);
if(strpos(strtolower($parse['host']), strtolower('twitch.tv')) === false)
{
die('Make sure it\'s a Twitch.tv link' . PHP_EOL);
}
$vodID = explode('/', $parse['path']);
$vodID = $vodID[2];
if(!is_numeric($vodID))
{
die('Id not a number!');
}
}
else if(is_numeric($vodURL))
{
$vodID = $vodURL;
}
else
{
die('Invalid URL!' . PHP_EOL);
}
}
else
{
die('Usage: ChatDrain <vod url>!' . PHP_EOL);
}
$outputFile = "$vodID-chatlog.txt";
if(file_exists($outputFile)) unlink($outputFile); //DELETE FILE
$request = getData($vodID, array('content_offset_seconds' => 0));
$response = $request['response'];
$err = $request['err'];
echo 'Starting...' . PHP_EOL;
if(!$err) //TODO: Make this recursive function
{
concatFile($outputFile, implode(PHP_EOL, processBatch($response)));
$cursor = $response['_next'];
//echo "Starting NEXT cursor:\n\t$cursor" . PHP_EOL . PHP_EOL;
while(true)
{
$request = getData($vodID, array('cursor' => $cursor));
$response = $request['response'];
$err = $request['err'];
if(!$err)
concatFile($outputFile, implode(PHP_EOL, processBatch($response)));
else
echo "cURL Error #$err";
if(isset($response['_next']))
{
$cursor = $response['_next'];
}
else
{
break;
}
echo 'Waiting...' . PHP_EOL;
//Be nice to Twitch and prevent them from banning us
//sleep(1);
usleep(0.25 * 1000000);
}
}
else
echo "cURL Error #$err";
// exec('explorer.exe /select,"' . $outputFile . '"');
echo 'FINISHED!' . PHP_EOL . PHP_EOL;
function processBatch($response)
{
$messages = array();
foreach($response['comments'] as $comment) //TODO: Error handling
{
$author = $comment['commenter']['name'];
//if(in_array(strtolower($author), array_map("strtolower", $blacklistUsers)))
// continue;
$displayName = $comment['commenter']['display_name'];
$message = $comment['message']['body'];
if(isset($comment['message']['user_badges']))
$prefix = hasRole('moderator', $comment['message']['user_badges']) ? 'M' : '';
$date = date("m/d/Y h:s A", strtotime($comment['created_at']));
$timecode = formatSeconds($comment['content_offset_seconds']);
$messages[] = sprintf('[%s] - [%s] %s%s%s: %s',
$date,
$timecode,
(isset($prefix) && !empty($prefix) ? "[$prefix] " : ''), //TODO: Not working
$displayName,
(!compareStr($displayName, $author, false) ? " ($author)" : ''),
$message
);
unset($prefix);
}
//echo '==========' . PHP_EOL;
return $messages;
}
function formatSeconds($seconds)
{
return sprintf('%02d:%02d:%02d', ($seconds / 3600),($seconds / 60%60), $seconds % 60);
}
function compareStr($str1, $str2, $caseSensitive=true)
{
if($caseSensitive)
return $str1 == $str2;
else
return strtolower($str1) == strtolower($str2);
}
function getData($vodID, $query)
{
$query = http_build_query($query, null, '&', PHP_QUERY_RFC3986);
$url = "https://api.twitch.tv/v5/videos/$vodID/comments" . (!empty($query) ? "?$query" : '');
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
'accept: application/vnd.twitchtv.v5+json',
'client-id: ' . CLIENT_ID
)
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
return array('response' => json_decode($response, true), 'err' => $err);
}
function concatFile($file, $text)
{
file_put_contents($file, PHP_EOL . $text, FILE_APPEND);
}
function hasRole($role, $arr)
{
$result = false;
foreach($arr as $item)
{
if($item['_id'] == $role)
{
$result = true;
break;
}
}
return $result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment