diff --git a/bridges/TwitchBridge.php b/bridges/TwitchBridge.php new file mode 100644 index 00000000..39b46010 --- /dev/null +++ b/bridges/TwitchBridge.php @@ -0,0 +1,202 @@ + array( + 'name' => 'Channel', + 'type' => 'text', + 'required' => true, + 'title' => 'Lowercase channel name as seen in channel URL' + ), + 'type' => array( + 'name' => 'Type', + 'type' => 'list', + 'values' => array( + 'All' => 'all', + 'Archive' => 'archive', + 'Highlights' => 'highlight', + 'Uploads' => 'upload' + ), + 'defaultValue' => 'archive' + ) + )); + + /* + * Official instructions for obtaining your own client ID can be found here: + * https://dev.twitch.tv/docs/v5/#getting-a-client-id + */ + const CLIENT_ID = 'kimne78kx3ncx6brgo4mv6wki5h1ko'; + + public function collectData(){ + // get channel user + $query_data = array( + 'login' => $this->getInput('channel') + ); + $users = $this->apiGet('users', $query_data)->users; + if(count($users) === 0) + returnClientError('User "' + . $this->getInput('channel') + . '" could not be found'); + $user = $users[0]; + + // get video list + $query_endpoint = 'channels/' . $user->_id . '/videos'; + $query_data = array( + 'broadcast_type' => $this->getInput('type'), + 'limit' => 10 + ); + $videos = $this->apiGet($query_endpoint, $query_data)->videos; + + foreach($videos as $video) { + $item = array( + 'uri' => $video->url, + 'title' => $video->title, + 'timestamp' => $video->published_at, + 'author' => $video->channel->display_name, + ); + + // Add categories for tags and played game + $item['categories'] = array_filter(explode(' ', $video->tag_list)); + if(!empty($video->game)) + $item['categories'][] = $video->game; + + // Add enclosures for thumbnails from a few points in the video + $item['enclosures'] = array(); + foreach($video->thumbnails->large as $thumbnail) + $item['enclosures'][] = $thumbnail->url; + + /* + * Content format example: + * + * [Preview Image] + * + * Some optional video description. + * + * Duration: 1:23:45 + * Views: 123 + * + * Played games: + * * 00:00:00 Game 1 + * * 00:12:34 Game 2 + * + */ + $item['content'] = '

' + . $video->description_html + . '

Duration: ' + . $this->formatTimestampTime($video->length) + . '
Views: ' + . $video->views + . '

'; + + // Add played games list to content + $video_id = trim($video->_id, 'v'); // _id gives 'v1234' but API wants '1234' + $markers = $this->apiGet('videos/' . $video_id . '/markers')->markers; + $item['content'] .= '

Played games:

'; + + $this->items[] = $item; + } + } + + // e.g. 01:53:27 + private function formatTimestampTime($seconds) { + return sprintf('%02d:%02d:%02d', + floor($seconds / 3600), + ($seconds / 60) % 60, + $seconds % 60); + } + + // e.g. 01h53m27s + private function formatQueryTime($seconds) { + return sprintf('%02dh%02dm%02ds', + floor($seconds / 3600), + ($seconds / 60) % 60, + $seconds % 60); + } + + /* + * Ideally the new 'helix' API should be used as v5/'kraken' is deprecated. + * The new API however still misses many features (markers, played game..) of + * the old one, so let's use the old one for as long as it's available. + */ + private function apiGet($endpoint, $query_data = array()) { + $query_data['api_version'] = 5; + $url = 'https://api.twitch.tv/kraken/' + . $endpoint + . '?' + . http_build_query($query_data); + $header = array( + 'Client-ID: ' . self::CLIENT_ID + ); + + $data = json_decode(getContents($url, $header)) + or returnServerError('API request to "' . $url . '" failed.'); + + return $data; + } + + public function getName(){ + if(!is_null($this->getInput('channel'))) { + return $this->getInput('channel') . ' twitch videos'; + } + + return parent::getName(); + } + + public function getURI(){ + if(!is_null($this->getInput('channel'))) { + return self::URI . $this->getInput('channel'); + } + + return parent::getURI(); + } + + public function detectParameters($url){ + $params = array(); + + // Matches e.g. https://www.twitch.tv/someuser/videos?filter=archives + $regex = '/^(https?:\/\/)? + (www\.)? + twitch\.tv\/ + ([^\/&?\n]+) + \/videos\?.*filter= + (all|archive|highlight|upload)/x'; + if(preg_match($regex, $url, $matches) > 0) { + $params['channel'] = urldecode($matches[3]); + $params['type'] = $matches[4]; + return $params; + } + + return null; + } +}