Skip to content

Commit

Permalink
Merge pull request #131 from nicklaw5/v5-0-5
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandin authored Jun 16, 2021
2 parents 0a49d6e + b0a047a commit d4cab23
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 6 deletions.
6 changes: 6 additions & 0 deletions spec/NewTwitchApi/NewTwitchApiSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use NewTwitchApi\Resources\ModerationApi;
use NewTwitchApi\Resources\PollsApi;
use NewTwitchApi\Resources\PredictionsApi;
use NewTwitchApi\Resources\ScheduleApi;
use NewTwitchApi\Resources\StreamsApi;
use NewTwitchApi\Resources\SubscriptionsApi;
use NewTwitchApi\Resources\TagsApi;
Expand Down Expand Up @@ -88,6 +89,11 @@ function it_should_provide_predictions_api()
$this->getPredictionsApi()->shouldBeAnInstanceOf(PredictionsApi::class);
}

function it_should_provide_schedule_api()
{
$this->getScheduleApi()->shouldBeAnInstanceOf(ScheduleApi::class);
}

function it_should_provide_subscriptions_api()
{
$this->getSubscriptionsApi()->shouldBeAnInstanceOf(SubscriptionsApi::class);
Expand Down
2 changes: 1 addition & 1 deletion spec/NewTwitchApi/Resources/EventSubApiSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function it_should_subscribe_to_channel_subscription_gift(RequestGenerator $requ

function it_should_subscribe_to_channel_subscription_message(RequestGenerator $requestGenerator, Request $request, Response $response)
{
$this->createEventSubSubscription('channel.subscription.message', 'beta', ['broadcaster_user_id' => '12345'], $requestGenerator)->willReturn($request);
$this->createEventSubSubscription('channel.subscription.message', '1', ['broadcaster_user_id' => '12345'], $requestGenerator)->willReturn($request);
$this->subscribeToChannelSubscriptionMessage($this->bearer, $this->secret, $this->callback, '12345')->shouldBe($response);
}

Expand Down
84 changes: 84 additions & 0 deletions spec/NewTwitchApi/Resources/ScheduleApiSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

namespace spec\NewTwitchApi\Resources;

use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use NewTwitchApi\RequestGenerator;
use NewTwitchApi\HelixGuzzleClient;
use PhpSpec\ObjectBehavior;

class ScheduleApiSpec extends ObjectBehavior
{
function let(HelixGuzzleClient $guzzleClient, RequestGenerator $requestGenerator, Request $request, Response $response)
{
$this->beConstructedWith($guzzleClient, $requestGenerator);
$guzzleClient->send($request)->willReturn($response);
}

function it_should_get_channel_stream_schedule(RequestGenerator $requestGenerator, Request $request, Response $response)
{
$requestGenerator->generate('GET', 'schedule', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
$this->getChannelStreamSchedule('TEST_TOKEN', '123')->shouldBe($response);
}

function it_should_get_channel_stream_schedule_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
{
$requestGenerator->generate('GET', 'schedule', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'start_time', 'value' => '2021-06-15T23:08:20+00:00'], ['key' => 'utc_offset', 'value' => '240'], ['key' => 'first', 'value' => 25], ['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
$this->getChannelStreamSchedule('TEST_TOKEN', '123', [], '2021-06-15T23:08:20+00:00', '240', 25, 'abc')->shouldBe($response);
}

function it_should_get_a_channel_stream_schedule(RequestGenerator $requestGenerator, Request $request, Response $response)
{
$requestGenerator->generate('GET', 'schedule', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '456']], [])->willReturn($request);
$this->getChannelStreamSchedule('TEST_TOKEN', '123', ['456'])->shouldBe($response);
}

function it_should_get_multiple_channel_stream_schedules(RequestGenerator $requestGenerator, Request $request, Response $response)
{
$requestGenerator->generate('GET', 'schedule', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '456'], ['key' => 'id', 'value' => '789']], [])->willReturn($request);
$this->getChannelStreamSchedule('TEST_TOKEN', '123', ['456', '789'])->shouldBe($response);
}

function it_should_get_channel_icalendar_with_no_auth(RequestGenerator $requestGenerator, Request $request, Response $response)
{
$requestGenerator->generate('GET', 'schedule/icalendar', null, [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
$this->getChanneliCalendar(null, '123')->shouldBe($response);
}

function it_should_get_channel_icalendar_with_auth(RequestGenerator $requestGenerator, Request $request, Response $response)
{
$requestGenerator->generate('GET', 'schedule/icalendar', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
$this->getChanneliCalendar('TEST_TOKEN', '123')->shouldBe($response);
}

function it_should_update_channel_stream_schedule(RequestGenerator $requestGenerator, Request $request, Response $response)
{
$requestGenerator->generate('PATCH', 'schedule/settings', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'is_vacation_enabled', 'value' => true], ['key' => 'vacation_start_time', 'value' => '2021-06-15T23:08:20+00:00'], ['key' => 'vacation_end_time', 'value' => '2021-06-22T23:08:20+00:00'], ['key' => 'timezone', 'value' => 'America/New_York']], [])->willReturn($request);
$this->updateChannelStreamSchedule('TEST_TOKEN', '123', true, '2021-06-15T23:08:20+00:00', '2021-06-22T23:08:20+00:00', 'America/New_York')->shouldBe($response);
}

function it_should_create_channel_stream_schedule_segment(RequestGenerator $requestGenerator, Request $request, Response $response)
{
$requestGenerator->generate('POST', 'schedule/segment', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [['key' => 'start_time', 'value' => '2021-06-15T23:08:20+00:00'], ['key' => 'timezone', 'value' => 'America/New_York'], ['key' => 'is_recurring', 'value' => true]])->willReturn($request);
$this->createChannelStreamScheduleSegment('TEST_TOKEN', '123', '2021-06-15T23:08:20+00:00', 'America/New_York', true)->shouldBe($response);
}

function it_should_create_channel_stream_schedule_segment_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
{
$requestGenerator->generate('POST', 'schedule/segment', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [['key' => 'start_time', 'value' => '2021-06-15T23:08:20+00:00'], ['key' => 'timezone', 'value' => 'America/New_York'], ['key' => 'is_recurring', 'value' => true], ['key' => 'duration', 'value' => '240']])->willReturn($request);
$this->createChannelStreamScheduleSegment('TEST_TOKEN', '123', '2021-06-15T23:08:20+00:00', 'America/New_York', true, ['duration' => '240'])->shouldBe($response);
}

function it_should_update_channel_stream_schedule_segment(RequestGenerator $requestGenerator, Request $request, Response $response)
{
$requestGenerator->generate('PATCH', 'schedule/segment', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '456']], [['key' => 'start_time', 'value' => '2021-06-15T23:08:20+00:00'], ['key' => 'timezone', 'value' => 'America/New_York'], ['key' => 'is_canceled', 'value' => true], ['key' => 'duration', 'value' => '240']])->willReturn($request);
$this->updateChannelStreamScheduleSegment('TEST_TOKEN', '123', '456', ['start_time' => '2021-06-15T23:08:20+00:00', 'timezone' => 'America/New_York', 'is_canceled' => true, 'duration' => '240'])->shouldBe($response);
}

