aboutsummaryrefslogtreecommitdiff
path: root/bridges/TwitchBridge.php
diff options
context:
space:
mode:
Diffstat (limited to 'bridges/TwitchBridge.php')
-rw-r--r--bridges/TwitchBridge.php399
1 files changed, 207 insertions, 192 deletions
diff --git a/bridges/TwitchBridge.php b/bridges/TwitchBridge.php
index a0e089dd..c26dafc6 100644
--- a/bridges/TwitchBridge.php
+++ b/bridges/TwitchBridge.php
@@ -1,58 +1,60 @@
<?php
-class TwitchBridge extends BridgeAbstract {
- const MAINTAINER = 'Roliga';
- const NAME = 'Twitch Bridge';
- const URI = 'https://twitch.tv/';
- const CACHE_TIMEOUT = 300; // 5min
- const DESCRIPTION = 'Twitch channel videos';
- const PARAMETERS = array( array(
- 'channel' => array(
- 'name' => 'Channel',
- 'type' => 'text',
- 'required' => true,
- 'exampleValue' => 'criticalrole',
- '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',
- 'Past Premieres' => 'past_premiere',
- 'Premiere Uploads' => 'premiere_upload'
- ),
- 'defaultValue' => 'archive'
- )
- ));
+class TwitchBridge extends BridgeAbstract
+{
+ const MAINTAINER = 'Roliga';
+ const NAME = 'Twitch Bridge';
+ const URI = 'https://twitch.tv/';
+ const CACHE_TIMEOUT = 300; // 5min
+ const DESCRIPTION = 'Twitch channel videos';
+ const PARAMETERS = [ [
+ 'channel' => [
+ 'name' => 'Channel',
+ 'type' => 'text',
+ 'required' => true,
+ 'exampleValue' => 'criticalrole',
+ 'title' => 'Lowercase channel name as seen in channel URL'
+ ],
+ 'type' => [
+ 'name' => 'Type',
+ 'type' => 'list',
+ 'values' => [
+ 'All' => 'all',
+ 'Archive' => 'archive',
+ 'Highlights' => 'highlight',
+ 'Uploads' => 'upload',
+ 'Past Premieres' => 'past_premiere',
+ 'Premiere Uploads' => 'premiere_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';
+ /*
+ * 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';
- const API_ENDPOINT = 'https://gql.twitch.tv/gql';
- const BROADCAST_TYPES = array(
- 'all' => array(
- 'ARCHIVE',
- 'HIGHLIGHT',
- 'UPLOAD',
- 'PAST_PREMIERE',
- 'PREMIERE_UPLOAD'
- ),
- 'archive' => 'ARCHIVE',
- 'highlight' => 'HIGHLIGHT',
- 'upload' => 'UPLOAD',
- 'past_premiere' => 'PAST_PREMIERE',
- 'premiere_upload' => 'PREMIERE_UPLOAD'
- );
+ const API_ENDPOINT = 'https://gql.twitch.tv/gql';
+ const BROADCAST_TYPES = [
+ 'all' => [
+ 'ARCHIVE',
+ 'HIGHLIGHT',
+ 'UPLOAD',
+ 'PAST_PREMIERE',
+ 'PREMIERE_UPLOAD'
+ ],
+ 'archive' => 'ARCHIVE',
+ 'highlight' => 'HIGHLIGHT',
+ 'upload' => 'UPLOAD',
+ 'past_premiere' => 'PAST_PREMIERE',
+ 'premiere_upload' => 'PREMIERE_UPLOAD'
+ ];
- public function collectData(){
- $query = <<<'EOD'
+ public function collectData()
+ {
+ $query = <<<'EOD'
query VODList($channel: String!, $types: [BroadcastType!]) {
user(login: $channel) {
displayName
@@ -89,176 +91,189 @@ query VODList($channel: String!, $types: [BroadcastType!]) {
}
}
EOD;
- $variables = array(
- 'channel' => $this->getInput('channel'),
- 'types' => self::BROADCAST_TYPES[$this->getInput('type')]
- );
- $data = $this->apiRequest($query, $variables);
+ $variables = [
+ 'channel' => $this->getInput('channel'),
+ 'types' => self::BROADCAST_TYPES[$this->getInput('type')]
+ ];
+ $data = $this->apiRequest($query, $variables);
- $user = $data->user;
- foreach($user->videos->edges as $edge) {
- $video = $edge->node;
+ $user = $data->user;
+ foreach ($user->videos->edges as $edge) {
+ $video = $edge->node;
- $url = 'https://www.twitch.tv/videos/' . $video->id;
+ $url = 'https://www.twitch.tv/videos/' . $video->id;
- $item = array(
- 'uri' => $url,
- 'title' => $video->title,
- 'timestamp' => $video->publishedAt,
- 'author' => $user->displayName,
- );
+ $item = [
+ 'uri' => $url,
+ 'title' => $video->title,
+ 'timestamp' => $video->publishedAt,
+ 'author' => $user->displayName,
+ ];
- // Add categories for tags and played game
- $item['categories'] = $video->tags;
- if(!is_null($video->game))
- $item['categories'][] = $video->game->displayName;
- foreach($video->contentTags as $tag)
- if(!$tag->isLanguageTag)
- $item['categories'][] = $tag->localizedName;
+ // Add categories for tags and played game
+ $item['categories'] = $video->tags;
+ if (!is_null($video->game)) {
+ $item['categories'][] = $video->game->displayName;
+ }
+ foreach ($video->contentTags as $tag) {
+ if (!$tag->isLanguageTag) {
+ $item['categories'][] = $tag->localizedName;
+ }
+ }
- // Add enclosures for thumbnails from a few points in the video
- // Thumbnail list has duplicate entries sometimes so remove those
- $item['enclosures'] = array_unique($video->thumbnailURLs);
+ // Add enclosures for thumbnails from a few points in the video
+ // Thumbnail list has duplicate entries sometimes so remove those
+ $item['enclosures'] = array_unique($video->thumbnailURLs);
- /*
- * 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'] = '<p><a href="'
- . $url
- . '"><img src="'
- . $video->previewThumbnailURL
- . '" /></a></p><p>'
- . $video->description // in markdown format
- . '</p><p><b>Duration:</b> '
- . $this->formatTimestampTime($video->lengthSeconds)
- . '<br/><b>Views:</b> '
- . $video->viewCount
- . '</p>';
+ /*
+ * 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'] = '<p><a href="'
+ . $url
+ . '"><img src="'
+ . $video->previewThumbnailURL
+ . '" /></a></p><p>'
+ . $video->description // in markdown format
+ . '</p><p><b>Duration:</b> '
+ . $this->formatTimestampTime($video->lengthSeconds)
+ . '<br/><b>Views:</b> '
+ . $video->viewCount
+ . '</p>';
- // Add played games list to content
- $item['content'] .= '<p><b>Played games:</b><ul>';
- if(count($video->moments->edges) > 0) {
- foreach($video->moments->edges as $edge) {
- $moment = $edge->node;
+ // Add played games list to content
+ $item['content'] .= '<p><b>Played games:</b><ul>';
+ if (count($video->moments->edges) > 0) {
+ foreach ($video->moments->edges as $edge) {
+ $moment = $edge->node;
- $item['categories'][] = $moment->description;
- $item['content'] .= '<li><a href="'
- . $url
- . '?t='
- . $this->formatQueryTime($moment->positionMilliseconds / 1000)
- . '">'
- . $this->formatTimestampTime($moment->positionMilliseconds / 1000)
- . '</a> - '
- . $moment->description
- . '</li>';
- }
- } else {
- $item['content'] .= '<li><a href="'
- . $url
- . '">00:00:00</a> - '
- . ($video->game ? $video->game->displayName : 'No Game')
- . '</li>';
- }
- $item['content'] .= '</ul></p>';
+ $item['categories'][] = $moment->description;
+ $item['content'] .= '<li><a href="'
+ . $url
+ . '?t='
+ . $this->formatQueryTime($moment->positionMilliseconds / 1000)
+ . '">'
+ . $this->formatTimestampTime($moment->positionMilliseconds / 1000)
+ . '</a> - '
+ . $moment->description
+ . '</li>';
+ }
+ } else {
+ $item['content'] .= '<li><a href="'
+ . $url
+ . '">00:00:00</a> - '
+ . ($video->game ? $video->game->displayName : 'No Game')
+ . '</li>';
+ }
+ $item['content'] .= '</ul></p>';
- $item['categories'] = array_unique($item['categories']);
+ $item['categories'] = array_unique($item['categories']);
- $this->items[] = $item;
- }
- }
+ $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. 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);
- }
+ // e.g. 01h53m27s
+ private function formatQueryTime($seconds)
+ {
+ return sprintf(
+ '%02dh%02dm%02ds',
+ floor($seconds / 3600),
+ ($seconds / 60) % 60,
+ $seconds % 60
+ );
+ }
- // GraphQL: https://graphql.org/
- // Tool for developing/testing queries: https://github.com/skevy/graphiql-app
- private function apiRequest($query, $variables) {
- $request = array(
- 'query' => $query,
- 'variables' => $variables
- );
- $header = array(
- 'Client-ID: ' . self::CLIENT_ID
- );
- $opts = array(
- CURLOPT_CUSTOMREQUEST => 'POST',
- CURLOPT_POSTFIELDS => json_encode($request)
- );
+ // GraphQL: https://graphql.org/
+ // Tool for developing/testing queries: https://github.com/skevy/graphiql-app
+ private function apiRequest($query, $variables)
+ {
+ $request = [
+ 'query' => $query,
+ 'variables' => $variables
+ ];
+ $header = [
+ 'Client-ID: ' . self::CLIENT_ID
+ ];
+ $opts = [
+ CURLOPT_CUSTOMREQUEST => 'POST',
+ CURLOPT_POSTFIELDS => json_encode($request)
+ ];
- Debug::log("Sending GraphQL query:\n" . $query);
- Debug::log("Sending GraphQL variables:\n"
- . json_encode($variables, JSON_PRETTY_PRINT));
+ Debug::log("Sending GraphQL query:\n" . $query);
+ Debug::log("Sending GraphQL variables:\n"
+ . json_encode($variables, JSON_PRETTY_PRINT));
- $response = json_decode(getContents(self::API_ENDPOINT, $header, $opts));
+ $response = json_decode(getContents(self::API_ENDPOINT, $header, $opts));
- Debug::log("Got GraphQL response:\n"
- . json_encode($response, JSON_PRETTY_PRINT));
+ Debug::log("Got GraphQL response:\n"
+ . json_encode($response, JSON_PRETTY_PRINT));
- if(isset($response->errors)) {
- $messages = array_column($response->errors, 'message');
- returnServerError('API error(s): ' . implode("\n", $messages));
- }
+ if (isset($response->errors)) {
+ $messages = array_column($response->errors, 'message');
+ returnServerError('API error(s): ' . implode("\n", $messages));
+ }
- return $response->data;
- }
+ return $response->data;
+ }
- public function getName(){
- if(!is_null($this->getInput('channel'))) {
- return $this->getInput('channel') . ' twitch videos';
- }
+ public function getName()
+ {
+ if (!is_null($this->getInput('channel'))) {
+ return $this->getInput('channel') . ' twitch videos';
+ }
- return parent::getName();
- }
+ return parent::getName();
+ }
- public function getURI(){
- if(!is_null($this->getInput('channel'))) {
- return self::URI . $this->getInput('channel');
- }
+ public function getURI()
+ {
+ if (!is_null($this->getInput('channel'))) {
+ return self::URI . $this->getInput('channel');
+ }
- return parent::getURI();
- }
+ return parent::getURI();
+ }
- public function detectParameters($url){
- $params = array();
+ public function detectParameters($url)
+ {
+ $params = [];
- // Matches e.g. https://www.twitch.tv/someuser/videos?filter=archives
- $regex = '/^(https?:\/\/)?
+ // 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;
- }
+ if (preg_match($regex, $url, $matches) > 0) {
+ $params['channel'] = urldecode($matches[3]);
+ $params['type'] = $matches[4];
+ return $params;
+ }
- return null;
- }
+ return null;
+ }
}