function it_should_delete_channel_stream_schedule_segment(RequestGenerator $requestGenerator, Request $request, Response $response)
{
$requestGenerator->generate('DELETE', 'schedule/segment', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '456']], [])->willReturn($request);
$this->deleteChannelStreamScheduleSegment('TEST_TOKEN', '123', '456')->shouldBe($response);
}
}
8 changes: 8 additions & 0 deletions src/NewTwitchApi/NewTwitchApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use NewTwitchApi\Resources\ModerationApi;
use NewTwitchApi\Resources\PollsApi;
use NewTwitchApi\Resources\PredictionsApi;
use NewTwitchApi\Resources\ScheduleApi;
use NewTwitchApi\Resources\SearchApi;
use NewTwitchApi\Resources\StreamsApi;
use NewTwitchApi\Resources\SubscriptionsApi;
Expand Down Expand Up @@ -47,6 +48,7 @@ class NewTwitchApi
private $moderationApi;
private $pollsApi;
private $predictionsApi;
private $scheduleApi;
private $searchApi;
private $streamsApi;
private $subscriptionsApi;
Expand Down Expand Up @@ -75,6 +77,7 @@ public function __construct(HelixGuzzleClient $helixGuzzleClient, string $client
$this->moderationApi = new ModerationApi($helixGuzzleClient, $requestGenerator);
$this->pollsApi = new PollsApi($helixGuzzleClient, $requestGenerator);
$this->predictionsApi = new PredictionsApi($helixGuzzleClient, $requestGenerator);
$this->scheduleApi = new ScheduleApi($helixGuzzleClient, $requestGenerator);
$this->searchApi = new SearchApi($helixGuzzleClient, $requestGenerator);
$this->streamsApi = new StreamsApi($helixGuzzleClient, $requestGenerator);
$this->subscriptionsApi = new SubscriptionsApi($helixGuzzleClient, $requestGenerator);
Expand Down Expand Up @@ -161,6 +164,11 @@ public function getPredictionsApi(): PredictionsApi
return $this->predictionsApi;
}

public function getScheduleApi(): ScheduleApi
{
return $this->scheduleApi;
}

public function getSearchApi(): SearchApi
{
return $this->searchApi;
Expand Down
14 changes: 11 additions & 3 deletions src/NewTwitchApi/RequestGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,16 @@

class RequestGenerator
{
public function generate(string $httpMethod, string $uriEndpoint, string $bearer, array $queryParamsMap = [], array $bodyParams = []): RequestInterface
public function generate(string $httpMethod, string $uriEndpoint, string $bearer = null, array $queryParamsMap = [], array $bodyParams = []): RequestInterface
{
$headers = [
'Accept' => 'application/json',
];

if ($bearer) {
$headers['Authorization'] = sprintf('Bearer %s', $bearer);
}

if (count($bodyParams) > 0) {
$request = new Request(
$httpMethod,
Expand All @@ -17,7 +25,7 @@ public function generate(string $httpMethod, string $uriEndpoint, string $bearer
$uriEndpoint,
$this->generateQueryParams($queryParamsMap)
),
['Authorization' => sprintf('Bearer %s', $bearer), 'Accept' => 'application/json'],
$headers,
$this->generateBodyParams($bodyParams)
);
} else {
Expand All @@ -28,7 +36,7 @@ public function generate(string $httpMethod, string $uriEndpoint, string $bearer
$uriEndpoint,
$this->generateQueryParams($queryParamsMap)
),
['Authorization' => sprintf('Bearer %s', $bearer)]
$headers
);
}

Expand Down
10 changes: 9 additions & 1 deletion src/NewTwitchApi/Resources/AbstractResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ protected function getApi(string $uriEndpoint, string $bearer, array $queryParam
return $this->sendToApi('GET', $uriEndpoint, $bearer, $queryParamsMap, $bodyParams);
}

/**
* @throws GuzzleException
*/
protected function getApiWithOptionalAuth(string $uriEndpoint, string $bearer = null, array $queryParamsMap = [], array $bodyParams = []): ResponseInterface
{
return $this->sendToApi('GET', $uriEndpoint, $bearer, $queryParamsMap, $bodyParams);
}

/**
* @throws GuzzleException
*/
Expand Down Expand Up @@ -60,7 +68,7 @@ protected function putApi(string $uriEndpoint, string $bearer, array $queryParam
return $this->sendToApi('PUT', $uriEndpoint, $bearer, $queryParamsMap, $bodyParams);
}

private function sendToApi(string $httpMethod, string $uriEndpoint, string $bearer, array $queryParamsMap = [], array $bodyParams = []): ResponseInterface
private function sendToApi(string $httpMethod, string $uriEndpoint, string $bearer = null, array $queryParamsMap = [], array $bodyParams = []): ResponseInterface
{
return $this->guzzleClient->send($this->requestGenerator->generate($httpMethod, $uriEndpoint, $bearer, $queryParamsMap, $bodyParams));
}
Expand Down
2 changes: 1 addition & 1 deletion src/NewTwitchApi/Resources/EventSubApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public function subscribeToChannelSubscriptionMessage(string $bearer, string $se
$secret,
$callback,
'channel.subscription.message',
'beta',
'1',
['broadcaster_user_id' => $twitchId],
);
}
Expand Down
145 changes: 145 additions & 0 deletions src/NewTwitchApi/Resources/ScheduleApi.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php

declare(strict_types=1);

namespace NewTwitchApi\Resources;

use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;

class ScheduleApi extends AbstractResource
{
/**
* @throws GuzzleException
* @link https://dev.twitch.tv/docs/api/reference/#get-channel-stream-schedule
*/
public function getChannelStreamSchedule(string $bearer, string $broadcasterId, array $ids = [], string $startTime = null, string $utcOffset = null, int $first = null, string $after = null): ResponseInterface
{
$queryParamsMap = [];

$queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];

foreach ($ids as $id) {
$queryParamsMap[] = ['key' => 'id', 'value' => $id];
}

if ($startTime) {
$queryParamsMap[] = ['key' => 'start_time', 'value' => $startTime];
}

if ($utcOffset) {
$queryParamsMap[] = ['key' => 'utc_offset', 'value' => $utcOffset];
}

if ($first) {
$queryParamsMap[] = ['key' => 'first', 'value' => $first];
}

if ($after) {
$queryParamsMap[] = ['key' => 'after', 'value' => $after];
}

return $this->getApi('schedule', $bearer, $queryParamsMap);
}

/**
* @throws GuzzleException
* @link https://dev.twitch.tv/docs/api/reference/#get-channel-icalendar
*/
public function getChanneliCalendar(string $bearer = null, string $broadcasterId): ResponseInterface
{
// This endpoint at the time of addition does not require any authorization, so the bearer is null.
// However, to prevent a breaking update in the future, it will remain the first function parameter.
// You may simple pass NULL to this to bypass authentication.

$queryParamsMap = [];

$queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];

return $this->getApiWithOptionalAuth('schedule/icalendar', $bearer, $queryParamsMap);
}

/**
* @throws GuzzleException
* @link https://dev.twitch.tv/docs/api/reference/#update-channel-stream-schedule
*/
public function updateChannelStreamSchedule(string $bearer, string $broadcasterId, bool $isVacationEnabled = null, $vacationStartTime = null, $vacationEndTime = null, $timezone = null): ResponseInterface
{
$queryParamsMap = [];

$queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];

if ($isVacationEnabled) {
$queryParamsMap[] = ['key' => 'is_vacation_enabled', 'value' => $isVacationEnabled];
}

if ($vacationStartTime) {
$queryParamsMap[] = ['key' => 'vacation_start_time', 'value' => $vacationStartTime];
}

if ($vacationEndTime) {
$queryParamsMap[] = ['key' => 'vacation_end_time', 'value' => $vacationEndTime];
}

if ($timezone) {
$queryParamsMap[] = ['key' => 'timezone', 'value' => $timezone];
}

return $this->patchApi('schedule/settings', $bearer, $queryParamsMap);
}

/**
* @throws GuzzleException
* @link https://dev.twitch.tv/docs/api/reference/#create-channel-stream-schedule-segment
*/
public function createChannelStreamScheduleSegment(string $bearer, string $broadcasterId, string $startTime, string $timezone, bool $isRecurring, array $additionalBodyParams = []): ResponseInterface
{
// $additionalBodyParams should be a standard key => value format, eg. ['duration' => '240'];
$queryParamsMap = $bodyParamsMap = [];

$queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];

$bodyParamsMap[] = ['key' => 'start_time', 'value' => $startTime];
$bodyParamsMap[] = ['key' => 'timezone', 'value' => $timezone];
$bodyParamsMap[] = ['key' => 'is_recurring', 'value' => $isRecurring];

foreach ($additionalBodyParams as $key => $value) {
$bodyParamsMap[] = ['key' => $key, 'value' => $value];
}

return $this->postApi('schedule/segment', $bearer, $queryParamsMap, $bodyParamsMap);
}

/**
* @throws GuzzleException
* @link https://dev.twitch.tv/docs/api/reference/#update-channel-stream-schedule-segment
*/
public function updateChannelStreamScheduleSegment(string $bearer, string $broadcasterId, string $segmentId, array $updateValues = []): ResponseInterface
{
// $updateValues should be a standard key => value format based on the values available on the documentation, eg. ['duration' => '240'];
$queryParamsMap = $bodyParamsMap = [];

$queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
$queryParamsMap[] = ['key' => 'id', 'value' => $segmentId];

foreach ($updateValues as $key => $value) {
$bodyParamsMap[] = ['key' => $key, 'value' => $value];
}

return $this->patchApi('schedule/segment', $bearer, $queryParamsMap, $bodyParamsMap);
}

/**
* @throws GuzzleException
* @link https://dev.twitch.tv/docs/api/reference/#delete-channel-stream-schedule-segment
*/
public function deleteChannelStreamScheduleSegment(string $bearer, string $broadcasterId, string $segmentId): ResponseInterface
{
$queryParamsMap = [];

$queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
$queryParamsMap[] = ['key' => 'id', 'value' => $segmentId];

return $this->deleteApi('schedule/segment', $bearer, $queryParamsMap);
}
}

0 comments on commit d4cab23

Please sign in to comment.