├── bin
├── git
│ └── hooks
│ │ └── pre-commit
└── new-api-cli-test-client.php
├── examples
├── README.md
└── users
│ └── get_user_example.md
├── src
├── NewTwitchApi.php
├── NewTwitchApi
│ ├── NewTwitchApi.php
│ └── HelixGuzzleClient.php
├── Auth
│ ├── AuthGuzzleClient.php
│ └── OauthApi.php
├── Resources
│ ├── GoalsApi.php
│ ├── AdsApi.php
│ ├── WebhooksApi.php
│ ├── WhispersApi.php
│ ├── HypeTrainApi.php
│ ├── RaidsApi.php
│ ├── CharityApi.php
│ ├── GamesApi.php
│ ├── TeamsApi.php
│ ├── SearchApi.php
│ ├── TagsApi.php
│ ├── SubscriptionsApi.php
│ ├── VideosApi.php
│ ├── PollsApi.php
│ ├── BitsApi.php
│ ├── PredictionsApi.php
│ ├── AnalyticsApi.php
│ ├── AbstractResource.php
│ ├── ClipsApi.php
│ ├── ChannelsApi.php
│ ├── EntitlementsApi.php
│ ├── StreamsApi.php
│ ├── ChannelPointsApi.php
│ ├── ScheduleApi.php
│ ├── UsersApi.php
│ └── ChatApi.php
├── HelixGuzzleClient.php
├── RequestGenerator.php
├── Webhooks
│ └── WebhooksSubscriptionApi.php
└── TwitchApi.php
├── .gitignore
├── Makefile
├── .php-cs-fixer.dist.php
├── phpunit.xml.dist
├── spec
└── TwitchApi
│ ├── Auth
│ ├── AuthGuzzleClientSpec.php
│ └── OauthApiSpec.php
│ ├── Resources
│ ├── GoalsApiSpec.php
│ ├── AdsApiSpec.php
│ ├── WhispersApiSpec.php
│ ├── RaidsApiSpec.php
│ ├── HypeTrainApiSpec.php
│ ├── CharityApiSpec.php
│ ├── WebhooksApiSpec.php
│ ├── SearchApiSpec.php
│ ├── TeamsApiSpec.php
│ ├── SubscriptionsApiSpec.php
│ ├── GamesApiSpec.php
│ ├── TagsApiSpec.php
│ ├── BitsApiSpec.php
│ ├── PollsApiSpec.php
│ ├── PredictionsApiSpec.php
│ ├── ClipsApiSpec.php
│ ├── ChannelsApiSpec.php
│ ├── AnalyticsApiSpec.php
│ ├── VideosApiSpec.php
│ ├── ScheduleApiSpec.php
│ ├── EntitlementsApiSpec.php
│ ├── ChatApiSpec.php
│ └── UsersApiSpec.php
│ ├── HelixGuzzleClientSpec.php
│ └── TwitchApiSpec.php
├── LICENSE
├── composer.json
├── .github
└── workflows
│ └── test.yaml
├── test
└── TwitchApi
│ └── Resources
│ └── UsersTest.php
└── README.md
/bin/git/hooks/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | ./vendor/bin/php-cs-fixer fix
3 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | ## Examples
2 |
3 | #### Users
4 | - [Get User](users/get_user_example.md)
5 |
6 | More to come...
7 |
--------------------------------------------------------------------------------
/src/NewTwitchApi.php:
--------------------------------------------------------------------------------
1 | run();
10 | } catch (InvalidArgumentException $e) {
11 | echo $e->getMessage();
12 | }
13 |
--------------------------------------------------------------------------------
/src/Auth/AuthGuzzleClient.php:
--------------------------------------------------------------------------------
1 | self::BASE_URI,
17 | ]);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.php-cs-fixer.dist.php:
--------------------------------------------------------------------------------
1 | in('src/')
5 | ->in('test/')
6 | ;
7 |
8 | $config = new PhpCsFixer\Config();
9 |
10 | return $config->setRules([
11 | '@PSR2' => true,
12 | '@Symfony' => true,
13 | 'phpdoc_annotation_without_dot' => false,
14 | 'phpdoc_no_alias_tag' => false,
15 | 'phpdoc_separation' => false,
16 | 'yoda_style' => false,
17 | ])
18 | ->setFinder($finder)
19 | ;
20 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 | test
7 |
8 |
9 |
10 |
11 | src
12 |
13 | src/
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/examples/users/get_user_example.md:
--------------------------------------------------------------------------------
1 | # Get User
2 |
3 | ## Supported API Versions
4 |
5 | v3 & v5
6 |
7 | ### v3 Example
8 |
9 | ```php
10 | $options = [
11 | 'client_id' => 'YOUR-CLIENT-ID',
12 | 'api_version' => 3,
13 | ];
14 |
15 | $twitchApi = new \TwitchApi\TwitchApi($options);
16 | $user = $twitchApi->getUser('summit1g');
17 | ```
18 |
19 | ### v5 Example
20 |
21 | ```php
22 | $options = [
23 | 'client_id' => 'YOUR-CLIENT-ID',
24 | ];
25 |
26 | $twitchApi = new \TwitchApi\TwitchApi($options);
27 | $user = $twitchApi->getUser(26490481);
28 | ```
29 |
--------------------------------------------------------------------------------
/src/Resources/GoalsApi.php:
--------------------------------------------------------------------------------
1 | 'broadcaster_id', 'value' => $broadcasterId];
20 |
21 | return $this->getApi('goals', $bearer, $queryParamsMap);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Resources/AdsApi.php:
--------------------------------------------------------------------------------
1 | 'broadcaster_id', 'value' => $broadcasterId];
21 | $bodyParamsMap[] = ['key' => 'length', 'value' => $length];
22 |
23 | return $this->postApi('channels/commercial', $bearer, [], $bodyParamsMap);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Resources/WebhooksApi.php:
--------------------------------------------------------------------------------
1 | 'first', 'value' => $first];
21 | }
22 | if ($after) {
23 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
24 | }
25 |
26 | return $this->getApi('webhooks/subscriptions', $bearer, $queryParamsMap);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Resources/WhispersApi.php:
--------------------------------------------------------------------------------
1 | 'from_user_id', 'value' => $fromUserId];
21 | $queryParamsMap[] = ['key' => 'to_user_id', 'value' => $toUserId];
22 |
23 | $bodyParamsMap[] = ['key' => 'message', 'value' => $message];
24 |
25 | return $this->postApi('whispers', $bearer, $queryParamsMap, $bodyParamsMap);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Auth/AuthGuzzleClientSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedThrough('getClient');
13 | $this->shouldHaveType('\GuzzleHttp\Client');
14 |
15 | /** @var Uri $uri */
16 | $uri = $this->getConfig('base_uri');
17 | $uri->getScheme()->shouldBe('https');
18 | $uri->getHost()->shouldBe('id.twitch.tv');
19 | $uri->getPath()->shouldBe('/oauth2/');
20 | }
21 |
22 | function it_should_have_passed_in_config_params_instead_of_defaults()
23 | {
24 | $this->beConstructedThrough('getClient', [['base_uri' => 'https://different.url']]);
25 | $this->shouldHaveType('\GuzzleHttp\Client');
26 | $this->getConfig('base_uri')->getHost()->shouldBe('different.url');
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/GoalsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_goals_by_broadcaster_id(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'goals', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
22 | $this->getGoals('TEST_TOKEN', '123')->shouldBe($response);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/AdsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_start_commercial(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('POST', 'channels/commercial', 'TEST_TOKEN', [], [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'length', 'value' => 30]])->willReturn($request);
22 | $this->startCommercial('TEST_TOKEN', '123', 30)->shouldBe($response);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Resources/HypeTrainApi.php:
--------------------------------------------------------------------------------
1 | 'broadcaster_id', 'value' => $broadcasterId];
21 |
22 | if ($first) {
23 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
24 | }
25 |
26 | if ($cursor) {
27 | $queryParamsMap[] = ['key' => 'cursor', 'value' => $cursor];
28 | }
29 |
30 | return $this->getApi('hypetrain/events', $bearer, $queryParamsMap);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/WhispersApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_send_a_whisper(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('POST', 'whispers', 'TEST_TOKEN', [['key' => 'from_user_id', 'value' => '123'], ['key' => 'to_user_id', 'value' => '456']], [['key' => 'message', 'value' => 'abc']])->willReturn($request);
22 | $this->sendWhisper('TEST_TOKEN', '123', '456', 'abc')->shouldBe($response);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017-2018 Nicholas Law
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/HelixGuzzleClient.php:
--------------------------------------------------------------------------------
1 | $clientId,
22 | 'Content-Type' => 'application/json',
23 | ];
24 |
25 | $client_config = [
26 | 'base_uri' => $baseUri,
27 | 'headers' => $headers,
28 | ];
29 |
30 | if (isset($config['handler'])) {
31 | $client_config = [];
32 | }
33 |
34 | $client_config = array_merge($client_config, $config);
35 |
36 | $this->client = new Client($client_config);
37 | }
38 |
39 | public function getConfig($option = null)
40 | {
41 | return $this->client->getConfig($option);
42 | }
43 |
44 | public function send($request)
45 | {
46 | return $this->client->send($request);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nicklaw5/twitch-api-php",
3 | "type": "library",
4 | "description": "A Twitch API client for PHP.",
5 | "keywords": [
6 | "twitch",
7 | "twitch.tv",
8 | "twitch-tv",
9 | "twitch-api",
10 | "api"
11 | ],
12 | "homepage": "http://github.com/nicklaw5/twitch-api-php",
13 | "license": "MIT",
14 | "authors": [
15 | {
16 | "name": "Nicholas Law",
17 | "homepage": "https://github.com/nicklaw5"
18 | },
19 | {
20 | "name": "Brian Zwahr",
21 | "homepage": "https://github.com/echosa"
22 | },
23 | {
24 | "name": "Brandin Arsenault",
25 | "homepage": "https://github.com/brandinarsenault"
26 | }
27 | ],
28 | "require": {
29 | "php": ">=7.4.0",
30 | "ext-json": "*",
31 | "guzzlehttp/guzzle": "~6.0|~7.0"
32 | },
33 | "require-dev": {
34 | "friendsofphp/php-cs-fixer": "^3.10",
35 | "phpspec/phpspec": "^7.2",
36 | "phpunit/phpunit": "^9.5"
37 | },
38 | "autoload": {
39 | "psr-4": {
40 | "TwitchApi\\": "src/",
41 | "TwitchApi\\Tests\\": "test/TwitchApi",
42 | "NewTwitchApi\\": "src/NewTwitchApi"
43 | }
44 | },
45 | "autoload-dev": {
46 | "psr-4": {
47 | "Tests\\": "test/"
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Resources/RaidsApi.php:
--------------------------------------------------------------------------------
1 | 'from_broadcaster_id', 'value' => $fromBroadcasterId];
21 | $queryParamsMap[] = ['key' => 'to_broadcaster_id', 'value' => $toBroadcasterId];
22 |
23 | return $this->postApi('raids', $bearer, $queryParamsMap);
24 | }
25 |
26 | /**
27 | * @throws GuzzleException
28 | * @link https://dev.twitch.tv/docs/api/reference#cancel-a-raid
29 | */
30 | public function cancelRaid(string $bearer, string $toBroadcasterId): ResponseInterface
31 | {
32 | $queryParamsMap = [];
33 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $toBroadcasterId];
34 |
35 | return $this->deleteApi('raids', $bearer, $queryParamsMap);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/.github/workflows/test.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Run tests
3 |
4 | on:
5 | pull_request:
6 | branches:
7 | - master
8 | push:
9 | branches:
10 | - master
11 |
12 | jobs:
13 | test:
14 | runs-on: ubuntu-latest
15 |
16 | strategy:
17 | matrix:
18 | php: ['7.4', '8.0', '8.1']
19 |
20 | steps:
21 | - uses: actions/checkout@v2
22 |
23 | - name: Setup PHP
24 | uses: shivammathur/setup-php@v2
25 | with:
26 | php-version: "${{ matrix.php }}"
27 |
28 | # Cache Composer dependencies, based on the example at https://github.com/actions/cache/blob/main/examples.md#php---composer
29 | - name: Get Composer Cache Directory
30 | id: composer-cache
31 | run: echo "::set-output name=dir::$(composer config cache-files-dir)"
32 |
33 | - name: Cache Composer dependencies
34 | uses: actions/cache@v2
35 | with:
36 | path: ${{ steps.composer-cache.outputs.dir }}
37 | key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
38 | restore-keys: |
39 | php${{ matrix.php }}-composer-
40 |
41 | - name: Install dependencies using Composer
42 | run: composer install --prefer-source --no-interaction
43 |
44 | - name: Run tests
45 | run: make test
46 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/RaidsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_start_a_raid(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('POST', 'raids', 'TEST_TOKEN', [['key' => 'from_broadcaster_id', 'value' => '123'], ['key' => 'to_broadcaster_id', 'value' => '456']], [])->willReturn($request);
22 | $this->startRaid('TEST_TOKEN', '123', '456')->shouldBe($response);
23 | }
24 |
25 | function it_should_cancel_a_raid(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('DELETE', 'raids', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
28 | $this->cancelRaid('TEST_TOKEN', '123')->shouldBe($response);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/HypeTrainApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_hype_train_events(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'hypetrain/events', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
22 | $this->getHypeTrainEvents('TEST_TOKEN', '123')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_hype_train_events_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'hypetrain/events', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'first', 'value' => 100], ['key' => 'cursor', 'value' => 'abc']], [])->willReturn($request);
28 | $this->getHypeTrainEvents('TEST_TOKEN', '123', 100, 'abc')->shouldBe($response);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Resources/CharityApi.php:
--------------------------------------------------------------------------------
1 | 'broadcaster_id', 'value' => $broadcasterId];
20 |
21 | return $this->getApi('charity/campaigns', $bearer, $queryParamsMap);
22 | }
23 |
24 | /**
25 | * @throws GuzzleException
26 | * @link https://dev.twitch.tv/docs/api/reference#get-charity-campaign-donations
27 | */
28 | public function getCharityCampaignDonations(string $bearer, string $broadcasterId, int $first = null, string $after = null): ResponseInterface
29 | {
30 | $queryParamsMap = [];
31 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
32 |
33 | if ($first) {
34 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
35 | }
36 |
37 | if ($after) {
38 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
39 | }
40 |
41 | return $this->getApi('charity/donations', $bearer, $queryParamsMap);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/spec/TwitchApi/HelixGuzzleClientSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith('TEST_CLIENT_ID');
13 | }
14 |
15 | function it_should_have_correct_base_uri()
16 | {
17 | $this->shouldHaveType('\TwitchApi\HelixGuzzleClient');
18 |
19 | /** @var Uri $uri */
20 | $uri = $this->getConfig('base_uri');
21 | $uri->getScheme()->shouldBe('https');
22 | $uri->getHost()->shouldBe('api.twitch.tv');
23 | $uri->getPath()->shouldBe('/helix/');
24 | }
25 |
26 | function it_should_have_client_id_header()
27 | {
28 | $this->shouldHaveType('\TwitchApi\HelixGuzzleClient');
29 | $this->getConfig('headers')->shouldHaveKeyWithValue('Client-ID', 'TEST_CLIENT_ID');
30 | }
31 |
32 | function it_should_have_json_content_type_header()
33 | {
34 |
35 | $this->shouldHaveType('\TwitchApi\HelixGuzzleClient');
36 | $this->getConfig('headers')->shouldHaveKeyWithValue('Content-Type', 'application/json');
37 | }
38 |
39 | function it_should_have_passed_in_config_params_instead_of_defaults()
40 | {
41 | $this->beConstructedWith('TEST_CLIENT_ID', ['base_uri' => 'https://different.url']);
42 | $this->shouldHaveType('\TwitchApi\HelixGuzzleClient');
43 | $this->getConfig('base_uri')->getHost()->shouldBe('different.url');
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Resources/GamesApi.php:
--------------------------------------------------------------------------------
1 | 'id', 'value' => $id];
21 | }
22 | foreach ($names as $name) {
23 | $queryParamsMap[] = ['key' => 'name', 'value' => $name];
24 | }
25 |
26 | return $this->getApi('games', $bearer, $queryParamsMap);
27 | }
28 |
29 | /**
30 | * @throws GuzzleException
31 | * @link https://dev.twitch.tv/docs/api/reference/#get-top-games
32 | */
33 | public function getTopGames(string $bearer, int $first = null, string $before = null, string $after = null): ResponseInterface
34 | {
35 | $queryParamsMap = [];
36 |
37 | if ($first) {
38 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
39 | }
40 |
41 | if ($before) {
42 | $queryParamsMap[] = ['key' => 'before', 'value' => $before];
43 | }
44 |
45 | if ($after) {
46 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
47 | }
48 |
49 | return $this->getApi('games/top', $bearer, $queryParamsMap);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Resources/TeamsApi.php:
--------------------------------------------------------------------------------
1 | 'broadcaster_id', 'value' => $broadcasterId];
21 |
22 | return $this->getApi('teams/channel', $bearer, $queryParamsMap);
23 | }
24 |
25 | /**
26 | * @throws GuzzleException
27 | * @link https://dev.twitch.tv/docs/api/reference#get-teams
28 | */
29 | public function getTeams(string $bearer, string $name = null, string $id = null): ResponseInterface
30 | {
31 | $queryParamsMap = [];
32 |
33 | if ($name) {
34 | $queryParamsMap[] = ['key' => 'name', 'value' => $name];
35 | }
36 |
37 | if ($id) {
38 | $queryParamsMap[] = ['key' => 'id', 'value' => $id];
39 | }
40 |
41 | return $this->getApi('teams', $bearer, $queryParamsMap);
42 | }
43 |
44 | /**
45 | * @throws GuzzleException
46 | */
47 | public function getTeamsByName(string $bearer, string $name): ResponseInterface
48 | {
49 | return $this->getTeams($bearer, $name, null);
50 | }
51 |
52 | /**
53 | * @throws GuzzleException
54 | */
55 | public function getTeamsById(string $bearer, string $id): ResponseInterface
56 | {
57 | return $this->getTeams($bearer, null, $id);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Resources/SearchApi.php:
--------------------------------------------------------------------------------
1 | 'query', 'value' => $query];
21 |
22 | if ($first) {
23 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
24 | }
25 |
26 | if ($after) {
27 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
28 | }
29 |
30 | return $this->getApi('search/categories', $bearer, $queryParamsMap);
31 | }
32 |
33 | /**
34 | * @throws GuzzleException
35 | * @link https://dev.twitch.tv/docs/api/reference#search-channels
36 | */
37 | public function searchChannels(string $bearer, string $query, $liveOnly = null, string $first = null, string $after = null): ResponseInterface
38 | {
39 | $queryParamsMap = [];
40 |
41 | $queryParamsMap[] = ['key' => 'query', 'value' => $query];
42 |
43 | if ($liveOnly) {
44 | $queryParamsMap[] = ['key' => 'live_only', 'value' => $liveOnly];
45 | }
46 |
47 | if ($first) {
48 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
49 | }
50 |
51 | if ($after) {
52 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
53 | }
54 |
55 | return $this->getApi('search/channels', $bearer, $queryParamsMap);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/CharityApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_charity_campaigns(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'charity/campaigns', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
22 | $this->getCharityCampaign('TEST_TOKEN', '123')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_charity_campaign_donations(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'charity/donations', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
28 | $this->getCharityCampaignDonations('TEST_TOKEN', '123')->shouldBe($response);
29 | }
30 |
31 | function it_should_get_charity_campaign_donations_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'charity/donations', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'first', 'value' => 100], ['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
34 | $this->getCharityCampaignDonations('TEST_TOKEN', '123', 100, 'abc')->shouldBe($response);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Resources/TagsApi.php:
--------------------------------------------------------------------------------
1 | 'tag_id', 'value' => $tagId];
22 | }
23 | if ($first) {
24 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
25 | }
26 |
27 | if ($after) {
28 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
29 | }
30 |
31 | return $this->getApi('tags/streams', $bearer, $queryParamsMap);
32 | }
33 |
34 | /**
35 | * @throws GuzzleException
36 | * @link https://dev.twitch.tv/docs/api/reference#get-stream-tags
37 | */
38 | public function getStreamTags(string $bearer, string $broadcasterId): ResponseInterface
39 | {
40 | $queryParamsMap = [];
41 |
42 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
43 |
44 | return $this->getApi('streams/tags', $bearer, $queryParamsMap);
45 | }
46 |
47 | /**
48 | * @throws GuzzleException
49 | * @link https://dev.twitch.tv/docs/api/reference#replace-stream-tags
50 | */
51 | public function replaceStreamTags(string $bearer, string $broadcasterId, $tags = []): ResponseInterface
52 | {
53 | $queryParamsMap = $bodyParamsMap = [];
54 |
55 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
56 |
57 | if (count($tags) > 0) {
58 | $bodyParamsMap[] = ['key' => 'tag_ids', 'value' => $tags];
59 | }
60 |
61 | return $this->putApi('streams/tags', $bearer, $queryParamsMap, $bodyParamsMap);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/WebhooksApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_webhooks_subscriptions(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'webhooks/subscriptions', 'TEST_TOKEN', [], [])->willReturn($request);
22 | $this->getWebhookSubscriptions('TEST_TOKEN')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_webhooks_subscriptions_with_first(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'webhooks/subscriptions', 'TEST_TOKEN', [['key' => 'first', 'value' => 100]], [])->willReturn($request);
28 | $this->getWebhookSubscriptions('TEST_TOKEN', 100)->shouldBe($response);
29 | }
30 |
31 | function it_should_get_webhooks_subscriptions_with_after(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'webhooks/subscriptions', 'TEST_TOKEN', [['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
34 | $this->getWebhookSubscriptions('TEST_TOKEN', null, 'abc')->shouldBe($response);
35 | }
36 |
37 | function it_should_get_webhooks_subscriptions_with_everything(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'webhooks/subscriptions', 'TEST_TOKEN', [['key' => 'first', 'value' => 100], ['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
40 | $this->getWebhookSubscriptions('TEST_TOKEN', 100, 'abc')->shouldBe($response);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Resources/SubscriptionsApi.php:
--------------------------------------------------------------------------------
1 | 'broadcaster_id', 'value' => $broadcasterId];
21 |
22 | if ($first) {
23 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
24 | }
25 |
26 | if ($after) {
27 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
28 | }
29 |
30 | return $this->getApi('subscriptions', $bearer, $queryParamsMap);
31 | }
32 |
33 | /**
34 | * @throws GuzzleException
35 | * @link https://dev.twitch.tv/docs/api/reference/#get-broadcaster-subscriptions
36 | */
37 | public function getBroadcasterSubscribers(string $bearer, string $broadcasterId, array $ids = []): ResponseInterface
38 | {
39 | $queryParamsMap = [];
40 |
41 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
42 |
43 | foreach ($ids as $id) {
44 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $id];
45 | }
46 |
47 | return $this->getApi('subscriptions', $bearer, $queryParamsMap);
48 | }
49 |
50 | /**
51 | * @throws GuzzleException
52 | * @link https://dev.twitch.tv/docs/api/reference#check-user-subscription
53 | */
54 | public function checkUserSubscription(string $bearer, string $broadcasterId, string $userId): ResponseInterface
55 | {
56 | $queryParamsMap = [];
57 |
58 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
59 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
60 |
61 | return $this->getApi('subscriptions/user', $bearer, $queryParamsMap);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/SearchApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_search_categories(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'search/categories', 'TEST_TOKEN', [['key' => 'query', 'value' => 'test']], [])->willReturn($request);
22 | $this->searchCategories('TEST_TOKEN', 'test')->shouldBe($response);
23 | }
24 |
25 | function it_should_search_categories_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'search/categories', 'TEST_TOKEN', [['key' => 'query', 'value' => 'test'], ['key' => 'first', 'value' => 100], ['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
28 | $this->searchCategories('TEST_TOKEN', 'test', 100, 'abc')->shouldBe($response);
29 | }
30 |
31 | function it_should_search_channels(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'search/channels', 'TEST_TOKEN', [['key' => 'query', 'value' => 'test']], [])->willReturn($request);
34 | $this->searchChannels('TEST_TOKEN', 'test')->shouldBe($response);
35 | }
36 |
37 | function it_should_search_channels_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'search/channels', 'TEST_TOKEN', [['key' => 'query', 'value' => 'test'], ['key' => 'live_only', 'value' => true], ['key' => 'first', 'value' => 100], ['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
40 | $this->searchChannels('TEST_TOKEN', 'test', true, 100, 'abc')->shouldBe($response);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Resources/VideosApi.php:
--------------------------------------------------------------------------------
1 | 'id', 'value' => $id];
22 | }
23 |
24 | if ($userId) {
25 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
26 | }
27 |
28 | if ($gameId) {
29 | $queryParamsMap[] = ['key' => 'game_id', 'value' => $gameId];
30 | }
31 |
32 | if ($first) {
33 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
34 | }
35 |
36 | if ($before) {
37 | $queryParamsMap[] = ['key' => 'before', 'value' => $before];
38 | }
39 |
40 | if ($after) {
41 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
42 | }
43 |
44 | if ($language) {
45 | $queryParamsMap[] = ['key' => 'language', 'value' => $language];
46 | }
47 |
48 | if ($period) {
49 | $queryParamsMap[] = ['key' => 'period', 'value' => $period];
50 | }
51 |
52 | if ($sort) {
53 | $queryParamsMap[] = ['key' => 'sort', 'value' => $sort];
54 | }
55 |
56 | if ($type) {
57 | $queryParamsMap[] = ['key' => 'type', 'value' => $type];
58 | }
59 |
60 | return $this->getApi('videos', $bearer, $queryParamsMap);
61 | }
62 |
63 | /**
64 | * @throws GuzzleException
65 | * @link https://dev.twitch.tv/docs/api/reference#delete-videos
66 | */
67 | public function deleteVideos(string $bearer, array $ids = []): ResponseInterface
68 | {
69 | $queryParamsMap = [];
70 |
71 | foreach ($ids as $id) {
72 | $queryParamsMap[] = ['key' => 'id', 'value' => $id];
73 | }
74 |
75 | return $this->deleteApi('videos', $bearer, $queryParamsMap);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/Resources/PollsApi.php:
--------------------------------------------------------------------------------
1 | 'broadcaster_id', 'value' => $broadcasterId];
21 |
22 | foreach ($ids as $id) {
23 | $queryParamsMap[] = ['key' => 'id', 'value' => $id];
24 | }
25 |
26 | if ($after) {
27 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
28 | }
29 |
30 | if ($first) {
31 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
32 | }
33 |
34 | return $this->getApi('polls', $bearer, $queryParamsMap);
35 | }
36 |
37 | /**
38 | * @throws GuzzleException
39 | * @link https://dev.twitch.tv/docs/api/reference#create-poll
40 | */
41 | public function createPoll(string $bearer, string $broadcasterId, string $title, array $choices, int $duration, $optionalBodyParams = []): ResponseInterface
42 | {
43 | $bodyParamsMap = [];
44 |
45 | $bodyParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
46 | $bodyParamsMap[] = ['key' => 'title', 'value' => $title];
47 | $bodyParamsMap[] = ['key' => 'choices', 'value' => $choices];
48 | $bodyParamsMap[] = ['key' => 'duration', 'value' => $duration];
49 |
50 | foreach ($optionalBodyParams as $key => $value) {
51 | $bodyParamsMap[] = ['key' => $key, 'value' => $value];
52 | }
53 |
54 | return $this->postApi('polls', $bearer, [], $bodyParamsMap);
55 | }
56 |
57 | /**
58 | * @throws GuzzleException
59 | * @link https://dev.twitch.tv/docs/api/reference#end-poll
60 | */
61 | public function endPoll(string $bearer, string $broadcasterId, string $pollId, string $status): ResponseInterface
62 | {
63 | $bodyParamsMap = [];
64 |
65 | $bodyParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
66 | $bodyParamsMap[] = ['key' => 'id', 'value' => $pollId];
67 | $bodyParamsMap[] = ['key' => 'status', 'value' => $status];
68 |
69 | return $this->patchApi('polls', $bearer, [], $bodyParamsMap);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/Resources/BitsApi.php:
--------------------------------------------------------------------------------
1 | 'broadcaster_id', 'value' => $broadcasterId];
22 | }
23 |
24 | return $this->getApi('bits/cheermotes', $bearer, $queryParamsMap);
25 | }
26 |
27 | /**
28 | * @throws GuzzleException
29 | * @link https://dev.twitch.tv/docs/api/reference#get-bits-leaderboard
30 | */
31 | public function getBitsLeaderboard(string $bearer, int $count = null, string $period = null, string $startedAt = null, string $userId = null): ResponseInterface
32 | {
33 | $queryParamsMap = [];
34 |
35 | if ($count) {
36 | $queryParamsMap[] = ['key' => 'count', 'value' => $count];
37 | }
38 |
39 | if ($period) {
40 | $queryParamsMap[] = ['key' => 'period', 'value' => $period];
41 | }
42 |
43 | if ($startedAt) {
44 | $queryParamsMap[] = ['key' => 'started_at', 'value' => $startedAt];
45 | }
46 |
47 | if ($userId) {
48 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
49 | }
50 |
51 | return $this->getApi('bits/leaderboard', $bearer, $queryParamsMap);
52 | }
53 |
54 | /**
55 | * @throws GuzzleException
56 | * @link https://dev.twitch.tv/docs/api/reference#get-extension-transactions
57 | */
58 | public function getExtensionTransactions(string $bearer, string $extensionId, array $transactionIds = [], int $first = null, string $after = null): ResponseInterface
59 | {
60 | $queryParamsMap = [];
61 |
62 | $queryParamsMap[] = ['key' => 'extension_id', 'value' => $extensionId];
63 |
64 | foreach ($transactionIds as $transactionId) {
65 | $queryParamsMap[] = ['key' => 'id', 'value' => $transactionId];
66 | }
67 |
68 | if ($first) {
69 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
70 | }
71 |
72 | if ($after) {
73 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
74 | }
75 |
76 | return $this->getApi('extensions/transactions', $bearer, $queryParamsMap);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/TeamsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_channel_teams(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'teams/channel', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
22 | $this->getChannelTeams('TEST_TOKEN', '123')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_teams(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'teams', 'TEST_TOKEN', [], [])->willReturn($request);
28 | $this->getTeams('TEST_TOKEN')->shouldBe($response);
29 | }
30 |
31 | function it_should_get_teams_by_name(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'teams', 'TEST_TOKEN', [['key' => 'name', 'value' => 'abc']], [])->willReturn($request);
34 | $this->getTeams('TEST_TOKEN', 'abc')->shouldBe($response);
35 | }
36 |
37 | function it_should_get_teams_by_name_with_helper_function(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'teams', 'TEST_TOKEN', [['key' => 'name', 'value' => 'abc']], [])->willReturn($request);
40 | $this->getTeamsByName('TEST_TOKEN', 'abc')->shouldBe($response);
41 | }
42 |
43 | function it_should_get_teams_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('GET', 'teams', 'TEST_TOKEN', [['key' => 'id', 'value' => '123']], [])->willReturn($request);
46 | $this->getTeams('TEST_TOKEN', null, '123')->shouldBe($response);
47 | }
48 |
49 | function it_should_get_teams_by_id_with_helper_function(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('GET', 'teams', 'TEST_TOKEN', [['key' => 'id', 'value' => '123']], [])->willReturn($request);
52 | $this->getTeamsById('TEST_TOKEN', '123')->shouldBe($response);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Resources/PredictionsApi.php:
--------------------------------------------------------------------------------
1 | 'broadcaster_id', 'value' => $broadcasterId];
21 |
22 | foreach ($ids as $id) {
23 | $queryParamsMap[] = ['key' => 'id', 'value' => $id];
24 | }
25 |
26 | if ($after) {
27 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
28 | }
29 |
30 | if ($first) {
31 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
32 | }
33 |
34 | return $this->getApi('predictions', $bearer, $queryParamsMap);
35 | }
36 |
37 | /**
38 | * @throws GuzzleException
39 | * @link https://dev.twitch.tv/docs/api/reference#create-prediction
40 | */
41 | public function createPrediction(string $bearer, string $broadcasterId, string $title, array $outcomes, int $predictionWindow): ResponseInterface
42 | {
43 | $bodyParamsMap = [];
44 |
45 | $bodyParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
46 | $bodyParamsMap[] = ['key' => 'title', 'value' => $title];
47 | $bodyParamsMap[] = ['key' => 'outcomes', 'value' => $outcomes];
48 | $bodyParamsMap[] = ['key' => 'prediction_window', 'value' => $predictionWindow];
49 |
50 | return $this->postApi('predictions', $bearer, [], $bodyParamsMap);
51 | }
52 |
53 | /**
54 | * @throws GuzzleException
55 | * @link https://dev.twitch.tv/docs/api/reference#end-prediction
56 | */
57 | public function endPrediction(string $bearer, string $broadcasterId, string $pollId, string $status, string $winningOutcomeId = null): ResponseInterface
58 | {
59 | $bodyParamsMap = [];
60 |
61 | $bodyParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
62 | $bodyParamsMap[] = ['key' => 'id', 'value' => $pollId];
63 | $bodyParamsMap[] = ['key' => 'status', 'value' => $status];
64 |
65 | if ($winningOutcomeId) {
66 | $bodyParamsMap[] = ['key' => 'winning_outcome_id', 'value' => $winningOutcomeId];
67 | }
68 |
69 | return $this->patchApi('predictions', $bearer, [], $bodyParamsMap);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/test/TwitchApi/Resources/UsersTest.php:
--------------------------------------------------------------------------------
1 | getHelixGuzzleClientWithMockUserResponse(), $this->getRequestGenerator());
20 | $response = $users->getUserById('TEST_APP_ACCESS_TOKEN', '44322889');
21 |
22 | $this->assertEquals(200, $response->getStatusCode());
23 | $contents = json_decode($response->getBody()->getContents());
24 | $this->assertEquals('dallas', $contents->data[0]->login);
25 | }
26 |
27 | public function testGetUserByUsernameShouldReturnSuccessfulResponseWithUserData(): void
28 | {
29 | $users = new UsersApi($this->getHelixGuzzleClientWithMockUserResponse(), $this->getRequestGenerator());
30 | $response = $users->getUserByUsername('TEST_APP_ACCESS_TOKEN', 'dallas');
31 |
32 | $this->assertEquals(200, $response->getStatusCode());
33 | $contents = json_decode($response->getBody()->getContents());
34 | $this->assertEquals(44322889, $contents->data[0]->id);
35 | }
36 |
37 | private function getHelixGuzzleClientWithMockUserResponse(): HelixGuzzleClient
38 | {
39 | // Example response from https://dev.twitch.tv/docs/api/reference/#get-users
40 | $getUserReponseJson = << $handler]);
62 | }
63 |
64 | private function getRequestGenerator(): RequestGenerator
65 | {
66 | return new RequestGenerator();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Resources/AnalyticsApi.php:
--------------------------------------------------------------------------------
1 | 'extension_id', 'value' => $extensionId];
22 | }
23 |
24 | if ($type) {
25 | $queryParamsMap[] = ['key' => 'type', 'value' => $type];
26 | }
27 |
28 | if ($first) {
29 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
30 | }
31 |
32 | if ($after) {
33 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
34 | }
35 |
36 | if ($startedAt) {
37 | $queryParamsMap[] = ['key' => 'started_at', 'value' => $startedAt];
38 | }
39 |
40 | if ($endedAt) {
41 | $queryParamsMap[] = ['key' => 'ended_at', 'value' => $endedAt];
42 | }
43 |
44 | return $this->getApi('analytics/extensions', $bearer, $queryParamsMap);
45 | }
46 |
47 | /**
48 | * @throws GuzzleException
49 | * @link https://dev.twitch.tv/docs/api/reference#get-game-analytics
50 | */
51 | public function getGameAnalytics(string $bearer, string $gameId = null, string $type = null, int $first = null, string $after = null, string $startedAt = null, string $endedAt = null): ResponseInterface
52 | {
53 | $queryParamsMap = [];
54 |
55 | if ($gameId) {
56 | $queryParamsMap[] = ['key' => 'game_id', 'value' => $gameId];
57 | }
58 |
59 | if ($type) {
60 | $queryParamsMap[] = ['key' => 'type', 'value' => $type];
61 | }
62 |
63 | if ($first) {
64 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
65 | }
66 |
67 | if ($after) {
68 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
69 | }
70 |
71 | if ($startedAt) {
72 | $queryParamsMap[] = ['key' => 'started_at', 'value' => $startedAt];
73 | }
74 |
75 | if ($endedAt) {
76 | $queryParamsMap[] = ['key' => 'ended_at', 'value' => $endedAt];
77 | }
78 |
79 | return $this->getApi('analytics/games', $bearer, $queryParamsMap);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/RequestGenerator.php:
--------------------------------------------------------------------------------
1 | 'application/json',
14 | ];
15 |
16 | if ($bearer) {
17 | $headers['Authorization'] = sprintf('Bearer %s', $bearer);
18 | }
19 |
20 | if (count($bodyParams) > 0) {
21 | $request = new Request(
22 | $httpMethod,
23 | sprintf(
24 | '%s%s',
25 | $uriEndpoint,
26 | $this->generateQueryParams($queryParamsMap)
27 | ),
28 | $headers,
29 | $this->generateBodyParams($bodyParams)
30 | );
31 | } else {
32 | $request = new Request(
33 | $httpMethod,
34 | sprintf(
35 | '%s%s',
36 | $uriEndpoint,
37 | $this->generateQueryParams($queryParamsMap)
38 | ),
39 | $headers
40 | );
41 | }
42 |
43 | return $request;
44 | }
45 |
46 | /**
47 | * $queryParamsMap should be a mapping of the param key expected in the API call URL,
48 | * and the value to be sent for that key.
49 | *
50 | * [['key' => 'param_key', 'value' => 42],['key' => 'other_key', 'value' => 'asdf']]
51 | * would result in
52 | * ?param_key=42&other_key=asdf
53 | */
54 | protected function generateQueryParams(array $queryParamsMap): string
55 | {
56 | $queryStringParams = '';
57 | foreach ($queryParamsMap as $paramMap) {
58 | if ($paramMap['value'] !== null) {
59 | if (is_bool($paramMap['value'])) {
60 | $paramMap['value'] = (int) $paramMap['value'];
61 | }
62 | $format = is_int($paramMap['value']) ? '%d' : '%s';
63 | $queryStringParams .= sprintf('&%s='.$format, $paramMap['key'], $paramMap['value']);
64 | }
65 | }
66 |
67 | return $queryStringParams ? '?'.substr($queryStringParams, 1) : '';
68 | }
69 |
70 | protected function generateBodyParams(array $bodyParamsMap): string
71 | {
72 | $bodyParams = [];
73 | foreach ($bodyParamsMap as $bodyParam) {
74 | if ($bodyParam['value'] !== null) {
75 | $bodyParams[$bodyParam['key']] = $bodyParam['value'];
76 | }
77 | }
78 |
79 | return json_encode($bodyParams);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/Resources/AbstractResource.php:
--------------------------------------------------------------------------------
1 | guzzleClient = $guzzleClient;
20 | $this->requestGenerator = $requestGenerator;
21 | }
22 |
23 | /**
24 | * @throws GuzzleException
25 | */
26 | protected function getApi(string $uriEndpoint, string $bearer, array $queryParamsMap = [], array $bodyParams = []): ResponseInterface
27 | {
28 | return $this->sendToApi('GET', $uriEndpoint, $bearer, $queryParamsMap, $bodyParams);
29 | }
30 |
31 | /**
32 | * @throws GuzzleException
33 | */
34 | protected function getApiWithOptionalAuth(string $uriEndpoint, string $bearer = null, array $queryParamsMap = [], array $bodyParams = []): ResponseInterface
35 | {
36 | return $this->sendToApi('GET', $uriEndpoint, $bearer, $queryParamsMap, $bodyParams);
37 | }
38 |
39 | /**
40 | * @throws GuzzleException
41 | */
42 | protected function deleteApi(string $uriEndpoint, string $bearer, array $queryParamsMap = [], array $bodyParams = []): ResponseInterface
43 | {
44 | return $this->sendToApi('DELETE', $uriEndpoint, $bearer, $queryParamsMap, $bodyParams);
45 | }
46 |
47 | /**
48 | * @throws GuzzleException
49 | */
50 | protected function patchApi(string $uriEndpoint, string $bearer, array $queryParamsMap = [], array $bodyParams = []): ResponseInterface
51 | {
52 | return $this->sendToApi('PATCH', $uriEndpoint, $bearer, $queryParamsMap, $bodyParams);
53 | }
54 |
55 | /**
56 | * @throws GuzzleException
57 | */
58 | protected function postApi(string $uriEndpoint, string $bearer, array $queryParamsMap = [], array $bodyParams = []): ResponseInterface
59 | {
60 | return $this->sendToApi('POST', $uriEndpoint, $bearer, $queryParamsMap, $bodyParams);
61 | }
62 |
63 | /**
64 | * @throws GuzzleException
65 | */
66 | protected function putApi(string $uriEndpoint, string $bearer, array $queryParamsMap = [], array $bodyParams = []): ResponseInterface
67 | {
68 | return $this->sendToApi('PUT', $uriEndpoint, $bearer, $queryParamsMap, $bodyParams);
69 | }
70 |
71 | private function sendToApi(string $httpMethod, string $uriEndpoint, string $bearer = null, array $queryParamsMap = [], array $bodyParams = []): ResponseInterface
72 | {
73 | return $this->guzzleClient->send($this->requestGenerator->generate($httpMethod, $uriEndpoint, $bearer, $queryParamsMap, $bodyParams));
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/SubscriptionsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_broadcaster_subscriptions(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'subscriptions', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
22 | $this->getBroadcasterSubscriptions('TEST_TOKEN', '123')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_broadcaster_subscriptions_with_all(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'subscriptions', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'first', 'value' => 100], ['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
28 | $this->getBroadcasterSubscriptions('TEST_TOKEN', '123', 100, 'abc')->shouldBe($response);
29 | }
30 |
31 | function it_should_get_broadcaster_subscribers(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'subscriptions', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
34 | $this->getBroadcasterSubscribers('TEST_TOKEN', '123')->shouldBe($response);
35 | }
36 |
37 | function it_should_get_broadcaster_subscribers_with_id(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'subscriptions', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'user_id', 'value' => '321']], [])->willReturn($request);
40 | $this->getBroadcasterSubscribers('TEST_TOKEN', '123', ['321'])->shouldBe($response);
41 | }
42 |
43 | function it_should_get_broadcaster_subscribers_with_ids(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('GET', 'subscriptions', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'user_id', 'value' => '321'], ['key' => 'user_id', 'value' => '456']], [])->willReturn($request);
46 | $this->getBroadcasterSubscribers('TEST_TOKEN', '123', ['321', '456'])->shouldBe($response);
47 | }
48 |
49 | function it_should_check_user_subscriptions(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('GET', 'subscriptions/user', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'user_id', 'value' => '456']], [])->willReturn($request);
52 | $this->checkUserSubscription('TEST_TOKEN', '123', '456')->shouldBe($response);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/GamesApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_games_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'games', 'TEST_TOKEN', [['key' => 'id', 'value' => '123']], [])->willReturn($request);
22 | $this->getGames('TEST_TOKEN', ['123'])->shouldBe($response);
23 | }
24 |
25 | function it_should_get_games_by_ids(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'games', 'TEST_TOKEN', [['key' => 'id', 'value' => '123'], ['key' => 'id', 'value' => '456']], [])->willReturn($request);
28 | $this->getGames('TEST_TOKEN', ['123', '456'])->shouldBe($response);
29 | }
30 |
31 | function it_should_get_games_by_name(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'games', 'TEST_TOKEN', [['key' => 'name', 'value' => 'abc']], [])->willReturn($request);
34 | $this->getGames('TEST_TOKEN', [], ['abc'])->shouldBe($response);
35 | }
36 |
37 | function it_should_get_games_by_names(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'games', 'TEST_TOKEN', [['key' => 'name', 'value' => 'abc'], ['key' => 'name', 'value' => 'def']], [])->willReturn($request);
40 | $this->getGames('TEST_TOKEN', [], ['abc', 'def'])->shouldBe($response);
41 | }
42 |
43 | function it_should_get_games_by_ids_and_names(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('GET', 'games', 'TEST_TOKEN', [['key' => 'id', 'value' => '123'], ['key' => 'id', 'value' => '456'], ['key' => 'name', 'value' => 'abc'], ['key' => 'name', 'value' => 'def']], [])->willReturn($request);
46 | $this->getGames('TEST_TOKEN', ['123', '456'], ['abc', 'def'])->shouldBe($response);
47 | }
48 |
49 | function it_should_get_top_games(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('GET', 'games/top', 'TEST_TOKEN', [], [])->willReturn($request);
52 | $this->getTopGames('TEST_TOKEN')->shouldBe($response);
53 | }
54 |
55 | function it_should_get_top_games_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $requestGenerator->generate('GET', 'games/top', 'TEST_TOKEN', [['key' => 'first', 'value' => 100], ['key' => 'before', 'value' => 'abc'], ['key' => 'after', 'value' => 'def']], [])->willReturn($request);
58 | $this->getTopGames('TEST_TOKEN', 100, 'abc', 'def')->shouldBe($response);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Resources/ClipsApi.php:
--------------------------------------------------------------------------------
1 | getClips($bearer, $broadcasterId, null, null, $first, $before, $after, $startedAt, $endedAt);
18 | }
19 |
20 | /**
21 | * @throws GuzzleException
22 | */
23 | public function getClipsByGameId(string $bearer, string $gameId, int $first = null, string $before = null, string $after = null, string $startedAt = null, string $endedAt = null): ResponseInterface
24 | {
25 | return $this->getClips($bearer, null, $gameId, null, $first, $before, $after, $startedAt, $endedAt);
26 | }
27 |
28 | /**
29 | * @throws GuzzleException
30 | */
31 | public function getClipsByIds(string $bearer, string $clipIds, string $startedAt = null, string $endedAt = null): ResponseInterface
32 | {
33 | return $this->getClips($bearer, null, null, $clipIds, null, null, null, $startedAt, $endedAt);
34 | }
35 |
36 | /**
37 | * @throws GuzzleException
38 | * @link https://dev.twitch.tv/docs/api/reference#get-clips
39 | */
40 | public function getClips(string $bearer, string $broadcasterId = null, string $gameId = null, string $clipIds = null, int $first = null, string $before = null, string $after = null, string $startedAt = null, string $endedAt = null): ResponseInterface
41 | {
42 | $queryParamsMap = [];
43 | if ($broadcasterId) {
44 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
45 | }
46 | if ($gameId) {
47 | $queryParamsMap[] = ['key' => 'game_id', 'value' => $gameId];
48 | }
49 | if ($clipIds) {
50 | $queryParamsMap[] = ['key' => 'id', 'value' => $clipIds];
51 | }
52 | if ($first) {
53 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
54 | }
55 | if ($before) {
56 | $queryParamsMap[] = ['key' => 'before', 'value' => $before];
57 | }
58 | if ($after) {
59 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
60 | }
61 | if ($startedAt) {
62 | $queryParamsMap[] = ['key' => 'started_at', 'value' => $startedAt];
63 | }
64 | if ($endedAt) {
65 | $queryParamsMap[] = ['key' => 'ended_at', 'value' => $endedAt];
66 | }
67 |
68 | return $this->getApi('clips', $bearer, $queryParamsMap);
69 | }
70 |
71 | /**
72 | * @throws GuzzleException
73 | * @link https://dev.twitch.tv/docs/api/reference#create-clip
74 | */
75 | public function createClip(string $bearer, string $broadcasterId, bool $hasDelay = null): ResponseInterface
76 | {
77 | $queryParamsMap = [];
78 |
79 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
80 |
81 | if ($hasDelay) {
82 | $queryParamsMap[] = ['key' => 'has_delay', 'value' => $hasDelay];
83 | }
84 |
85 | return $this->postApi('clips', $bearer, $queryParamsMap);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/TagsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_all_tags(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'tags/streams', 'TEST_TOKEN', [], [])->willReturn($request);
22 | $this->getAllStreamTags('TEST_TOKEN')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_all_tags_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'tags/streams', 'TEST_TOKEN', [['key' => 'tag_id', 'value' => '123']], [])->willReturn($request);
28 | $this->getAllStreamTags('TEST_TOKEN', ['123'])->shouldBe($response);
29 | }
30 |
31 | function it_should_get_all_tags_with_first(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'tags/streams', 'TEST_TOKEN', [['key' => 'first', 'value' => 100]], [])->willReturn($request);
34 | $this->getAllStreamTags('TEST_TOKEN', [], 100)->shouldBe($response);
35 | }
36 |
37 | function it_should_get_all_tags_with_after(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'tags/streams', 'TEST_TOKEN', [['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
40 | $this->getAllStreamTags('TEST_TOKEN', [], null, 'abc')->shouldBe($response);
41 | }
42 |
43 | function it_should_get_stream_tags(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('GET', 'streams/tags', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
46 | $this->getStreamTags('TEST_TOKEN', '123')->shouldBe($response);
47 | }
48 |
49 | function it_should_replace_stream_tags(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('PUT', 'streams/tags', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
52 | $this->replaceStreamTags('TEST_TOKEN', '123')->shouldBe($response);
53 | }
54 |
55 | function it_should_replace_stream_tags_with_one_tag(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $requestGenerator->generate('PUT', 'streams/tags', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [['key' => 'tag_ids', 'value' => ['456']]])->willReturn($request);
58 | $this->replaceStreamTags('TEST_TOKEN', '123', ['456'])->shouldBe($response);
59 | }
60 |
61 | function it_should_replace_stream_tags_with_multiple_tags(RequestGenerator $requestGenerator, Request $request, Response $response)
62 | {
63 | $requestGenerator->generate('PUT', 'streams/tags', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [['key' => 'tag_ids', 'value' => ['456', '789']]])->willReturn($request);
64 | $this->replaceStreamTags('TEST_TOKEN', '123', ['456', '789'])->shouldBe($response);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Resources/ChannelsApi.php:
--------------------------------------------------------------------------------
1 | 'broadcaster_id', 'value' => $broadcasterId];
21 |
22 | return $this->getApi('channels', $bearer, $queryParamsMap);
23 | }
24 |
25 | /**
26 | * @throws GuzzleException
27 | * @link https://dev.twitch.tv/docs/api/reference#get-channel-editors
28 | */
29 | public function getChannelEditors(string $bearer, string $broadcasterId): ResponseInterface
30 | {
31 | $queryParamsMap = [];
32 |
33 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
34 |
35 | return $this->getApi('channels/editors', $bearer, $queryParamsMap);
36 | }
37 |
38 | /**
39 | * @throws GuzzleException
40 | * @link https://dev.twitch.tv/docs/api/reference#modify-channel-information
41 | */
42 | public function modifyChannelInfo(string $bearer, string $broadcasterId, $bodyParams = []): ResponseInterface
43 | {
44 | // $bodyParams should be a standard key => value format, eg. ['game_id' => '1'];
45 | $queryParamsMap = $bodyParamsMap = [];
46 |
47 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
48 |
49 | foreach ($bodyParams as $key => $value) {
50 | $bodyParamsMap[] = ['key' => $key, 'value' => $value];
51 | }
52 |
53 | return $this->patchApi('channels', $bearer, $queryParamsMap, $bodyParamsMap);
54 | }
55 |
56 | /**
57 | * @throws GuzzleException
58 | * @link https://dev.twitch.tv/docs/api/reference/#get-followed-channels
59 | */
60 | public function getFollowedChannels(string $bearer, string $userId, string $broadcasterId = null, int $first = null, string $after = null): ResponseInterface
61 | {
62 | $queryParamsMap = [];
63 |
64 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
65 |
66 | if ($broadcasterId) {
67 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
68 | }
69 |
70 | if ($first) {
71 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
72 | }
73 |
74 | if ($after) {
75 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
76 | }
77 |
78 | return $this->getApi('channels/followed', $bearer, $queryParamsMap);
79 | }
80 |
81 | /**
82 | * @throws GuzzleException
83 | * @link https://dev.twitch.tv/docs/api/reference/#get-channel-followers
84 | */
85 | public function getChannelFollowers(string $bearer, string $broadcasterId, string $userId = null, int $first = null, string $after = null): ResponseInterface
86 | {
87 | $queryParamsMap = [];
88 |
89 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
90 |
91 | if ($userId) {
92 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
93 | }
94 |
95 | if ($first) {
96 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
97 | }
98 |
99 | if ($after) {
100 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
101 | }
102 |
103 | return $this->getApi('channels/followers', $bearer, $queryParamsMap);
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/BitsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_getcheermotes(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'bits/cheermotes', 'TEST_TOKEN', [], [])->willReturn($request);
22 | $this->getCheermotes('TEST_TOKEN')->shouldBe($response);
23 | }
24 |
25 | function it_should_getcheermotes_by_broadcaster_id(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'bits/cheermotes', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
28 | $this->getCheermotes('TEST_TOKEN', '123')->shouldBe($response);
29 | }
30 |
31 | function it_should_extension_transactions(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'extensions/transactions', 'TEST_TOKEN', [['key' => 'extension_id', 'value' => '1']], [])->willReturn($request);
34 | $this->getExtensionTransactions('TEST_TOKEN', '1')->shouldBe($response);
35 | }
36 |
37 | function it_should_extension_transactions_with_transaction_id(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'extensions/transactions', 'TEST_TOKEN', [['key' => 'extension_id', 'value' => '1'], ['key' => 'id', 'value' => '321']], [])->willReturn($request);
40 | $this->getExtensionTransactions('TEST_TOKEN', '1', ['321'])->shouldBe($response);
41 | }
42 |
43 | function it_should_extension_transactions_with_first(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('GET', 'extensions/transactions', 'TEST_TOKEN', [['key' => 'extension_id', 'value' => '1'], ['key' => 'first', 'value' => '100']], [])->willReturn($request);
46 | $this->getExtensionTransactions('TEST_TOKEN', '1', [], 100)->shouldBe($response);
47 | }
48 |
49 | function it_should_extension_transactions_with_after(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('GET', 'extensions/transactions', 'TEST_TOKEN', [['key' => 'extension_id', 'value' => '1'], ['key' => 'after', 'value' => '100']], [])->willReturn($request);
52 | $this->getExtensionTransactions('TEST_TOKEN', '1', [], null, 100)->shouldBe($response);
53 | }
54 |
55 | function it_should_get_bits_leaderboard(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $requestGenerator->generate('GET', 'bits/leaderboard', 'TEST_TOKEN', [], [])->willReturn($request);
58 | $this->getBitsLeaderboard('TEST_TOKEN')->shouldBe($response);
59 | }
60 |
61 | function it_should_get_bits_leaderboard_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
62 | {
63 | $requestGenerator->generate('GET', 'bits/leaderboard', 'TEST_TOKEN', [['key' => 'count', 'value' => '100'], ['key' => 'period', 'value' => 'all'], ['key' => 'started_at', 'value' => '2019-10-12T07:20:50.52Z'], ['key' => 'user_id', 'value' => '123']], [])->willReturn($request);
64 | $this->getBitsLeaderboard('TEST_TOKEN', 100, 'all', '2019-10-12T07:20:50.52Z', '123')->shouldBe($response);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/PollsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_polls(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'polls', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
22 | $this->getPolls('TEST_TOKEN', '123')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_polls_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'polls', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '321']], [])->willReturn($request);
28 | $this->getPolls('TEST_TOKEN', '123', ['321'])->shouldBe($response);
29 | }
30 |
31 | function it_should_get_polls_by_ids(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'polls', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '321'], ['key' => 'id', 'value' => '456']], [])->willReturn($request);
34 | $this->getPolls('TEST_TOKEN', '123', ['321', '456'])->shouldBe($response);
35 | }
36 |
37 | function it_should_get_polls_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'polls', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'after', 'value' => 'abc'], ['key' => 'first', 'value' => 100]], [])->willReturn($request);
40 | $this->getPolls('TEST_TOKEN', '123', [], 'abc', 100)->shouldBe($response);
41 | }
42 |
43 | function it_should_create_a_poll(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('POST', 'polls', 'TEST_TOKEN', [], [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'title', 'value' => 'What is my name?'], ['key' => 'choices', 'value' => [['title' => 'John'], ['title' => 'Doe']]], ['key' => 'duration', 'value' => 15]])->willReturn($request);
46 | $this->createPoll('TEST_TOKEN', '123', 'What is my name?', [['title' => 'John'], ['title' => 'Doe']], 15)->shouldBe($response);
47 | }
48 |
49 | function it_should_create_a_poll_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('POST', 'polls', 'TEST_TOKEN', [], [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'title', 'value' => 'What is my name?'], ['key' => 'choices', 'value' => [['title' => 'John'], ['title' => 'Doe']]], ['key' => 'duration', 'value' => 15], ['key' => 'bits_voting_enabled', 'value' => 1]])->willReturn($request);
52 | $this->createPoll('TEST_TOKEN', '123', 'What is my name?', [['title' => 'John'], ['title' => 'Doe']], 15, ['bits_voting_enabled' => 1])->shouldBe($response);
53 | }
54 |
55 | function it_should_end_a_poll(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $requestGenerator->generate('PATCH', 'polls', 'TEST_TOKEN', [], [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '456'], ['key' => 'status', 'value' => 'TERMINATED']])->willReturn($request);
58 | $this->endPoll('TEST_TOKEN', '123', '456', 'TERMINATED')->shouldBe($response);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/PredictionsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_predictions(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'predictions', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
22 | $this->getPredictions('TEST_TOKEN', '123')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_predictions_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'predictions', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '321']], [])->willReturn($request);
28 | $this->getPredictions('TEST_TOKEN', '123', ['321'])->shouldBe($response);
29 | }
30 |
31 | function it_should_get_predictions_by_ids(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'predictions', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '321'], ['key' => 'id', 'value' => '456']], [])->willReturn($request);
34 | $this->getPredictions('TEST_TOKEN', '123', ['321', '456'])->shouldBe($response);
35 | }
36 |
37 | function it_should_get_predictions_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'predictions', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'after', 'value' => 'abc'], ['key' => 'first', 'value' => 100]], [])->willReturn($request);
40 | $this->getPredictions('TEST_TOKEN', '123', [], 'abc', 100)->shouldBe($response);
41 | }
42 |
43 | function it_should_create_a_prediction(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('POST', 'predictions', 'TEST_TOKEN', [], [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'title', 'value' => 'Will the coin land on heads or tails?'], ['key' => 'outcomes', 'value' => [['title' => 'Heads'], ['title' => 'Tails']]], ['key' => 'prediction_window', 'value' => 15]])->willReturn($request);
46 | $this->createPrediction('TEST_TOKEN', '123', 'Will the coin land on heads or tails?', [['title' => 'Heads'], ['title' => 'Tails']], 15)->shouldBe($response);
47 | }
48 |
49 | function it_should_end_a_prediction(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('PATCH', 'predictions', 'TEST_TOKEN', [], [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '456'], ['key' => 'status', 'value' => 'CANCELLED']])->willReturn($request);
52 | $this->endPrediction('TEST_TOKEN', '123', '456', 'CANCELLED')->shouldBe($response);
53 | }
54 |
55 | function it_should_resolve_a_prediction(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $requestGenerator->generate('PATCH', 'predictions', 'TEST_TOKEN', [], [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '456'], ['key' => 'status', 'value' => 'RESOLVED'], ['key' => 'winning_outcome_id', 'value' => '1']])->willReturn($request);
58 | $this->endPrediction('TEST_TOKEN', '123', '456', 'RESOLVED', '1')->shouldBe($response);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Resources/EntitlementsApi.php:
--------------------------------------------------------------------------------
1 | 'manifest_id', 'value' => $manifestId];
20 | $queryParamsMap[] = ['key' => 'type', 'value' => $type];
21 |
22 | return $this->postApi('entitlements/upload', $bearer, $queryParamsMap);
23 | }
24 |
25 | /**
26 | * @throws GuzzleException
27 | * @link https://dev.twitch.tv/docs/api/reference#get-code-status
28 | */
29 | public function getCodeStatus(string $bearer, int $userId, array $codes = []): ResponseInterface
30 | {
31 | $queryParamsMap = [];
32 |
33 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
34 |
35 | foreach ($codes as $code) {
36 | $queryParamsMap[] = ['key' => 'code', 'value' => $code];
37 | }
38 |
39 | return $this->getApi('entitlements/codes', $bearer, $queryParamsMap);
40 | }
41 |
42 | /**
43 | * @throws GuzzleException
44 | * @link https://dev.twitch.tv/docs/api/reference#get-drops-entitlements
45 | */
46 | public function getDropsEntitlements(string $bearer, string $id = null, string $userId = null, string $gameId = null, string $after = null, int $first = null, string $fulfillmentStatus = null): ResponseInterface
47 | {
48 | $queryParamsMap = [];
49 |
50 | if ($id) {
51 | $queryParamsMap[] = ['key' => 'id', 'value' => $id];
52 | }
53 |
54 | if ($userId) {
55 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
56 | }
57 |
58 | if ($gameId) {
59 | $queryParamsMap[] = ['key' => 'game_id', 'value' => $gameId];
60 | }
61 |
62 | if ($after) {
63 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
64 | }
65 |
66 | if ($first) {
67 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
68 | }
69 |
70 | if ($fulfillmentStatus) {
71 | $queryParamsMap[] = ['key' => 'fulfillment_status', 'value' => $fulfillmentStatus];
72 | }
73 |
74 | return $this->getApi('entitlements/drops', $bearer, $queryParamsMap);
75 | }
76 |
77 | /**
78 | * @throws GuzzleException
79 | * @link https://dev.twitch.tv/docs/api/reference#update-drops-entitlements
80 | */
81 | public function updateDropsEntitlements(string $bearer, array $entitlement_ids = null, string $fulfillment_status = null): ResponseInterface
82 | {
83 | $bodyParamsMap = [];
84 |
85 | if ($entitlement_ids) {
86 | $bodyParamsMap[] = ['key' => 'entitlement_ids', 'value' => $entitlement_ids];
87 | }
88 |
89 | if ($fulfillment_status) {
90 | $bodyParamsMap[] = ['key' => 'fulfillment_status', 'value' => $fulfillment_status];
91 | }
92 |
93 | return $this->patchApi('entitlements/drops', $bearer, [], $bodyParamsMap);
94 | }
95 |
96 | /**
97 | * @throws GuzzleException
98 | * @link https://dev.twitch.tv/docs/api/reference#redeem-code
99 | */
100 | public function redeemCode(string $bearer, int $userId, array $codes = []): ResponseInterface
101 | {
102 | $queryParamsMap = [];
103 |
104 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
105 |
106 | foreach ($codes as $code) {
107 | $queryParamsMap[] = ['key' => 'code', 'value' => $code];
108 | }
109 |
110 | return $this->postApi('entitlements/code', $bearer, $queryParamsMap);
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Auth/OauthApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith('client-id', 'client-secret', $guzzleClient);
15 | }
16 |
17 | function it_should_get_auth_url(Client $guzzleClient)
18 | {
19 | $guzzleClient->getConfig('base_uri')->willReturn('https://id.twitch.tv/oauth2/');
20 | $this->getAuthUrl('https://redirect.url')->shouldReturn(
21 | 'https://id.twitch.tv/oauth2/authorize?client_id=client-id&redirect_uri=https://redirect.url&response_type=code&scope='
22 | );
23 | }
24 |
25 | function it_should_get_access_token(Client $guzzleClient, Response $response)
26 | {
27 | $request = new Request(
28 | 'POST',
29 | 'token'
30 | );
31 | $guzzleClient->send($request, ['json' => [
32 | 'client_id' => 'client-id',
33 | 'client_secret' => 'client-secret',
34 | 'grant_type' => 'authorization_code',
35 | 'redirect_uri' => 'https://redirect.url',
36 | 'code' => 'user-code-from-twitch',
37 | 'state' => null,
38 | ]])->willReturn($response);
39 |
40 | $this->getUserAccessToken('user-code-from-twitch', 'https://redirect.url')->shouldBe($response);
41 | }
42 |
43 | function it_should_get_refresh_token(Client $guzzleClient, Response $response)
44 | {
45 | $request = new Request(
46 | 'POST',
47 | 'token'
48 | );
49 | $guzzleClient->send($request, ['json' => [
50 | 'client_id' => 'client-id',
51 | 'client_secret' => 'client-secret',
52 | 'grant_type' => 'refresh_token',
53 | 'refresh_token' => 'user-refresh-token',
54 | ]])->willReturn($response);
55 |
56 | $this->refreshToken('user-refresh-token')->shouldBe($response);
57 | }
58 |
59 | function it_should_validate_access_token(Client $guzzleClient, Response $response)
60 | {
61 | $request = new Request(
62 | 'GET',
63 | 'validate',
64 | [
65 | 'Authorization' => 'OAuth user-access-token',
66 | ]
67 | );
68 | $guzzleClient->send($request, [])->willReturn($response);
69 |
70 | $this->validateAccessToken('user-access-token')->shouldBe($response);
71 | }
72 |
73 | function it_should_return_true_if_access_token_is_valid(Client $guzzleClient, Response $response)
74 | {
75 | $request = new Request(
76 | 'GET',
77 | 'validate',
78 | [
79 | 'Authorization' => 'OAuth user-access-token',
80 | ]
81 | );
82 | $response->getStatusCode()->willReturn(200);
83 | $guzzleClient->send($request, [])->willReturn($response);
84 |
85 | $this->isValidAccessToken('user-access-token')->shouldReturn(true);
86 | }
87 |
88 | function it_should_return_false_if_access_token_is_invalid(Client $guzzleClient, Response $response)
89 | {
90 | $request = new Request(
91 | 'GET',
92 | 'validate',
93 | [
94 | 'Authorization' => 'OAuth invalid-user-access-token',
95 | ]
96 | );
97 | $response->getStatusCode()->willReturn(401);
98 | $guzzleClient->send($request, [])->willReturn($response);
99 |
100 | $this->isValidAccessToken('invalid-user-access-token')->shouldReturn(false);
101 | }
102 |
103 | function it_should_get_app_access_token(Client $guzzleClient, Response $response)
104 | {
105 | $request = new Request(
106 | 'POST',
107 | 'token'
108 | );
109 | $guzzleClient->send($request, ['json' => [
110 | 'client_id' => 'client-id',
111 | 'client_secret' => 'client-secret',
112 | 'grant_type' => 'client_credentials',
113 | 'scope' => '',
114 | ]])->willReturn($response);
115 |
116 | $this->getAppAccessToken()->shouldBe($response);
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/ClipsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_clips_by_broadcaster_id(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'clips', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
22 | $this->getClips('TEST_TOKEN', '123')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_clips_by_broadcaster_id_with_helper_function(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'clips', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
28 | $this->getClipsByBroadcasterId('TEST_TOKEN', '123')->shouldBe($response);
29 | }
30 |
31 | function it_should_get_clips_by_game_id(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'clips', 'TEST_TOKEN', [['key' => 'game_id', 'value' => '123']], [])->willReturn($request);
34 | $this->getClips('TEST_TOKEN', null, '123')->shouldBe($response);
35 | }
36 |
37 | function it_should_get_clips_by_game_id_with_helper_function(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'clips', 'TEST_TOKEN', [['key' => 'game_id', 'value' => '123']], [])->willReturn($request);
40 | $this->getClipsByGameId('TEST_TOKEN', '123')->shouldBe($response);
41 | }
42 |
43 | function it_should_get_one_clip_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('GET', 'clips', 'TEST_TOKEN', [['key' => 'id', 'value' => '123']], [])->willReturn($request);
46 | $this->getClips('TEST_TOKEN', null, null, '123')->shouldBe($response);
47 | }
48 |
49 | function it_should_get_one_clip_by_id_with_helper_function(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('GET', 'clips', 'TEST_TOKEN', [['key' => 'id', 'value' => '123']], [])->willReturn($request);
52 | $this->getClipsByIds('TEST_TOKEN', '123')->shouldBe($response);
53 | }
54 |
55 | function it_should_get_multiple_clips_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $requestGenerator->generate('GET', 'clips', 'TEST_TOKEN', [['key' => 'id', 'value' => '123,456']], [])->willReturn($request);
58 | $this->getClips('TEST_TOKEN', null, null, '123,456')->shouldBe($response);
59 | }
60 |
61 | function it_should_get_multiple_clips_by_id_with_helper_function(RequestGenerator $requestGenerator, Request $request, Response $response)
62 | {
63 | $requestGenerator->generate('GET', 'clips', 'TEST_TOKEN', [['key' => 'id', 'value' => '123,456']], [])->willReturn($request);
64 | $this->getClipsByIds('TEST_TOKEN', '123,456')->shouldBe($response);
65 | }
66 |
67 | function it_should_get_clips_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
68 | {
69 | $requestGenerator->generate('GET', 'clips', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'first', 'value' => '10'], ['key' => 'before', 'value' => 'abc'], ['key' => 'after', 'value' => 'def'], ['key' => 'started_at', 'value' => '2018-10-12T07:20:50.52Z'], ['key' => 'ended_at', 'value' => '2019-10-12T07:20:50.52Z']], [])->willReturn($request);
70 | $this->getClips('TEST_TOKEN', '123', null, null, 10, 'abc', 'def', '2018-10-12T07:20:50.52Z', '2019-10-12T07:20:50.52Z')->shouldBe($response);
71 | }
72 |
73 | function it_should_create_a_clip(RequestGenerator $requestGenerator, Request $request, Response $response)
74 | {
75 | $requestGenerator->generate('POST', 'clips', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'has_delay', 'value' => 'true']], [])->willReturn($request);
76 | $this->createClip('TEST_TOKEN', '123', true)->shouldBe($response);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/Auth/OauthApi.php:
--------------------------------------------------------------------------------
1 | clientId = $clientId;
22 | $this->clientSecret = $clientSecret;
23 | $this->guzzleClient = $guzzleClient ?? AuthGuzzleClient::getClient();
24 | }
25 |
26 | /**
27 | * @return string A full authentication URL, including the Guzzle client's base URI.
28 | */
29 | public function getAuthUrl(string $redirectUri, string $responseType = 'code', string $scope = '', bool $forceVerify = false, string $state = null): string
30 | {
31 | return sprintf(
32 | '%s%s',
33 | $this->guzzleClient->getConfig('base_uri'),
34 | $this->getPartialAuthUrl($redirectUri, $responseType, $scope, $forceVerify, $state)
35 | );
36 | }
37 |
38 | /**
39 | * @throws GuzzleException
40 | */
41 | public function getUserAccessToken($code, string $redirectUri, $state = null): ResponseInterface
42 | {
43 | return $this->makeRequest(
44 | new Request('POST', 'token'),
45 | [
46 | RequestOptions::JSON => [
47 | 'client_id' => $this->clientId,
48 | 'client_secret' => $this->clientSecret,
49 | 'grant_type' => 'authorization_code',
50 | 'redirect_uri' => $redirectUri,
51 | 'code' => $code,
52 | 'state' => $state,
53 | ],
54 | ]
55 | );
56 | }
57 |
58 | /**
59 | * @throws GuzzleException
60 | */
61 | public function refreshToken(string $refeshToken, string $scope = ''): ResponseInterface
62 | {
63 | $requestOptions = [
64 | 'client_id' => $this->clientId,
65 | 'client_secret' => $this->clientSecret,
66 | 'grant_type' => 'refresh_token',
67 | 'refresh_token' => $refeshToken,
68 | ];
69 | if ($scope) {
70 | $requestOptions['scope'] = $scope;
71 | }
72 |
73 | return $this->makeRequest(
74 | new Request('POST', 'token'),
75 | [
76 | RequestOptions::JSON => $requestOptions,
77 | ]
78 | );
79 | }
80 |
81 | /**
82 | * @throws GuzzleException
83 | */
84 | public function validateAccessToken(string $accessToken): ResponseInterface
85 | {
86 | return $this->makeRequest(
87 | new Request(
88 | 'GET',
89 | 'validate',
90 | [
91 | 'Authorization' => sprintf('OAuth %s', $accessToken),
92 | ]
93 | )
94 | );
95 | }
96 |
97 | /**
98 | * @throws GuzzleException
99 | */
100 | public function isValidAccessToken(string $accessToken): bool
101 | {
102 | return $this->validateAccessToken($accessToken)->getStatusCode() === 200;
103 | }
104 |
105 | /**
106 | * @throws GuzzleException
107 | */
108 | public function getAppAccessToken(string $scope = ''): ResponseInterface
109 | {
110 | return $this->makeRequest(
111 | new Request('POST', 'token'),
112 | [
113 | RequestOptions::JSON => [
114 | 'client_id' => $this->clientId,
115 | 'client_secret' => $this->clientSecret,
116 | 'grant_type' => 'client_credentials',
117 | 'scope' => $scope,
118 | ],
119 | ]
120 | );
121 | }
122 |
123 | /**
124 | * @throws GuzzleException
125 | */
126 | private function makeRequest(Request $request, array $options = []): ResponseInterface
127 | {
128 | return $this->guzzleClient->send($request, $options);
129 | }
130 |
131 | /**
132 | * @return string A partial authentication URL, excluding the Guzzle client's base URI.
133 | */
134 | private function getPartialAuthUrl(string $redirectUri, string $responseType = 'code', string $scope = '', bool $forceVerify = false, string $state = null): string
135 | {
136 | $optionalParameters = '';
137 | $optionalParameters .= $forceVerify ? '&force_verify=true' : '';
138 | $optionalParameters .= $state ? sprintf('&state=%s', $state) : '';
139 |
140 | return sprintf(
141 | 'authorize?client_id=%s&redirect_uri=%s&response_type=%s&scope=%s%s',
142 | $this->clientId,
143 | $redirectUri,
144 | $responseType,
145 | $scope,
146 | $optionalParameters
147 | );
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/ChannelsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_channel_info(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'channels', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
22 | $this->getChannelInfo('TEST_TOKEN', '123')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_channel_editors(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'channels/editors', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
28 | $this->getChannelEditors('TEST_TOKEN', '123')->shouldBe($response);
29 | }
30 |
31 | function it_should_modify_channel_with_game_id(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('PATCH', 'channels', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [['key' => 'game_id', 'value' => '0']])->willReturn($request);
34 | $this->modifyChannelInfo('TEST_TOKEN', '123', ['game_id' => '0'])->shouldBe($response);
35 | }
36 |
37 | function it_should_modify_channel_with_language(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('PATCH', 'channels', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [['key' => 'broadcaster_language', 'value' => 'en']])->willReturn($request);
40 | $this->modifyChannelInfo('TEST_TOKEN', '123', ['broadcaster_language' => 'en'])->shouldBe($response);
41 | }
42 |
43 | function it_should_modify_channel_with_title(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('PATCH', 'channels', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [['key' => 'title', 'value' => 'test 123']])->willReturn($request);
46 | $this->modifyChannelInfo('TEST_TOKEN', '123', ['title' => 'test 123'])->shouldBe($response);
47 | }
48 |
49 | function it_should_modify_channel_with_delay(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('PATCH', 'channels', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [['key' => 'delay', 'value' => 5]])->willReturn($request);
52 | $this->modifyChannelInfo('TEST_TOKEN', '123', ['delay' => 5])->shouldBe($response);
53 | }
54 |
55 | function it_should_modify_channel_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $requestGenerator->generate('PATCH', 'channels', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [['key' => 'game_id', 'value' => '0'], ['key' => 'broadcaster_language', 'value' => 'en'], ['key' => 'title', 'value' => 'test 123'], ['key' => 'delay', 'value' => 5]])->willReturn($request);
58 | $this->modifyChannelInfo('TEST_TOKEN', '123', ['game_id' => '0', 'broadcaster_language' => 'en', 'title' => 'test 123', 'delay' => 5])->shouldBe($response);
59 | }
60 |
61 | function it_should_get_followed_channels(RequestGenerator $requestGenerator, Request $request, Response $response)
62 | {
63 | $requestGenerator->generate('GET', 'channels/followed', 'TEST_TOKEN', [['key' => 'user_id', 'value' => '123']], [])->willReturn($request);
64 | $this->getFollowedChannels('TEST_TOKEN', '123')->shouldBe($response);
65 | }
66 |
67 | function it_should_get_followed_channels_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
68 | {
69 | $requestGenerator->generate('GET', 'channels/followed', 'TEST_TOKEN', [['key' => 'user_id', 'value' => '123'], ['key' => 'broadcaster_id', 'value' => '456'], ['key' => 'first', 'value' => 100], ['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
70 | $this->getFollowedChannels('TEST_TOKEN', '123', '456', 100, 'abc')->shouldBe($response);
71 | }
72 |
73 | function it_should_get_channel_followers(RequestGenerator $requestGenerator, Request $request, Response $response)
74 | {
75 | $requestGenerator->generate('GET', 'channels/followers', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
76 | $this->getChannelFollowers('TEST_TOKEN', '123')->shouldBe($response);
77 | }
78 |
79 | function it_should_get_channel_followers_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
80 | {
81 | $requestGenerator->generate('GET', 'channels/followers', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'user_id', 'value' => '456'], ['key' => 'first', 'value' => 100], ['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
82 | $this->getChannelFollowers('TEST_TOKEN', '123', '456', 100, 'abc')->shouldBe($response);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/Webhooks/WebhooksSubscriptionApi.php:
--------------------------------------------------------------------------------
1 | clientId = $clientId;
21 | $this->secret = $secret;
22 | $this->guzzleClient = $guzzleClient ?? HelixGuzzleClient::getClient($clientId);
23 | }
24 |
25 | public function subscribeToStream(string $twitchId, string $callback, string $bearer, int $leaseSeconds = 0): void
26 | {
27 | $this->subscribe(
28 | sprintf('https://api.twitch.tv/helix/streams?user_id=%s', $twitchId),
29 | $callback,
30 | $bearer,
31 | $leaseSeconds
32 | );
33 | }
34 |
35 | public function subscribeToSubscriptionEvents(string $twitchId, string $callback, string $bearer, int $leaseSeconds = 0): void
36 | {
37 | $this->subscribe(
38 | sprintf('https://api.twitch.tv/helix/subscriptions/events?broadcaster_id=%s&first=1', $twitchId),
39 | $callback,
40 | $bearer,
41 | $leaseSeconds
42 | );
43 | }
44 |
45 | public function subscribeToUser(string $twitchId, string $callback, string $bearer, int $leaseSeconds = 0): void
46 | {
47 | $this->subscribe(
48 | sprintf('https://api.twitch.tv/helix/users?id=%s', $twitchId),
49 | $callback,
50 | $bearer,
51 | $leaseSeconds
52 | );
53 | }
54 |
55 | public function subscribeToUserFollows(string $followerId, string $followedUserId, int $first, string $callback, string $bearer, int $leaseSeconds = 0): void
56 | {
57 | $queryParams = [];
58 | if ($followerId) {
59 | $queryParams['from_id'] = $followerId;
60 | }
61 | if ($followedUserId) {
62 | $queryParams['to_id'] = $followedUserId;
63 | }
64 | if ($first) {
65 | $queryParams['first'] = $first;
66 | }
67 | $this->subscribe(
68 | sprintf('https://api.twitch.tv/helix/users/follows?%s', http_build_query($queryParams)),
69 | $callback,
70 | $bearer,
71 | $leaseSeconds
72 | );
73 | }
74 |
75 | public function unsubscribeFromStream(string $twitchId, string $callback, string $bearer): void
76 | {
77 | $this->unsubscribe(
78 | sprintf('https://api.twitch.tv/helix/streams?user_id=%s', $twitchId),
79 | $callback,
80 | $bearer
81 | );
82 | }
83 |
84 | public function unsubscribeFromUser(string $twitchId, string $callback, string $bearer)
85 | {
86 | $this->unsubscribe(
87 | sprintf('https://api.twitch.tv/helix/users?id=%s', $twitchId),
88 | $callback,
89 | $bearer
90 | );
91 | }
92 |
93 | public function unsubscribeFromUserFollows(string $followerId, string $followedUserId, int $first, string $callback, string $bearer)
94 | {
95 | $queryParams = [];
96 | if ($followerId) {
97 | $queryParams['from_id'] = $followerId;
98 | }
99 | if ($followedUserId) {
100 | $queryParams['to_id'] = $followedUserId;
101 | }
102 | if ($first) {
103 | $queryParams['first'] = $first;
104 | }
105 | $this->unsubscribe(
106 | sprintf('https://api.twitch.tv/helix/users/follows?%s', http_build_query($queryParams)),
107 | $callback,
108 | $bearer
109 | );
110 | }
111 |
112 | public function validateWebhookEventCallback(string $xHubSignature, string $content): bool
113 | {
114 | [$hashAlgorithm, $expectedHash] = explode('=', $xHubSignature);
115 | $generatedHash = hash_hmac($hashAlgorithm, $content, $this->secret);
116 |
117 | return $expectedHash === $generatedHash;
118 | }
119 |
120 | private function subscribe(string $topic, string $callback, string $bearer, int $leaseSeconds = 0): void
121 | {
122 | $headers = [
123 | 'Client-ID' => $this->clientId,
124 | ];
125 |
126 | $headers['Authorization'] = sprintf('Bearer %s', $bearer);
127 |
128 | $body = [
129 | 'hub.callback' => $callback,
130 | 'hub.mode' => self::SUBSCRIBE,
131 | 'hub.topic' => $topic,
132 | 'hub.lease_seconds' => $leaseSeconds,
133 | 'hub.secret' => $this->secret,
134 | ];
135 |
136 | $this->guzzleClient->post('webhooks/hub', [
137 | 'headers' => $headers,
138 | 'body' => json_encode($body),
139 | ]);
140 | }
141 |
142 | private function unsubscribe(string $topic, string $callback, string $bearer): void
143 | {
144 | $headers = [
145 | 'Client-ID' => $this->clientId,
146 | ];
147 |
148 | $headers['Authorization'] = sprintf('Bearer %s', $bearer);
149 |
150 | $body = [
151 | 'hub.callback' => $callback,
152 | 'hub.mode' => self::UNSUBSCRIBE,
153 | 'hub.topic' => $topic,
154 | ];
155 |
156 | $this->guzzleClient->post('webhooks/hub', [
157 | 'headers' => $headers,
158 | 'body' => json_encode($body),
159 | ]);
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/src/Resources/StreamsApi.php:
--------------------------------------------------------------------------------
1 | getStreams($bearer, [$userId]);
18 | }
19 |
20 | /**
21 | * @throws GuzzleException
22 | */
23 | public function getStreamForUsername(string $bearer, string $username): ResponseInterface
24 | {
25 | return $this->getStreams($bearer, [], [$username]);
26 | }
27 |
28 | /**
29 | * @throws GuzzleException
30 | */
31 | public function getStreamsByGameId(string $bearer, string $gameId, int $first = null, string $before = null, string $after = null): ResponseInterface
32 | {
33 | return $this->getStreams($bearer, [], [], [$gameId]);
34 | }
35 |
36 | /**
37 | * @throws GuzzleException
38 | */
39 | public function getStreamsByLanguage(string $bearer, string $language, int $first = null, string $before = null, string $after = null): ResponseInterface
40 | {
41 | return $this->getStreams($bearer, [], [], [], [$language]);
42 | }
43 |
44 | /**
45 | * @throws GuzzleException
46 | * @link https://dev.twitch.tv/docs/api/reference#get-stream-key
47 | */
48 | public function getStreamKey(string $bearer, string $broadcasterId): ResponseInterface
49 | {
50 | $queryParamsMap = [];
51 |
52 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
53 |
54 | return $this->getApi('streams/key', $bearer, $queryParamsMap);
55 | }
56 |
57 | /**
58 | * @throws GuzzleException
59 | * @link https://dev.twitch.tv/docs/api/reference/#get-streams
60 | */
61 | public function getStreams(string $bearer, array $userIds = [], array $usernames = [], array $gameIds = [], array $languages = [], int $first = null, string $before = null, string $after = null): ResponseInterface
62 | {
63 | $queryParamsMap = [];
64 | foreach ($userIds as $id) {
65 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $id];
66 | }
67 | foreach ($usernames as $username) {
68 | $queryParamsMap[] = ['key' => 'user_login', 'value' => $username];
69 | }
70 | foreach ($gameIds as $gameId) {
71 | $queryParamsMap[] = ['key' => 'game_id', 'value' => $gameId];
72 | }
73 | foreach ($languages as $language) {
74 | $queryParamsMap[] = ['key' => 'language', 'value' => $language];
75 | }
76 | if ($first) {
77 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
78 | }
79 | if ($before) {
80 | $queryParamsMap[] = ['key' => 'before', 'value' => $before];
81 | }
82 | if ($after) {
83 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
84 | }
85 |
86 | return $this->getApi('streams', $bearer, $queryParamsMap);
87 | }
88 |
89 | /**
90 | * @throws GuzzleException
91 | * @link https://dev.twitch.tv/docs/api/reference/#get-stream-markers
92 | */
93 | public function getStreamMarkers(string $bearer, string $userId = null, string $videoId = null, string $first = null, string $before = null, string $after = null): ResponseInterface
94 | {
95 | $queryParamsMap = [];
96 |
97 | if ($userId) {
98 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
99 | }
100 |
101 | if ($videoId) {
102 | $queryParamsMap[] = ['key' => 'video_id', 'value' => $videoId];
103 | }
104 |
105 | if ($first) {
106 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
107 | }
108 |
109 | if ($before) {
110 | $queryParamsMap[] = ['key' => 'before', 'value' => $before];
111 | }
112 |
113 | if ($after) {
114 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
115 | }
116 |
117 | return $this->getApi('streams/markers', $bearer, $queryParamsMap);
118 | }
119 |
120 | /**
121 | * @throws GuzzleException
122 | * @link https://dev.twitch.tv/docs/api/reference/#get-followed-streams
123 | */
124 | public function getFollowedStreams(string $bearer, string $userId, int $first = null, string $after = null): ResponseInterface
125 | {
126 | $queryParamsMap = [];
127 |
128 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
129 |
130 | if ($first) {
131 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
132 | }
133 |
134 | if ($after) {
135 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
136 | }
137 |
138 | return $this->getApi('streams/followed', $bearer, $queryParamsMap);
139 | }
140 |
141 | /**
142 | * @throws GuzzleException
143 | * @link https://dev.twitch.tv/docs/api/reference#create-stream-marker
144 | */
145 | public function createStreamMarker(string $bearer, string $userId, string $description = null): ResponseInterface
146 | {
147 | $bodyParamsMap = [];
148 |
149 | $bodyParamsMap[] = ['key' => 'user_id', 'value' => $userId];
150 | if ($description) {
151 | $bodyParamsMap[] = ['key' => 'description', 'value' => $description];
152 | }
153 |
154 | return $this->postApi('streams/markers', $bearer, [], $bodyParamsMap);
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/src/Resources/ChannelPointsApi.php:
--------------------------------------------------------------------------------
1 | getCustomReward($bearer, $broadcasterId, [$id], $onlyManageableRewards);
18 | }
19 |
20 | /**
21 | * @throws GuzzleException
22 | * @link https://dev.twitch.tv/docs/api/reference#get-custom-reward
23 | */
24 | public function getCustomReward(string $bearer, string $broadcasterId, array $ids = [], bool $onlyManageableRewards = null): ResponseInterface
25 | {
26 | $queryParamsMap = [];
27 |
28 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
29 |
30 | foreach ($ids as $id) {
31 | $queryParamsMap[] = ['key' => 'id', 'value' => $id];
32 | }
33 |
34 | if ($onlyManageableRewards) {
35 | $queryParamsMap[] = ['key' => 'only_manageable_rewards', 'value' => $onlyManageableRewards];
36 | }
37 |
38 | return $this->getApi('channel_points/custom_rewards', $bearer, $queryParamsMap);
39 | }
40 |
41 | /**
42 | * @throws GuzzleException
43 | * @link https://dev.twitch.tv/docs/api/reference#get-custom-reward-redemption
44 | */
45 | public function getCustomRewardRedemption(string $bearer, string $broadcasterId, string $rewardId = null, array $ids = [], string $status = null, string $sort = null, string $after = null, string $first = null): ResponseInterface
46 | {
47 | $queryParamsMap = [];
48 |
49 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
50 |
51 | if ($rewardId) {
52 | $queryParamsMap[] = ['key' => 'reward_id', 'value' => $rewardId];
53 | }
54 |
55 | foreach ($ids as $id) {
56 | $queryParamsMap[] = ['key' => 'id', 'value' => $id];
57 | }
58 |
59 | if ($status) {
60 | $queryParamsMap[] = ['key' => 'status', 'value' => $status];
61 | }
62 |
63 | if ($sort) {
64 | $queryParamsMap[] = ['key' => 'sort', 'value' => $sort];
65 | }
66 |
67 | if ($after) {
68 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
69 | }
70 |
71 | if ($first) {
72 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
73 | }
74 |
75 | return $this->getApi('channel_points/custom_rewards/redemptions', $bearer, $queryParamsMap);
76 | }
77 |
78 | /**
79 | * @throws GuzzleException
80 | * @link https://dev.twitch.tv/docs/api/reference#create-custom-rewards
81 | */
82 | public function createCustomReward(string $bearer, string $broadcasterId, string $title, int $cost, $additionalBodyParams = []): ResponseInterface
83 | {
84 | // $additionalBodyParams should be a standard key => value format, eg. ['game_id' => '1'];
85 | $queryParamsMap = $bodyParamsMap = [];
86 |
87 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
88 |
89 | $bodyParamsMap[] = ['key' => 'title', 'value' => $title];
90 | $bodyParamsMap[] = ['key' => 'cost', 'value' => $cost];
91 |
92 | foreach ($additionalBodyParams as $key => $value) {
93 | $bodyParamsMap[] = ['key' => $key, 'value' => $value];
94 | }
95 |
96 | return $this->postApi('channel_points/custom_rewards', $bearer, $queryParamsMap, $bodyParamsMap);
97 | }
98 |
99 | /**
100 | * @throws GuzzleException
101 | * @link https://dev.twitch.tv/docs/api/reference#update-custom-reward
102 | */
103 | public function updateCustomReward(string $bearer, string $broadcasterId, string $rewardId, $bodyParams = []): ResponseInterface
104 | {
105 | // $bodyParams should be a standard key => value format, eg. ['game_id' => '1'];
106 | $queryParamsMap = $bodyParamsMap = [];
107 |
108 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
109 | $queryParamsMap[] = ['key' => 'id', 'value' => $rewardId];
110 |
111 | foreach ($bodyParams as $key => $value) {
112 | $bodyParamsMap[] = ['key' => $key, 'value' => $value];
113 | }
114 |
115 | return $this->patchApi('channel_points/custom_rewards', $bearer, $queryParamsMap, $bodyParamsMap);
116 | }
117 |
118 | /**
119 | * @throws GuzzleException
120 | * @link https://dev.twitch.tv/docs/api/reference#delete-custom-reward
121 | */
122 | public function deleteCustomReward(string $bearer, string $broadcasterId, string $id): ResponseInterface
123 | {
124 | $queryParamsMap = [];
125 |
126 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
127 |
128 | $queryParamsMap[] = ['key' => 'id', 'value' => $id];
129 |
130 | return $this->deleteApi('channel_points/custom_rewards', $bearer, $queryParamsMap);
131 | }
132 |
133 | /**
134 | * @throws GuzzleException
135 | * @link https://dev.twitch.tv/docs/api/reference#update-redemption-status
136 | */
137 | public function updateRedemptionStatus(string $bearer, string $broadcasterId, string $rewardId, string $redemptionId, string $status): ResponseInterface
138 | {
139 | $queryParamsMap = $bodyParamsMap = [];
140 |
141 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
142 | $queryParamsMap[] = ['key' => 'reward_id', 'value' => $rewardId];
143 | $queryParamsMap[] = ['key' => 'id', 'value' => $redemptionId];
144 |
145 | $bodyParamsMap[] = ['key' => 'status', 'value' => $status];
146 |
147 | return $this->patchApi('channel_points/custom_rewards/redemptions', $bearer, $queryParamsMap, $bodyParamsMap);
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/spec/TwitchApi/TwitchApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, 'client-id', 'client-secret');
43 | }
44 |
45 | function it_should_provide_oauth_api()
46 | {
47 | $this->getOauthApi()->shouldBeAnInstanceOf(OauthApi::class);
48 | }
49 |
50 | function it_should_provide_ads_api()
51 | {
52 | $this->getAdsApi()->shouldBeAnInstanceOf(AdsApi::class);
53 | }
54 |
55 | function it_should_provide_analytics_api()
56 | {
57 | $this->getAnalyticsApi()->shouldBeAnInstanceOf(AnalyticsApi::class);
58 | }
59 |
60 | function it_should_provide_bits_api()
61 | {
62 | $this->getBitsApi()->shouldBeAnInstanceOf(BitsApi::class);
63 | }
64 |
65 | function it_should_provide_channel_points_api()
66 | {
67 | $this->getChannelPointsApi()->shouldBeAnInstanceOf(ChannelPointsApi::class);
68 | }
69 |
70 | function it_should_provide_channels_api()
71 | {
72 | $this->getChannelsApi()->shouldBeAnInstanceOf(ChannelsApi::class);
73 | }
74 |
75 | function it_should_provide_charity_api()
76 | {
77 | $this->getCharityApi()->shouldBeAnInstanceOf(CharityApi::class);
78 | }
79 |
80 | function it_should_provide_chat_api()
81 | {
82 | $this->getChatApi()->shouldBeAnInstanceOf(ChatApi::class);
83 | }
84 |
85 | function it_should_provide_clips_api()
86 | {
87 | $this->getClipsApi()->shouldBeAnInstanceOf(ClipsApi::class);
88 | }
89 |
90 | function it_should_provide_entitlements_api()
91 | {
92 | $this->getEntitlementsApi()->shouldBeAnInstanceOf(EntitlementsApi::class);
93 | }
94 |
95 | function it_should_provide_event_sub_api()
96 | {
97 | $this->getEventSubApi()->shouldBeAnInstanceOf(EventSubApi::class);
98 | }
99 |
100 | function it_should_provide_games_api()
101 | {
102 | $this->getGamesApi()->shouldBeAnInstanceOf(GamesApi::class);
103 | }
104 |
105 | function it_should_provide_goals_api()
106 | {
107 | $this->getGoalsApi()->shouldBeAnInstanceOf(GoalsApi::class);
108 | }
109 |
110 | function it_should_provide_hype_train_api() {
111 | $this->getHypeTrainApi()->shouldBeAnInstanceOf(HypeTrainApi::class);
112 | }
113 |
114 | function it_should_provide_moderation_api()
115 | {
116 | $this->getModerationApi()->shouldBeAnInstanceOf(ModerationApi::class);
117 | }
118 |
119 | function it_should_provide_polls_api()
120 | {
121 | $this->getPollsApi()->shouldBeAnInstanceOf(PollsApi::class);
122 | }
123 |
124 | function it_should_provide_predictions_api()
125 | {
126 | $this->getPredictionsApi()->shouldBeAnInstanceOf(PredictionsApi::class);
127 | }
128 |
129 | function it_should_provide_raids_api()
130 | {
131 | $this->getRaidsApi()->shouldBeAnInstanceOf(RaidsApi::class);
132 | }
133 |
134 | function it_should_provide_schedule_api()
135 | {
136 | $this->getScheduleApi()->shouldBeAnInstanceOf(ScheduleApi::class);
137 | }
138 |
139 | function it_should_provide_search_api()
140 | {
141 | $this->getSearchApi()->shouldBeAnInstanceOf(SearchApi::class);
142 | }
143 |
144 | function it_should_provide_streams_api()
145 | {
146 | $this->getStreamsApi()->shouldBeAnInstanceOf(StreamsApi::class);
147 | }
148 |
149 | function it_should_provide_subscriptions_api()
150 | {
151 | $this->getSubscriptionsApi()->shouldBeAnInstanceOf(SubscriptionsApi::class);
152 | }
153 |
154 | function it_should_provide_tags_api()
155 | {
156 | $this->getTagsApi()->shouldBeAnInstanceOf(TagsApi::class);
157 | }
158 |
159 | function it_should_provide_teams_api()
160 | {
161 | $this->getTeamsApi()->shouldBeAnInstanceOf(TeamsApi::class);
162 | }
163 |
164 | function it_should_provide_users_api()
165 | {
166 | $this->getUsersApi()->shouldBeAnInstanceOf(UsersApi::class);
167 | }
168 |
169 | function it_should_provide_videos_api()
170 | {
171 | $this->getVideosApi()->shouldBeAnInstanceOf(VideosApi::class);
172 | }
173 |
174 | function it_should_provide_webhooks_api()
175 | {
176 | $this->getWebhooksApi()->shouldBeAnInstanceOf(WebhooksApi::class);
177 | }
178 |
179 | function it_should_provide_whispers_api()
180 | {
181 | $this->getWhispersApi()->shouldBeAnInstanceOf(WhispersApi::class);
182 | }
183 |
184 | function it_should_provide_webhooks_subscription_api()
185 | {
186 | $this->getWebhooksSubscriptionApi()->shouldBeAnInstanceOf(WebhooksSubscriptionApi::class);
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/src/Resources/ScheduleApi.php:
--------------------------------------------------------------------------------
1 | 'broadcaster_id', 'value' => $broadcasterId];
21 |
22 | foreach ($ids as $id) {
23 | $queryParamsMap[] = ['key' => 'id', 'value' => $id];
24 | }
25 |
26 | if ($startTime) {
27 | $queryParamsMap[] = ['key' => 'start_time', 'value' => $startTime];
28 | }
29 |
30 | if ($utcOffset) {
31 | $queryParamsMap[] = ['key' => 'utc_offset', 'value' => $utcOffset];
32 | }
33 |
34 | if ($first) {
35 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
36 | }
37 |
38 | if ($after) {
39 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
40 | }
41 |
42 | return $this->getApi('schedule', $bearer, $queryParamsMap);
43 | }
44 |
45 | /**
46 | * @throws GuzzleException
47 | * @link https://dev.twitch.tv/docs/api/reference/#get-channel-icalendar
48 | */
49 | public function getChanneliCalendar(string $bearer = null, string $broadcasterId): ResponseInterface
50 | {
51 | // This endpoint at the time of addition does not require any authorization, so the bearer is null.
52 | // However, to prevent a breaking update in the future, it will remain the first function parameter.
53 | // You may simple pass NULL to this to bypass authentication.
54 |
55 | $queryParamsMap = [];
56 |
57 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
58 |
59 | return $this->getApiWithOptionalAuth('schedule/icalendar', $bearer, $queryParamsMap);
60 | }
61 |
62 | /**
63 | * @throws GuzzleException
64 | * @link https://dev.twitch.tv/docs/api/reference/#update-channel-stream-schedule
65 | */
66 | public function updateChannelStreamSchedule(string $bearer, string $broadcasterId, bool $isVacationEnabled = null, $vacationStartTime = null, $vacationEndTime = null, $timezone = null): ResponseInterface
67 | {
68 | $queryParamsMap = [];
69 |
70 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
71 |
72 | if ($isVacationEnabled) {
73 | $queryParamsMap[] = ['key' => 'is_vacation_enabled', 'value' => $isVacationEnabled];
74 | }
75 |
76 | if ($vacationStartTime) {
77 | $queryParamsMap[] = ['key' => 'vacation_start_time', 'value' => $vacationStartTime];
78 | }
79 |
80 | if ($vacationEndTime) {
81 | $queryParamsMap[] = ['key' => 'vacation_end_time', 'value' => $vacationEndTime];
82 | }
83 |
84 | if ($timezone) {
85 | $queryParamsMap[] = ['key' => 'timezone', 'value' => $timezone];
86 | }
87 |
88 | return $this->patchApi('schedule/settings', $bearer, $queryParamsMap);
89 | }
90 |
91 | /**
92 | * @throws GuzzleException
93 | * @link https://dev.twitch.tv/docs/api/reference/#create-channel-stream-schedule-segment
94 | */
95 | public function createChannelStreamScheduleSegment(string $bearer, string $broadcasterId, string $startTime, string $timezone, bool $isRecurring, array $additionalBodyParams = []): ResponseInterface
96 | {
97 | // $additionalBodyParams should be a standard key => value format, eg. ['duration' => '240'];
98 | $queryParamsMap = $bodyParamsMap = [];
99 |
100 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
101 |
102 | $bodyParamsMap[] = ['key' => 'start_time', 'value' => $startTime];
103 | $bodyParamsMap[] = ['key' => 'timezone', 'value' => $timezone];
104 | $bodyParamsMap[] = ['key' => 'is_recurring', 'value' => $isRecurring];
105 |
106 | foreach ($additionalBodyParams as $key => $value) {
107 | $bodyParamsMap[] = ['key' => $key, 'value' => $value];
108 | }
109 |
110 | return $this->postApi('schedule/segment', $bearer, $queryParamsMap, $bodyParamsMap);
111 | }
112 |
113 | /**
114 | * @throws GuzzleException
115 | * @link https://dev.twitch.tv/docs/api/reference/#update-channel-stream-schedule-segment
116 | */
117 | public function updateChannelStreamScheduleSegment(string $bearer, string $broadcasterId, string $segmentId, array $updateValues = []): ResponseInterface
118 | {
119 | // $updateValues should be a standard key => value format based on the values available on the documentation, eg. ['duration' => '240'];
120 | $queryParamsMap = $bodyParamsMap = [];
121 |
122 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
123 | $queryParamsMap[] = ['key' => 'id', 'value' => $segmentId];
124 |
125 | foreach ($updateValues as $key => $value) {
126 | $bodyParamsMap[] = ['key' => $key, 'value' => $value];
127 | }
128 |
129 | return $this->patchApi('schedule/segment', $bearer, $queryParamsMap, $bodyParamsMap);
130 | }
131 |
132 | /**
133 | * @throws GuzzleException
134 | * @link https://dev.twitch.tv/docs/api/reference/#delete-channel-stream-schedule-segment
135 | */
136 | public function deleteChannelStreamScheduleSegment(string $bearer, string $broadcasterId, string $segmentId): ResponseInterface
137 | {
138 | $queryParamsMap = [];
139 |
140 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
141 | $queryParamsMap[] = ['key' => 'id', 'value' => $segmentId];
142 |
143 | return $this->deleteApi('schedule/segment', $bearer, $queryParamsMap);
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/Resources/UsersApi.php:
--------------------------------------------------------------------------------
1 | getUsers($userAccessToken, [], [], $includeEmail);
18 | }
19 |
20 | /**
21 | * @throws GuzzleException
22 | */
23 | public function getUserById(string $bearer, string $id, bool $includeEmail = false): ResponseInterface
24 | {
25 | return $this->getUsers($bearer, [$id], [], $includeEmail);
26 | }
27 |
28 | /**
29 | * @throws GuzzleException
30 | */
31 | public function getUserByUsername(string $bearer, string $username, bool $includeEmail = false): ResponseInterface
32 | {
33 | return $this->getUsers($bearer, [], [$username], $includeEmail);
34 | }
35 |
36 | /**
37 | * @throws GuzzleException
38 | * @link https://dev.twitch.tv/docs/api/reference/#get-users
39 | */
40 | public function getUsers(string $bearer, array $ids = [], array $usernames = [], bool $includeEmail = false): ResponseInterface
41 | {
42 | $queryParamsMap = [];
43 | foreach ($ids as $id) {
44 | $queryParamsMap[] = ['key' => 'id', 'value' => $id];
45 | }
46 | foreach ($usernames as $username) {
47 | $queryParamsMap[] = ['key' => 'login', 'value' => $username];
48 | }
49 | if ($includeEmail) {
50 | $queryParamsMap[] = ['key' => 'scope', 'value' => 'user:read:email'];
51 | }
52 |
53 | return $this->getApi('users', $bearer, $queryParamsMap);
54 | }
55 |
56 | /**
57 | * @throws GuzzleException
58 | * @link https://dev.twitch.tv/docs/api/reference/#get-users-follows
59 | */
60 | public function getUsersFollows(string $bearer, string $followerId = null, string $followedUserId = null, int $first = null, string $after = null): ResponseInterface
61 | {
62 | $queryParamsMap = [];
63 | if ($followerId) {
64 | $queryParamsMap[] = ['key' => 'from_id', 'value' => $followerId];
65 | }
66 | if ($followedUserId) {
67 | $queryParamsMap[] = ['key' => 'to_id', 'value' => $followedUserId];
68 | }
69 | if ($first) {
70 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
71 | }
72 | if ($after) {
73 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
74 | }
75 |
76 | return $this->getApi('users/follows', $bearer, $queryParamsMap);
77 | }
78 |
79 | /**
80 | * @throws GuzzleException
81 | * @link https://dev.twitch.tv/docs/api/reference/#get-user-extensions
82 | */
83 | public function getUserExtensions(string $bearer): ResponseInterface
84 | {
85 | $queryParamsMap = [];
86 |
87 | return $this->getApi('users/extensions/list', $bearer, $queryParamsMap);
88 | }
89 |
90 | /**
91 | * @throws GuzzleException
92 | * @link https://dev.twitch.tv/docs/api/reference/#get-user-active-extensions
93 | */
94 | public function getActiveUserExtensions(string $bearer, string $userId = null): ResponseInterface
95 | {
96 | $queryParamsMap = [];
97 |
98 | if ($userId) {
99 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
100 | }
101 |
102 | return $this->getApi('users/extensions', $bearer, $queryParamsMap);
103 | }
104 |
105 | /**
106 | * @throws GuzzleException
107 | * @link https://dev.twitch.tv/docs/api/reference#update-user
108 | */
109 | public function updateUser(string $bearer, string $description = null): ResponseInterface
110 | {
111 | $queryParamsMap = [];
112 |
113 | if ($description) {
114 | $queryParamsMap[] = ['key' => 'description', 'value' => $description];
115 | }
116 |
117 | return $this->putApi('users', $bearer, $queryParamsMap);
118 | }
119 |
120 | /**
121 | * @throws GuzzleException
122 | * @link https://dev.twitch.tv/docs/api/reference#get-user-block-list
123 | */
124 | public function getUserBlockList(string $bearer, string $broadcasterId, int $first = null, string $after = null): ResponseInterface
125 | {
126 | $queryParamsMap = [];
127 |
128 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
129 |
130 | if ($first) {
131 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
132 | }
133 | if ($after) {
134 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
135 | }
136 |
137 | return $this->getApi('users/blocks', $bearer, $queryParamsMap);
138 | }
139 |
140 | /**
141 | * @throws GuzzleException
142 | * @link https://dev.twitch.tv/docs/api/reference#block-user
143 | */
144 | public function blockUser(string $bearer, string $targetUserId, string $sourceContext = null, string $reason = null): ResponseInterface
145 | {
146 | $queryParamsMap = [];
147 |
148 | $queryParamsMap[] = ['key' => 'target_user_id', 'value' => $targetUserId];
149 |
150 | if ($sourceContext) {
151 | $queryParamsMap[] = ['key' => 'source_context', 'value' => $sourceContext];
152 | }
153 |
154 | if ($reason) {
155 | $queryParamsMap[] = ['key' => 'reason', 'value' => $reason];
156 | }
157 |
158 | return $this->putApi('users/blocks', $bearer, $queryParamsMap);
159 | }
160 |
161 | /**
162 | * @throws GuzzleException
163 | * @link https://dev.twitch.tv/docs/api/reference#unblock-user
164 | */
165 | public function unblockUser(string $bearer, string $targetUserId): ResponseInterface
166 | {
167 | $queryParamsMap = [];
168 |
169 | $queryParamsMap[] = ['key' => 'target_user_id', 'value' => $targetUserId];
170 |
171 | return $this->deleteApi('users/blocks', $bearer, $queryParamsMap);
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/AnalyticsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_extension_analytics(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'analytics/extensions', 'TEST_TOKEN', [], [])->willReturn($request);
22 | $this->getExtensionAnalytics('TEST_TOKEN')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_extension_analytics_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'analytics/extensions', 'TEST_TOKEN', [['key' => 'extension_id', 'value' => '1']], [])->willReturn($request);
28 | $this->getExtensionAnalytics('TEST_TOKEN', '1')->shouldBe($response);
29 | }
30 |
31 | function it_should_get_extension_analytics_with_type(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'analytics/extensions', 'TEST_TOKEN', [['key' => 'type', 'value' => 'overview_v1']], [])->willReturn($request);
34 | $this->getExtensionAnalytics('TEST_TOKEN', null, 'overview_v1')->shouldBe($response);
35 | }
36 |
37 | function it_should_get_extension_analytics_with_first(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'analytics/extensions', 'TEST_TOKEN', [['key' => 'first', 'value' => '100']], [])->willReturn($request);
40 | $this->getExtensionAnalytics('TEST_TOKEN', null, null, 100)->shouldBe($response);
41 | }
42 |
43 | function it_should_get_extension_analytics_with_after(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('GET', 'analytics/extensions', 'TEST_TOKEN', [['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
46 | $this->getExtensionAnalytics('TEST_TOKEN', null, null, null, 'abc')->shouldBe($response);
47 | }
48 |
49 | function it_should_get_extension_analytics_with_started_at(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('GET', 'analytics/extensions', 'TEST_TOKEN', [['key' => 'started_at', 'value' => '2020-01-01T00:00:00Z']], [])->willReturn($request);
52 | $this->getExtensionAnalytics('TEST_TOKEN', null, null, null, null, '2020-01-01T00:00:00Z')->shouldBe($response);
53 | }
54 |
55 | function it_should_get_extension_analytics_with_ended_at(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $requestGenerator->generate('GET', 'analytics/extensions', 'TEST_TOKEN', [['key' => 'ended_at', 'value' => '2020-01-01T00:00:00Z']], [])->willReturn($request);
58 | $this->getExtensionAnalytics('TEST_TOKEN', null, null, null, null, null, '2020-01-01T00:00:00Z')->shouldBe($response);
59 | }
60 |
61 | function it_should_get_game_analytics(RequestGenerator $requestGenerator, Request $request, Response $response)
62 | {
63 | $requestGenerator->generate('GET', 'analytics/games', 'TEST_TOKEN', [], [])->willReturn($request);
64 | $this->getGameAnalytics('TEST_TOKEN')->shouldBe($response);
65 | }
66 |
67 | function it_should_get_game_analytics_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
68 | {
69 | $requestGenerator->generate('GET', 'analytics/games', 'TEST_TOKEN', [['key' => 'game_id', 'value' => '1']], [])->willReturn($request);
70 | $this->getGameAnalytics('TEST_TOKEN', '1')->shouldBe($response);
71 | }
72 |
73 | function it_should_get_game_analytics_with_type(RequestGenerator $requestGenerator, Request $request, Response $response)
74 | {
75 | $requestGenerator->generate('GET', 'analytics/games', 'TEST_TOKEN', [['key' => 'type', 'value' => 'overview_v1']], [])->willReturn($request);
76 | $this->getGameAnalytics('TEST_TOKEN', null, 'overview_v1')->shouldBe($response);
77 | }
78 |
79 | function it_should_get_game_analytics_with_first(RequestGenerator $requestGenerator, Request $request, Response $response)
80 | {
81 | $requestGenerator->generate('GET', 'analytics/games', 'TEST_TOKEN', [['key' => 'first', 'value' => '100']], [])->willReturn($request);
82 | $this->getGameAnalytics('TEST_TOKEN', null, null, 100)->shouldBe($response);
83 | }
84 |
85 | function it_should_get_game_analytics_with_after(RequestGenerator $requestGenerator, Request $request, Response $response)
86 | {
87 | $requestGenerator->generate('GET', 'analytics/games', 'TEST_TOKEN', [['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
88 | $this->getGameAnalytics('TEST_TOKEN', null, null, null, 'abc')->shouldBe($response);
89 | }
90 |
91 | function it_should_get_game_analytics_with_started_at(RequestGenerator $requestGenerator, Request $request, Response $response)
92 | {
93 | $requestGenerator->generate('GET', 'analytics/games', 'TEST_TOKEN', [['key' => 'started_at', 'value' => '2020-01-01T00:00:00Z']], [])->willReturn($request);
94 | $this->getGameAnalytics('TEST_TOKEN', null, null, null, null, '2020-01-01T00:00:00Z')->shouldBe($response);
95 | }
96 |
97 | function it_should_get_game_analytics_with_ended_at(RequestGenerator $requestGenerator, Request $request, Response $response)
98 | {
99 | $requestGenerator->generate('GET', 'analytics/games', 'TEST_TOKEN', [['key' => 'ended_at', 'value' => '2020-01-01T00:00:00Z']], [])->willReturn($request);
100 | $this->getGameAnalytics('TEST_TOKEN', null, null, null, null, null, '2020-01-01T00:00:00Z')->shouldBe($response);
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/VideosApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_video_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'videos', 'TEST_TOKEN', [['key' => 'id', 'value' => '123']], [])->willReturn($request);
22 | $this->getVideos('TEST_TOKEN', ['123'])->shouldBe($response);
23 | }
24 |
25 | function it_should_get_videos_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'videos', 'TEST_TOKEN', [['key' => 'id', 'value' => '123'], ['key' => 'id', 'value' => '321']], [])->willReturn($request);
28 | $this->getVideos('TEST_TOKEN', ['123', '321'])->shouldBe($response);
29 | }
30 |
31 | function it_should_get_videos_by_user_id(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'videos', 'TEST_TOKEN', [['key' => 'user_id', 'value' => '123']], [])->willReturn($request);
34 | $this->getVideos('TEST_TOKEN', [], '123')->shouldBe($response);
35 | }
36 |
37 | function it_should_get_videos_by_game_id(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'videos', 'TEST_TOKEN', [['key' => 'game_id', 'value' => '123']], [])->willReturn($request);
40 | $this->getVideos('TEST_TOKEN', [], null, '123')->shouldBe($response);
41 | }
42 |
43 | function it_should_get_videos_with_first(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('GET', 'videos', 'TEST_TOKEN', [['key' => 'first', 'value' => 100]], [])->willReturn($request);
46 | $this->getVideos('TEST_TOKEN', [], null, null, 100)->shouldBe($response);
47 | }
48 |
49 | function it_should_get_videos_with_before(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('GET', 'videos', 'TEST_TOKEN', [['key' => 'before', 'value' => 'abc']], [])->willReturn($request);
52 | $this->getVideos('TEST_TOKEN', [], null, null, null, 'abc')->shouldBe($response);
53 | }
54 |
55 | function it_should_get_videos_with_after(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $requestGenerator->generate('GET', 'videos', 'TEST_TOKEN', [['key' => 'after', 'value' => 'cba']], [])->willReturn($request);
58 | $this->getVideos('TEST_TOKEN', [], null, null, null, null, 'cba')->shouldBe($response);
59 | }
60 |
61 | function it_should_get_videos_with_language(RequestGenerator $requestGenerator, Request $request, Response $response)
62 | {
63 | $requestGenerator->generate('GET', 'videos', 'TEST_TOKEN', [['key' => 'language', 'value' => 'en']], [])->willReturn($request);
64 | $this->getVideos('TEST_TOKEN', [], null, null, null, null, null, 'en')->shouldBe($response);
65 | }
66 |
67 | function it_should_get_videos_with_period(RequestGenerator $requestGenerator, Request $request, Response $response)
68 | {
69 | $requestGenerator->generate('GET', 'videos', 'TEST_TOKEN', [['key' => 'period', 'value' => 'all']], [])->willReturn($request);
70 | $this->getVideos('TEST_TOKEN', [], null, null, null, null, null, null, 'all')->shouldBe($response);
71 | }
72 |
73 | function it_should_get_videos_with_sort(RequestGenerator $requestGenerator, Request $request, Response $response)
74 | {
75 | $requestGenerator->generate('GET', 'videos', 'TEST_TOKEN', [['key' => 'sort', 'value' => 'trending']], [])->willReturn($request);
76 | $this->getVideos('TEST_TOKEN', [], null, null, null, null, null, null, null, 'trending')->shouldBe($response);
77 | }
78 |
79 | function it_should_get_videos_with_type(RequestGenerator $requestGenerator, Request $request, Response $response)
80 | {
81 | $requestGenerator->generate('GET', 'videos', 'TEST_TOKEN', [['key' => 'type', 'value' => 'all']], [])->willReturn($request);
82 | $this->getVideos('TEST_TOKEN', [], null, null, null, null, null, null, null, null, 'all')->shouldBe($response);
83 | }
84 |
85 | function it_should_get_videos_with_everything(RequestGenerator $requestGenerator, Request $request, Response $response)
86 | {
87 | $requestGenerator->generate('GET', 'videos', 'TEST_TOKEN', [['key' => 'user_id', 'value' => '123'], ['key' => 'game_id', 'value' => '321'], ['key' => 'first', 'value' => 100], ['key' => 'before', 'value' => 'abc'], ['key' => 'after', 'value' => 'def'], ['key' => 'language', 'value' => 'en'], ['key' => 'period', 'value' => 'all'], ['key' => 'sort', 'value' => 'trending'], ['key' => 'type', 'value' => 'all']], [])->willReturn($request);
88 | $this->getVideos('TEST_TOKEN', [], '123', '321', 100, 'abc', 'def', 'en', 'all', 'trending', 'all')->shouldBe($response);
89 | }
90 |
91 | function it_should_delete_videos(RequestGenerator $requestGenerator, Request $request, Response $response)
92 | {
93 | $requestGenerator->generate('DELETE', 'videos', 'TEST_TOKEN', [['key' => 'id', 'value' => '123']], [])->willReturn($request);
94 | $this->deleteVideos('TEST_TOKEN', ['123'])->shouldBe($response);
95 | }
96 |
97 | function it_should_delete_multiple_videos(RequestGenerator $requestGenerator, Request $request, Response $response)
98 | {
99 | $requestGenerator->generate('DELETE', 'videos', 'TEST_TOKEN', [['key' => 'id', 'value' => '123'], ['key' => 'id', 'value' => '321']], [])->willReturn($request);
100 | $this->deleteVideos('TEST_TOKEN', ['123', '321'])->shouldBe($response);
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/ScheduleApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_channel_stream_schedule(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'schedule', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
22 | $this->getChannelStreamSchedule('TEST_TOKEN', '123')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_channel_stream_schedule_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $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);
28 | $this->getChannelStreamSchedule('TEST_TOKEN', '123', [], '2021-06-15T23:08:20+00:00', '240', 25, 'abc')->shouldBe($response);
29 | }
30 |
31 | function it_should_get_a_channel_stream_schedule(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'schedule', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '456']], [])->willReturn($request);
34 | $this->getChannelStreamSchedule('TEST_TOKEN', '123', ['456'])->shouldBe($response);
35 | }
36 |
37 | function it_should_get_multiple_channel_stream_schedules(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'schedule', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '456'], ['key' => 'id', 'value' => '789']], [])->willReturn($request);
40 | $this->getChannelStreamSchedule('TEST_TOKEN', '123', ['456', '789'])->shouldBe($response);
41 | }
42 |
43 | function it_should_get_channel_icalendar_with_no_auth(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('GET', 'schedule/icalendar', null, [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
46 | $this->getChanneliCalendar(null, '123')->shouldBe($response);
47 | }
48 |
49 | function it_should_get_channel_icalendar_with_auth(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('GET', 'schedule/icalendar', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
52 | $this->getChanneliCalendar('TEST_TOKEN', '123')->shouldBe($response);
53 | }
54 |
55 | function it_should_update_channel_stream_schedule(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $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);
58 | $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);
59 | }
60 |
61 | function it_should_create_channel_stream_schedule_segment(RequestGenerator $requestGenerator, Request $request, Response $response)
62 | {
63 | $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);
64 | $this->createChannelStreamScheduleSegment('TEST_TOKEN', '123', '2021-06-15T23:08:20+00:00', 'America/New_York', true)->shouldBe($response);
65 | }
66 |
67 | function it_should_create_channel_stream_schedule_segment_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
68 | {
69 | $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);
70 | $this->createChannelStreamScheduleSegment('TEST_TOKEN', '123', '2021-06-15T23:08:20+00:00', 'America/New_York', true, ['duration' => '240'])->shouldBe($response);
71 | }
72 |
73 | function it_should_update_channel_stream_schedule_segment(RequestGenerator $requestGenerator, Request $request, Response $response)
74 | {
75 | $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);
76 | $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);
77 | }
78 |
79 | function it_should_delete_channel_stream_schedule_segment(RequestGenerator $requestGenerator, Request $request, Response $response)
80 | {
81 | $requestGenerator->generate('DELETE', 'schedule/segment', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'id', 'value' => '456']], [])->willReturn($request);
82 | $this->deleteChannelStreamScheduleSegment('TEST_TOKEN', '123', '456')->shouldBe($response);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/EntitlementsApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_create_entitlement_grants_upload_url(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('POST', 'entitlements/upload', 'TEST_TOKEN', [['key' => 'manifest_id', 'value' => '123'], ['key' => 'type', 'value' => 'bulk_drops_grant']], [])->willReturn($request);
22 | $this->createEntitlementGrantsUploadURL('TEST_TOKEN', '123', 'bulk_drops_grant')->shouldBe($response);
23 | }
24 |
25 | function it_should_create_entitlement_grants_upload_url_shorthand(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('POST', 'entitlements/upload', 'TEST_TOKEN', [['key' => 'manifest_id', 'value' => '123'], ['key' => 'type', 'value' => 'bulk_drops_grant']], [])->willReturn($request);
28 | $this->createEntitlementGrantsUploadURL('TEST_TOKEN', '123')->shouldBe($response);
29 | }
30 |
31 | function it_should_get_code_status(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'entitlements/codes', 'TEST_TOKEN', [['key' => 'user_id', 'value' => '123'], ['key' => 'code', 'value' => 'abc']], [])->willReturn($request);
34 | $this->getCodeStatus('TEST_TOKEN', '123', ['abc'])->shouldBe($response);
35 | }
36 |
37 | function it_should_get_codes_status(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'entitlements/codes', 'TEST_TOKEN', [['key' => 'user_id', 'value' => '123'], ['key' => 'code', 'value' => 'abc'], ['key' => 'code', 'value' => 'def']], [])->willReturn($request);
40 | $this->getCodeStatus('TEST_TOKEN', '123', ['abc', 'def'])->shouldBe($response);
41 | }
42 |
43 | function it_should_get_drop_entitlements_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('GET', 'entitlements/drops', 'TEST_TOKEN', [['key' => 'id', 'value' => '123']], [])->willReturn($request);
46 | $this->getDropsEntitlements('TEST_TOKEN', '123')->shouldBe($response);
47 | }
48 |
49 | function it_should_get_drop_entitlements_by_user_id(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('GET', 'entitlements/drops', 'TEST_TOKEN', [['key' => 'user_id', 'value' => '123']], [])->willReturn($request);
52 | $this->getDropsEntitlements('TEST_TOKEN', null, '123')->shouldBe($response);
53 | }
54 |
55 | function it_should_get_drop_entitlements_by_user_id_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $requestGenerator->generate('GET', 'entitlements/drops', 'TEST_TOKEN', [['key' => 'user_id', 'value' => '123'], ['key' => 'after', 'value' => 'abc'], ['key' => 'first', 'value' => 100]], [])->willReturn($request);
58 | $this->getDropsEntitlements('TEST_TOKEN', null, '123', null, 'abc', 100)->shouldBe($response);
59 | }
60 |
61 | function it_should_get_drop_entitlements_by_game_id(RequestGenerator $requestGenerator, Request $request, Response $response)
62 | {
63 | $requestGenerator->generate('GET', 'entitlements/drops', 'TEST_TOKEN', [['key' => 'game_id', 'value' => '123']], [])->willReturn($request);
64 | $this->getDropsEntitlements('TEST_TOKEN', null, null, '123')->shouldBe($response);
65 | }
66 |
67 | function it_should_get_drop_entitlements_by_game_id_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
68 | {
69 | $requestGenerator->generate('GET', 'entitlements/drops', 'TEST_TOKEN', [['key' => 'game_id', 'value' => '123'], ['key' => 'after', 'value' => 'abc'], ['key' => 'first', 'value' => 100]], [])->willReturn($request);
70 | $this->getDropsEntitlements('TEST_TOKEN', null, null, '123', 'abc', 100)->shouldBe($response);
71 | }
72 |
73 | function it_should_get_drop_entitlements_by_status(RequestGenerator $requestGenerator, Request $request, Response $response)
74 | {
75 | $requestGenerator->generate('GET', 'entitlements/drops', 'TEST_TOKEN', [['key' => 'fulfillment_status', 'value' => 'CLAIMED']], [])->willReturn($request);
76 | $this->getDropsEntitlements('TEST_TOKEN', null, null, null, null, null, 'CLAIMED')->shouldBe($response);
77 | }
78 |
79 | function it_should_redeem_code(RequestGenerator $requestGenerator, Request $request, Response $response)
80 | {
81 | $requestGenerator->generate('POST', 'entitlements/code', 'TEST_TOKEN', [['key' => 'user_id', 'value' => '123'], ['key' => 'code', 'value' => 'abc']], [])->willReturn($request);
82 | $this->redeemCode('TEST_TOKEN', '123', ['abc'])->shouldBe($response);
83 | }
84 |
85 | function it_should_redeem_codes(RequestGenerator $requestGenerator, Request $request, Response $response)
86 | {
87 | $requestGenerator->generate('POST', 'entitlements/code', 'TEST_TOKEN', [['key' => 'user_id', 'value' => '123'], ['key' => 'code', 'value' => 'abc'], ['key' => 'code', 'value' => 'def']], [])->willReturn($request);
88 | $this->redeemCode('TEST_TOKEN', '123', ['abc', 'def'])->shouldBe($response);
89 | }
90 |
91 | function it_should_update_drop_entitlements(RequestGenerator $requestGenerator, Request $request, Response $response)
92 | {
93 | $requestGenerator->generate('PATCH', 'entitlements/drops', 'TEST_TOKEN', [], [])->willReturn($request);
94 | $this->updateDropsEntitlements('TEST_TOKEN')->shouldBe($response);
95 | }
96 |
97 | function it_should_update_one_drop_entitlements(RequestGenerator $requestGenerator, Request $request, Response $response)
98 | {
99 | $requestGenerator->generate('PATCH', 'entitlements/drops', 'TEST_TOKEN', [], [['key' => 'entitlement_ids', 'value' => ['123']], ['key' => 'fulfillment_status', 'value' => 'FULFILLED']])->willReturn($request);
100 | $this->updateDropsEntitlements('TEST_TOKEN', ['123'], 'FULFILLED')->shouldBe($response);
101 | }
102 |
103 | function it_should_update_multiple_drop_entitlements(RequestGenerator $requestGenerator, Request $request, Response $response)
104 | {
105 | $requestGenerator->generate('PATCH', 'entitlements/drops', 'TEST_TOKEN', [], [['key' => 'entitlement_ids', 'value' => ['123', '456']], ['key' => 'fulfillment_status', 'value' => 'FULFILLED']])->willReturn($request);
106 | $this->updateDropsEntitlements('TEST_TOKEN', ['123', '456'], 'FULFILLED')->shouldBe($response);
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/Resources/ChatApi.php:
--------------------------------------------------------------------------------
1 | 'broadcaster_id', 'value' => $broadcasterId];
20 |
21 | return $this->getApi('chat/emotes', $bearer, $queryParamsMap);
22 | }
23 |
24 | /**
25 | * @throws GuzzleException
26 | * @link https://dev.twitch.tv/docs/api/reference#get-global-emotes
27 | */
28 | public function getGlobalEmotes(string $bearer): ResponseInterface
29 | {
30 | return $this->getApi('chat/emotes/global', $bearer);
31 | }
32 |
33 | /**
34 | * @throws GuzzleException
35 | * @link https://dev.twitch.tv/docs/api/reference#get-emote-sets
36 | */
37 | public function getEmoteSets(string $bearer, array $emoteSetIds = []): ResponseInterface
38 | {
39 | $queryParamsMap = [];
40 |
41 | foreach ($emoteSetIds as $emoteSetId) {
42 | $queryParamsMap[] = ['key' => 'emote_set_id', 'value' => $emoteSetId];
43 | }
44 |
45 | return $this->getApi('chat/emotes/set', $bearer, $queryParamsMap);
46 | }
47 |
48 | public function getEmoteSet(string $bearer, string $emoteSetId): ResponseInterface
49 | {
50 | $queryParamsMap = [];
51 | $queryParamsMap[] = ['key' => 'emote_set_id', 'value' => $emoteSetId];
52 |
53 | return $this->getApi('chat/emotes/set', $bearer, $queryParamsMap);
54 | }
55 |
56 | /**
57 | * @throws GuzzleException
58 | * @link https://dev.twitch.tv/docs/api/reference#get-channel-chat-badges
59 | */
60 | public function getChannelChatBadges(string $bearer, string $broadcasterId): ResponseInterface
61 | {
62 | $queryParamsMap = [];
63 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
64 |
65 | return $this->getApi('chat/badges', $bearer, $queryParamsMap);
66 | }
67 |
68 | /**
69 | * @throws GuzzleException
70 | * @link https://dev.twitch.tv/docs/api/reference#get-global-chat-badges
71 | */
72 | public function getGlobalChatBadges(string $bearer): ResponseInterface
73 | {
74 | return $this->getApi('chat/badges/global', $bearer);
75 | }
76 |
77 | /**
78 | * @throws GuzzleException
79 | * @link https://dev.twitch.tv/docs/api/reference#get-chat-settings
80 | */
81 | public function getChatSettings(string $bearer, string $broadcasterId, string $moderatorId = null): ResponseInterface
82 | {
83 | $queryParamsMap = [];
84 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
85 |
86 | if ($moderatorId) {
87 | $queryParamsMap[] = ['key' => 'moderator_id', 'value' => $moderatorId];
88 | }
89 |
90 | return $this->getApi('chat/settings', $bearer, $queryParamsMap);
91 | }
92 |
93 | /**
94 | * @throws GuzzleException
95 | * @link https://dev.twitch.tv/docs/api/reference#update-chat-settings
96 | */
97 | public function updateChatSettings(string $bearer, string $broadcasterId, string $moderatorId, array $chatSettings): ResponseInterface
98 | {
99 | $queryParamsMap = $bodyParamsMap = [];
100 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
101 |
102 | $queryParamsMap[] = ['key' => 'moderator_id', 'value' => $moderatorId];
103 |
104 | foreach ($chatSettings as $key => $value) {
105 | $bodyParamsMap[] = ['key' => $key, 'value' => $value];
106 | }
107 |
108 | return $this->patchApi('chat/settings', $bearer, $queryParamsMap, $bodyParamsMap);
109 | }
110 |
111 | /**
112 | * @throws GuzzleException
113 | * @link https://dev.twitch.tv/docs/api/reference#send-chat-announcement
114 | */
115 | public function sendChatAnnouncement(string $bearer, string $broadcasterId, string $moderatorId, string $message, string $color = null): ResponseInterface
116 | {
117 | $queryParamsMap = $bodyParamsMap = [];
118 |
119 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
120 |
121 | $queryParamsMap[] = ['key' => 'moderator_id', 'value' => $moderatorId];
122 |
123 | $bodyParamsMap[] = ['key' => 'message', 'value' => $message];
124 |
125 | if ($color) {
126 | $bodyParamsMap[] = ['key' => 'color', 'value' => $color];
127 | }
128 |
129 | return $this->postApi('chat/announcements', $bearer, $queryParamsMap, $bodyParamsMap);
130 | }
131 |
132 | /**
133 | * @throws GuzzleException
134 | * @link https://dev.twitch.tv/docs/api/reference#get-user-chat-color
135 | */
136 | public function getUserChatColor(string $bearer, string $userId): ResponseInterface
137 | {
138 | $queryParamsMap = [];
139 |
140 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
141 |
142 | return $this->getApi('chat/color', $bearer, $queryParamsMap);
143 | }
144 |
145 | /**
146 | * @throws GuzzleException
147 | * @link https://dev.twitch.tv/docs/api/reference#update-user-chat-color
148 | */
149 | public function updateUserChatColor(string $bearer, string $userId, string $color): ResponseInterface
150 | {
151 | $queryParamsMap = [];
152 |
153 | $queryParamsMap[] = ['key' => 'user_id', 'value' => $userId];
154 |
155 | $queryParamsMap[] = ['key' => 'color', 'value' => $color];
156 |
157 | return $this->putApi('chat/color', $bearer, $queryParamsMap);
158 | }
159 |
160 | /**
161 | * @throws GuzzleException
162 | * @link https://dev.twitch.tv/docs/api/reference#get-chatters
163 | */
164 | public function getChatters(string $bearer, string $broadcasterId, string $moderatorId, int $first = null, string $after = null): ResponseInterface
165 | {
166 | $queryParamsMap = [];
167 |
168 | $queryParamsMap[] = ['key' => 'broadcaster_id', 'value' => $broadcasterId];
169 |
170 | $queryParamsMap[] = ['key' => 'moderator_id', 'value' => $moderatorId];
171 |
172 | if ($first) {
173 | $queryParamsMap[] = ['key' => 'first', 'value' => $first];
174 | }
175 |
176 | if ($after) {
177 | $queryParamsMap[] = ['key' => 'after', 'value' => $after];
178 | }
179 |
180 | return $this->getApi('chat/chatters', $bearer, $queryParamsMap);
181 | }
182 |
183 | /**
184 | * @throws GuzzleException
185 | * @link https://dev.twitch.tv/docs/api/reference/#send-a-shoutout
186 | */
187 | public function sendShoutout(string $bearer, string $fromBroadcasterId, string $toBroadcasterId, string $moderatorId): ResponseInterface
188 | {
189 | $queryParamsMap = [];
190 |
191 | $queryParamsMap[] = ['key' => 'from_broadcaster_id', 'value' => $fromBroadcasterId];
192 |
193 | $queryParamsMap[] = ['key' => 'to_broadcaster_id', 'value' => $toBroadcasterId];
194 |
195 | $queryParamsMap[] = ['key' => 'moderator_id', 'value' => $moderatorId];
196 |
197 | return $this->postApi('chat/shoutouts', $bearer, $queryParamsMap);
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/ChatApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_channel_emotes(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'chat/emotes', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
22 | $this->getChannelEmotes('TEST_TOKEN', '123')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_global_emotes(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'chat/emotes/global', 'TEST_TOKEN', [], [])->willReturn($request);
28 | $this->getGlobalEmotes('TEST_TOKEN')->shouldBe($response);
29 | }
30 |
31 | function it_should_get_one_emote_set(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'chat/emotes/set', 'TEST_TOKEN', [['key' => 'emote_set_id', 'value' => '123']], [])->willReturn($request);
34 | $this->getEmoteSets('TEST_TOKEN', ['123'])->shouldBe($response);
35 | }
36 |
37 | function it_should_get_one_emote_set_with_helper_function(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'chat/emotes/set', 'TEST_TOKEN', [['key' => 'emote_set_id', 'value' => '123']], [])->willReturn($request);
40 | $this->getEmoteSet('TEST_TOKEN', '123')->shouldBe($response);
41 | }
42 |
43 | function it_should_get_multiple_emote_sets(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('GET', 'chat/emotes/set', 'TEST_TOKEN', [['key' => 'emote_set_id', 'value' => '123'], ['key' => 'emote_set_id', 'value' => '456']], [])->willReturn($request);
46 | $this->getEmoteSets('TEST_TOKEN', ['123', '456'])->shouldBe($response);
47 | }
48 |
49 | function it_should_get_channel_chat_badges(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('GET', 'chat/badges', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
52 | $this->getChannelChatBadges('TEST_TOKEN', '123')->shouldBe($response);
53 | }
54 |
55 | function it_should_get_global_chat_badges(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $requestGenerator->generate('GET', 'chat/badges/global', 'TEST_TOKEN', [], [])->willReturn($request);
58 | $this->getGlobalChatBadges('TEST_TOKEN')->shouldBe($response);
59 | }
60 |
61 | function it_should_get_chat_settings(RequestGenerator $requestGenerator, Request $request, Response $response)
62 | {
63 | $requestGenerator->generate('GET', 'chat/settings', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
64 | $this->getChatSettings('TEST_TOKEN', '123')->shouldBe($response);
65 | }
66 |
67 | function it_should_get_chat_settings_with_moderator_id(RequestGenerator $requestGenerator, Request $request, Response $response)
68 | {
69 | $requestGenerator->generate('GET', 'chat/settings', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'moderator_id', 'value' => '456']], [])->willReturn($request);
70 | $this->getChatSettings('TEST_TOKEN', '123', '456')->shouldBe($response);
71 | }
72 |
73 | function it_should_update_chat_settings_with_one_setting(RequestGenerator $requestGenerator, Request $request, Response $response)
74 | {
75 | $requestGenerator->generate('PATCH', 'chat/settings', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'moderator_id', 'value' => '456']], [['key' => 'emote_mode', 'value' => true]])->willReturn($request);
76 | $this->updateChatSettings('TEST_TOKEN', '123', '456', ['emote_mode' => true])->shouldBe($response);
77 | }
78 |
79 | function it_should_update_chat_settings_with_multiple_settings(RequestGenerator $requestGenerator, Request $request, Response $response)
80 | {
81 | $requestGenerator->generate('PATCH', 'chat/settings', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'moderator_id', 'value' => '456']], [['key' => 'emote_mode', 'value' => true], ['key' => 'slow_mode_wait_time', 'value' => 10]])->willReturn($request);
82 | $this->updateChatSettings('TEST_TOKEN', '123', '456', ['emote_mode' => true, 'slow_mode_wait_time' => 10])->shouldBe($response);
83 | }
84 |
85 | function it_should_send_a_chat_announcement(RequestGenerator $requestGenerator, Request $request, Response $response)
86 | {
87 | $requestGenerator->generate('POST', 'chat/announcements', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'moderator_id', 'value' => '456']], [['key' => 'message', 'value' => 'Hello World']])->willReturn($request);
88 | $this->sendChatAnnouncement('TEST_TOKEN', '123', '456', 'Hello World')->shouldBe($response);
89 | }
90 |
91 | function it_should_send_a_chat_announcement_with_a_color(RequestGenerator $requestGenerator, Request $request, Response $response)
92 | {
93 | $requestGenerator->generate('POST', 'chat/announcements', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'moderator_id', 'value' => '456']], [['key' => 'message', 'value' => 'Hello World'], ['key' => 'color', 'value' => 'red']])->willReturn($request);
94 | $this->sendChatAnnouncement('TEST_TOKEN', '123', '456', 'Hello World', 'red')->shouldBe($response);
95 | }
96 |
97 | function it_should_get_a_users_chat_color(RequestGenerator $requestGenerator, Request $request, Response $response)
98 | {
99 | $requestGenerator->generate('GET', 'chat/color', 'TEST_TOKEN', [['key' => 'user_id', 'value' => '123']], [])->willReturn($request);
100 | $this->getUserChatColor('TEST_TOKEN', '123')->shouldBe($response);
101 | }
102 |
103 | function it_should_update_a_users_chat_color(RequestGenerator $requestGenerator, Request $request, Response $response)
104 | {
105 | $requestGenerator->generate('PUT', 'chat/color', 'TEST_TOKEN', [['key' => 'user_id', 'value' => '123'], ['key' => 'color', 'value' => 'red']], [])->willReturn($request);
106 | $this->updateUserChatColor('TEST_TOKEN', '123', 'red')->shouldBe($response);
107 | }
108 |
109 | function it_should_get_chatters(RequestGenerator $requestGenerator, Request $request, Response $response)
110 | {
111 | $requestGenerator->generate('GET', 'chat/chatters', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'moderator_id', 'value' => '456']], [])->willReturn($request);
112 | $this->getChatters('TEST_TOKEN', '123', '456')->shouldBe($response);
113 | }
114 |
115 | function it_should_get_chatters_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
116 | {
117 | $requestGenerator->generate('GET', 'chat/chatters', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'moderator_id', 'value' => '456'],['key' => 'first', 'value' => 100], ['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
118 | $this->getChatters('TEST_TOKEN', '123', '456', 100, 'abc')->shouldBe($response);
119 | }
120 |
121 | function it_should_send_a_shoutout(RequestGenerator $requestGenerator, Request $request, Response $response)
122 | {
123 | $requestGenerator->generate('POST', 'chat/shoutouts', 'TEST_TOKEN', [['key' => 'from_broadcaster_id', 'value' => '123'], ['key' => 'to_broadcaster_id', 'value' => '456'], ['key' => 'moderator_id', 'value' => '789']], [])->willReturn($request);
124 | $this->sendShoutout('TEST_TOKEN', '123', '456', '789')->shouldBe($response);
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/TwitchApi.php:
--------------------------------------------------------------------------------
1 | oauthApi = new OauthApi($clientId, $clientSecret, $authGuzzleClient);
74 | $this->adsApi = new AdsApi($helixGuzzleClient, $requestGenerator);
75 | $this->analyticsApi = new AnalyticsApi($helixGuzzleClient, $requestGenerator);
76 | $this->bitsApi = new BitsApi($helixGuzzleClient, $requestGenerator);
77 | $this->channelPointsApi = new ChannelPointsApi($helixGuzzleClient, $requestGenerator);
78 | $this->channelsApi = new ChannelsApi($helixGuzzleClient, $requestGenerator);
79 | $this->charityApi = new CharityApi($helixGuzzleClient, $requestGenerator);
80 | $this->chatApi = new ChatApi($helixGuzzleClient, $requestGenerator);
81 | $this->clipsApi = new ClipsApi($helixGuzzleClient, $requestGenerator);
82 | $this->entitlementsApi = new EntitlementsApi($helixGuzzleClient, $requestGenerator);
83 | $this->eventSubApi = new EventSubApi($helixGuzzleClient, $requestGenerator);
84 | $this->gamesApi = new GamesApi($helixGuzzleClient, $requestGenerator);
85 | $this->goalsApi = new GoalsApi($helixGuzzleClient, $requestGenerator);
86 | $this->hypeTrainApi = new HypeTrainApi($helixGuzzleClient, $requestGenerator);
87 | $this->moderationApi = new ModerationApi($helixGuzzleClient, $requestGenerator);
88 | $this->pollsApi = new PollsApi($helixGuzzleClient, $requestGenerator);
89 | $this->predictionsApi = new PredictionsApi($helixGuzzleClient, $requestGenerator);
90 | $this->raidsApi = new RaidsApi($helixGuzzleClient, $requestGenerator);
91 | $this->scheduleApi = new ScheduleApi($helixGuzzleClient, $requestGenerator);
92 | $this->searchApi = new SearchApi($helixGuzzleClient, $requestGenerator);
93 | $this->streamsApi = new StreamsApi($helixGuzzleClient, $requestGenerator);
94 | $this->subscriptionsApi = new SubscriptionsApi($helixGuzzleClient, $requestGenerator);
95 | $this->tagsApi = new TagsApi($helixGuzzleClient, $requestGenerator);
96 | $this->teamsApi = new TeamsApi($helixGuzzleClient, $requestGenerator);
97 | $this->usersApi = new UsersApi($helixGuzzleClient, $requestGenerator);
98 | $this->videosApi = new VideosApi($helixGuzzleClient, $requestGenerator);
99 | $this->webhooksApi = new WebhooksApi($helixGuzzleClient, $requestGenerator);
100 | $this->whispersApi = new WhispersApi($helixGuzzleClient, $requestGenerator);
101 | $this->webhooksSubscriptionApi = new WebhooksSubscriptionApi($clientId, $clientSecret, $helixGuzzleClient);
102 | }
103 |
104 | public function getOauthApi(): OauthApi
105 | {
106 | return $this->oauthApi;
107 | }
108 |
109 | public function getAdsApi(): AdsApi
110 | {
111 | return $this->adsApi;
112 | }
113 |
114 | public function getAnalyticsApi(): AnalyticsApi
115 | {
116 | return $this->analyticsApi;
117 | }
118 |
119 | public function getBitsApi(): BitsApi
120 | {
121 | return $this->bitsApi;
122 | }
123 |
124 | public function getChannelPointsApi(): ChannelPointsApi
125 | {
126 | return $this->channelPointsApi;
127 | }
128 |
129 | public function getChannelsApi(): ChannelsApi
130 | {
131 | return $this->channelsApi;
132 | }
133 |
134 | public function getCharityApi(): CharityApi
135 | {
136 | return $this->charityApi;
137 | }
138 |
139 | public function getChatApi(): ChatApi
140 | {
141 | return $this->chatApi;
142 | }
143 |
144 | public function getClipsApi(): ClipsApi
145 | {
146 | return $this->clipsApi;
147 | }
148 |
149 | public function getEntitlementsApi(): EntitlementsApi
150 | {
151 | return $this->entitlementsApi;
152 | }
153 |
154 | public function getEventSubApi(): EventSubApi
155 | {
156 | return $this->eventSubApi;
157 | }
158 |
159 | public function getGamesApi(): GamesApi
160 | {
161 | return $this->gamesApi;
162 | }
163 |
164 | public function getGoalsApi(): GoalsApi
165 | {
166 | return $this->goalsApi;
167 | }
168 |
169 | public function getHypeTrainApi(): HypeTrainApi
170 | {
171 | return $this->hypeTrainApi;
172 | }
173 |
174 | public function getModerationApi(): ModerationApi
175 | {
176 | return $this->moderationApi;
177 | }
178 |
179 | public function getPollsApi(): PollsApi
180 | {
181 | return $this->pollsApi;
182 | }
183 |
184 | public function getPredictionsApi(): PredictionsApi
185 | {
186 | return $this->predictionsApi;
187 | }
188 |
189 | public function getRaidsApi(): RaidsApi
190 | {
191 | return $this->raidsApi;
192 | }
193 |
194 | public function getScheduleApi(): ScheduleApi
195 | {
196 | return $this->scheduleApi;
197 | }
198 |
199 | public function getSearchApi(): SearchApi
200 | {
201 | return $this->searchApi;
202 | }
203 |
204 | public function getStreamsApi(): StreamsApi
205 | {
206 | return $this->streamsApi;
207 | }
208 |
209 | public function getSubscriptionsApi(): SubscriptionsApi
210 | {
211 | return $this->subscriptionsApi;
212 | }
213 |
214 | public function getTagsApi(): TagsApi
215 | {
216 | return $this->tagsApi;
217 | }
218 |
219 | public function getTeamsApi(): TeamsApi
220 | {
221 | return $this->teamsApi;
222 | }
223 |
224 | public function getUsersApi(): UsersApi
225 | {
226 | return $this->usersApi;
227 | }
228 |
229 | public function getVideosApi(): VideosApi
230 | {
231 | return $this->videosApi;
232 | }
233 |
234 | public function getWebhooksApi(): WebhooksApi
235 | {
236 | return $this->webhooksApi;
237 | }
238 |
239 | public function getWhispersApi(): WhispersApi
240 | {
241 | return $this->whispersApi;
242 | }
243 |
244 | public function getWebhooksSubscriptionApi(): WebhooksSubscriptionApi
245 | {
246 | return $this->webhooksSubscriptionApi;
247 | }
248 | }
249 |
--------------------------------------------------------------------------------
/spec/TwitchApi/Resources/UsersApiSpec.php:
--------------------------------------------------------------------------------
1 | beConstructedWith($guzzleClient, $requestGenerator);
16 | $guzzleClient->send($request)->willReturn($response);
17 | }
18 |
19 | function it_should_get_user_with_access_token(RequestGenerator $requestGenerator, Request $request, Response $response)
20 | {
21 | $requestGenerator->generate('GET', 'users', 'TEST_TOKEN', [], [])->willReturn($request);
22 | $this->getUsers('TEST_TOKEN')->shouldBe($response);
23 | }
24 |
25 | function it_should_get_user_with_access_token_convenience_method(RequestGenerator $requestGenerator, Request $request, Response $response)
26 | {
27 | $requestGenerator->generate('GET', 'users', 'TEST_TOKEN', [], [])->willReturn($request);
28 | $this->getUserByAccessToken('TEST_TOKEN')->shouldBe($response);
29 | }
30 |
31 | function it_should_get_users_by_ids(RequestGenerator $requestGenerator, Request $request, Response $response)
32 | {
33 | $requestGenerator->generate('GET', 'users', 'TEST_TOKEN', [['key' => 'id', 'value' => '12345'], ['key' => 'id', 'value' => '98765']], [])->willReturn($request);
34 | $this->getUsers('TEST_TOKEN', ['12345', '98765'])->shouldBe($response);
35 | }
36 |
37 | function it_should_get_users_by_usernames(RequestGenerator $requestGenerator, Request $request, Response $response)
38 | {
39 | $requestGenerator->generate('GET', 'users', 'TEST_TOKEN', [['key' => 'login', 'value' => 'twitchuser'], ['key' => 'login', 'value' => 'anotheruser']], [])->willReturn($request);
40 | $this->getUsers('TEST_TOKEN', [], ['twitchuser', 'anotheruser'])->shouldBe($response);
41 | }
42 |
43 | function it_should_get_users_by_id_and_username(RequestGenerator $requestGenerator, Request $request, Response $response)
44 | {
45 | $requestGenerator->generate('GET', 'users', 'TEST_TOKEN', [['key' => 'id', 'value' => '12345'], ['key' => 'id', 'value' => '98765'], ['key' => 'login', 'value' => 'twitchuser'], ['key' => 'login', 'value' => 'anotheruser']], [])->willReturn($request);
46 | $this->getUsers('TEST_TOKEN', ['12345', '98765'], ['twitchuser', 'anotheruser'])->shouldBe($response);
47 | }
48 |
49 | function it_should_get_a_single_user_by_id(RequestGenerator $requestGenerator, Request $request, Response $response)
50 | {
51 | $requestGenerator->generate('GET', 'users', 'TEST_TOKEN', [['key' => 'id', 'value' => '12345']], [])->willReturn($request);
52 | $this->getUserById('TEST_TOKEN', '12345')->shouldBe($response);
53 | }
54 |
55 | function it_should_get_a_single_user_by_username(RequestGenerator $requestGenerator, Request $request, Response $response)
56 | {
57 | $requestGenerator->generate('GET', 'users', 'TEST_TOKEN', [['key' => 'login', 'value' => 'twitchuser']], [])->willReturn($request);
58 | $this->getUserByUsername('TEST_TOKEN', 'twitchuser')->shouldBe($response);
59 | }
60 |
61 | function it_should_get_users_follows_by_follower_id(RequestGenerator $requestGenerator, Request $request, Response $response)
62 | {
63 | $requestGenerator->generate('GET', 'users/follows', 'TEST_TOKEN', [['key' => 'from_id', 'value' => '12345']], [])->willReturn($request);
64 | $this->getUsersFollows('TEST_TOKEN', '12345')->shouldBe($response);
65 | }
66 |
67 | function it_should_get_users_follows_by_followed_id(RequestGenerator $requestGenerator, Request $request, Response $response)
68 | {
69 | $requestGenerator->generate('GET', 'users/follows', 'TEST_TOKEN', [['key' => 'to_id', 'value' => '12345']], [])->willReturn($request);
70 | $this->getUsersFollows('TEST_TOKEN', null, '12345')->shouldBe($response);
71 | }
72 |
73 | function it_should_get_users_follows_by_follower_id_and_followed_id(RequestGenerator $requestGenerator, Request $request, Response $response)
74 | {
75 | $requestGenerator->generate('GET', 'users/follows', 'TEST_TOKEN', [['key' => 'from_id', 'value' => '12345'], ['key' => 'to_id', 'value' => '98765']], [])->willReturn($request);
76 | $this->getUsersFollows('TEST_TOKEN', '12345', '98765')->shouldBe($response);
77 | }
78 |
79 | function it_should_get_users_follows_page_by_first(RequestGenerator $requestGenerator, Request $request, Response $response)
80 | {
81 | $requestGenerator->generate('GET', 'users/follows', 'TEST_TOKEN', [['key' => 'first', 'value' => 42]], [])->willReturn($request);
82 | $this->getUsersFollows('TEST_TOKEN', null, null, 42)->shouldBe($response);
83 | }
84 |
85 | function it_should_get_users_follows_page_by_after(RequestGenerator $requestGenerator, Request $request, Response $response)
86 | {
87 | $requestGenerator->generate('GET', 'users/follows', 'TEST_TOKEN', [['key' => 'after', 'value' => '42']], [])->willReturn($request);
88 | $this->getUsersFollows('TEST_TOKEN', null, null, null, '42')->shouldBe($response);
89 | }
90 |
91 | function it_should_get_users_follows_by_everything(RequestGenerator $requestGenerator, Request $request, Response $response)
92 | {
93 | $requestGenerator->generate('GET', 'users/follows', 'TEST_TOKEN', [['key' => 'from_id', 'value' => '12345'], ['key' => 'to_id', 'value' => '98765'], ['key' => 'first', 'value' => 42], ['key' => 'after', 'value' => '99']], [])->willReturn($request);
94 | $this->getUsersFollows('TEST_TOKEN', '12345', '98765', 42, '99')->shouldBe($response);
95 | }
96 |
97 | function it_should_update_user(RequestGenerator $requestGenerator, Request $request, Response $response)
98 | {
99 | $requestGenerator->generate('PUT', 'users', 'TEST_TOKEN', [], [])->willReturn($request);
100 | $this->updateUser('TEST_TOKEN')->shouldBe($response);
101 | }
102 |
103 | function it_should_update_user_description(RequestGenerator $requestGenerator, Request $request, Response $response)
104 | {
105 | $requestGenerator->generate('PUT', 'users', 'TEST_TOKEN', [['key' => 'description', 'value' => 'test']], [])->willReturn($request);
106 | $this->updateUser('TEST_TOKEN', 'test')->shouldBe($response);
107 | }
108 |
109 | function it_should_get_user_block_list(RequestGenerator $requestGenerator, Request $request, Response $response)
110 | {
111 | $requestGenerator->generate('GET', 'users/blocks', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123']], [])->willReturn($request);
112 | $this->getUserBlockList('TEST_TOKEN', '123')->shouldBe($response);
113 | }
114 |
115 | function it_should_get_user_block_list_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
116 | {
117 | $requestGenerator->generate('GET', 'users/blocks', 'TEST_TOKEN', [['key' => 'broadcaster_id', 'value' => '123'], ['key' => 'first', 'value' => 100], ['key' => 'after', 'value' => 'abc']], [])->willReturn($request);
118 | $this->getUserBlockList('TEST_TOKEN', '123', 100, 'abc')->shouldBe($response);
119 | }
120 |
121 | function it_should_block_user(RequestGenerator $requestGenerator, Request $request, Response $response)
122 | {
123 | $requestGenerator->generate('PUT', 'users/blocks', 'TEST_TOKEN', [['key' => 'target_user_id', 'value' => '123']], [])->willReturn($request);
124 | $this->blockUser('TEST_TOKEN', '123')->shouldBe($response);
125 | }
126 |
127 | function it_should_block_user_with_opts(RequestGenerator $requestGenerator, Request $request, Response $response)
128 | {
129 | $requestGenerator->generate('PUT', 'users/blocks', 'TEST_TOKEN', [['key' => 'target_user_id', 'value' => '123'], ['key' => 'source_context', 'value' => 'chat'], ['key' => 'reason', 'value' => 'spam']], [])->willReturn($request);
130 | $this->blockUser('TEST_TOKEN', '123', 'chat', 'spam')->shouldBe($response);
131 | }
132 |
133 | function it_should_unblock_user(RequestGenerator $requestGenerator, Request $request, Response $response)
134 | {
135 | $requestGenerator->generate('DELETE', 'users/blocks', 'TEST_TOKEN', [['key' => 'target_user_id', 'value' => '123']], [])->willReturn($request);
136 | $this->unblockUser('TEST_TOKEN', '123')->shouldBe($response);
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Twitch API PHP Library
2 |
3 | 
4 | 
5 | 
6 | 
7 |
8 | The Twitch API PHP Library allows you to interact through HTTP to a number of [Twitch API](https://dev.twitch.tv/docs/api/) endpoints. The library does not format the repsonses of your request so you have full flexability in how to handle the data that is returned from the API.
9 |
10 | ## Documentation & Links
11 |
12 | - [Twitch API Documentation](https://dev.twitch.tv/docs/api/)
13 | - [TwitchDev Discord](https://link.twitch.tv/devchat)
14 | - [Twitch API Community Discord](https://discord.gg/PKE8cPA3zb)
15 |
16 | ## Getting Started
17 |
18 | ### Requirements
19 |
20 | - PHP 7.4 - The library has been shown to work on earlier versions but we encourage you to use the latest versions of PHP that are tested with our library. - The requirement will be increased to PHP 8.0 in the future, so you should develop for the latest version of PHP.
21 | - Composer
22 | - `ext-json: *`
23 | - [guzzlehttp/guzzle](https://github.com/guzzle/guzzle) `~6.0|~7.0`
24 |
25 | ### Installation
26 |
27 | The recommended way to install the Twitch API PHP Library is through [Composer](https://getcomposer.org/).
28 |
29 | ```bash
30 | composer require nicklaw5/twitch-api-php
31 |
32 | ```
33 |
34 | ### Example Usage
35 |
36 | All calls to the Twitch API require bearer tokens that can be retrieved through the `OauthApi` class. You can review the [types of tokens](https://dev.twitch.tv/docs/authentication/#types-of-tokens) in the Twitch API docs. The below examples store the Client ID, Secret and Scopes directly in the example, but you should not do this. Store your IDs, Secret, and Scopes in a secure place such as your database or environment variables or alternate settings storage. Security of this information is important. Here is an example of how you can retrieve a token for your application:
37 |
38 | ```php
39 | $twitch_client_id = 'TWITCH_CLIENT_ID';
40 | $twitch_client_secret = 'TWITCH_CLIENT_SECRET';
41 | $twitch_scopes = '';
42 |
43 | $helixGuzzleClient = new \TwitchApi\HelixGuzzleClient($twitch_client_id);
44 | $twitchApi = new \TwitchApi\TwitchApi($helixGuzzleClient, $twitch_client_id, $twitch_client_secret);
45 | $oauth = $twitchApi->getOauthApi();
46 |
47 | try {
48 | $token = $oauth->getAppAccessToken($twitch_scopes ?? '');
49 | $data = json_decode($token->getBody()->getContents());
50 |
51 | // Your bearer token
52 | $twitch_access_token = $data->access_token ?? null;
53 | } catch (Exception $e) {
54 | //TODO: Handle Error
55 | }
56 | ```
57 |
58 | Here is an example of how you retrieve a users token:
59 |
60 | ```php
61 | $twitch_client_id = 'TWITCH_CLIENT_ID';
62 | $twitch_client_secret = 'TWITCH_CLIENT_SECRET';
63 | $twitch_scopes = '';
64 |
65 | $helixGuzzleClient = new \TwitchApi\HelixGuzzleClient($twitch_client_id);
66 | $twitchApi = new \TwitchApi\TwitchApi($helixGuzzleClient, $twitch_client_id, $twitch_client_secret);
67 | $oauth = $twitchApi->getOauthApi();
68 |
69 | // Get the code from URI
70 | $code = $_GET['code'];
71 |
72 | // Get the current URL, we'll use this to redirect them back to exactly where they came from
73 | $currentUri = explode('?', 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'])[0];
74 |
75 | if ($code == '') {
76 | // Generate the Oauth Uri
77 | $oauthUri = $oauth->getAuthUrl($currentUri, 'code', $twitch_scopes);
78 | // Redirect them as there was no auth code
79 | header("Location: {$oauthUri}");
80 | } else {
81 | try {
82 | $token = $oauth->getUserAccessToken($code, $currentUri);
83 | // It is a good practice to check the status code when they've responded, this really is optional though
84 | if ($token->getStatusCode() == 200) {
85 | // Below is the returned token data
86 | $data = json_decode($token->getBody()->getContents());
87 |
88 | // Your bearer token
89 | $twitch_access_token = $data->access_token ?? null;
90 | } else {
91 | //TODO: Handle Error
92 | }
93 | } catch (Exception $e) {
94 | //TODO: Handle Error
95 | }
96 | }
97 | ```
98 |
99 | When you have a user token that is expired, you're able to refresh it instead of requiring them to authenticate again. Here is an example of how you refresh a users token:
100 |
101 | ```php
102 | $twitch_client_id = 'TWITCH_CLIENT_ID';
103 | $twitch_client_secret = 'TWITCH_CLIENT_SECRET';
104 | $twitch_scopes = '';
105 | $user_refresh_token = 'REFRESH_TOKEN';
106 |
107 | $helixGuzzleClient = new \TwitchApi\HelixGuzzleClient($twitch_client_id);
108 | $twitchApi = new \TwitchApi\TwitchApi($helixGuzzleClient, $twitch_client_id, $twitch_client_secret);
109 | $oauth = $twitchApi->getOauthApi();
110 |
111 | try {
112 | $token = $oauth->getAppAccessToken($twitch_scopes ?? '');
113 | $data = json_decode($token->getBody()->getContents());
114 |
115 | // Your bearer token
116 | $twitch_access_token = $data->access_token ?? null;
117 |
118 | // The scopes from the API
119 | $twitch_scopes = $data->scope;
120 | } catch (Exception $e) {
121 | //TODO: Handle Error
122 | }
123 | ```
124 |
125 | ### Usage of the API Classes
126 |
127 | Everything stems from the `TwitchApi` class. However, if you want to individually instantiate `UsersApi`, `OauthApi`, etc. you are free to do so.
128 |
129 | The API calls generally return an object implementing `ResponseInterface`. Since you are getting the full `Response` object, you'll need to handle its contents, e.g. by decoding then into an object with `json_decode()`. This library does not assume this is what you want to do, so it does not do this for you automatically. This library simply acts as a middleman between your code and Twitch, providing you with the raw responses the Twitch API returns.
130 |
131 | The individual API classes that can be called from `TwitchApi` correspond to the [Twitch API documentation](https://dev.twitch.tv/docs/api/). The rest of the API classes are based on the resources listed [here](https://dev.twitch.tv/docs/api/reference/). The methods in the classes generally correspond to the endpoints for each resource. The naming convention was chosen to try and match the Twitch documentation. Each primary endpoint method (not convenience or helper methods) should have an `@link` annotation with a URL to that endpoint's specific documentation.
132 |
133 | Here is a sample of retrieving a users table from their access token:
134 |
135 | ```php
136 | $twitch_client_id = 'TWITCH_CLIENT_ID';
137 | $twitch_client_secret = 'TWITCH_CLIENT_SECRET';
138 | // Assuming you already have the access token - see above
139 | $twitch_access_token = 'the token';
140 |
141 | // The Guzzle client used can be the included `HelixGuzzleClient` class, for convenience.
142 | // You can also use a mock, fake, or other double for testing, of course.
143 | $helixGuzzleClient = new \TwitchApi\HelixGuzzleClient($twitch_client_id);
144 |
145 | // Instantiate TwitchApi. Can be done in a service layer and injected as well.
146 | $twitchApi = new TwitchApi($helixGuzzleClient, $twitch_client_id, $twitch_client_secret);
147 |
148 | try {
149 | // Make the API call. A ResponseInterface object is returned.
150 | $response = $twitchApi->getUsersApi()->getUserByAccessToken($twitch_access_token);
151 |
152 | // Get and decode the actual content sent by Twitch.
153 | $responseContent = json_decode($response->getBody()->getContents());
154 |
155 | // Return the first (or only) user.
156 | return $responseContent->data[0];
157 | } catch (GuzzleException $e) {
158 | //TODO: Handle Error
159 | }
160 | ```
161 |
162 | ## Developer Tools
163 |
164 | ### PHP Coding Standards Fixer
165 |
166 | [PHP Coding Standards Fixer](https://cs.sensiolabs.org/) (`php-cs-fixer`) has been added, specifically for the New Twitch API code. A configuration file for it can be found in `.php_cs.dist`. The ruleset is left at default (PSR-2 at this time). The configuration file mostly just limits it's scope to only the New Twitch API code.
167 |
168 | You can run the fixer with `vendor/bin/php-cs-fixer fix`. However, the easiest way to run the fixer is with the provided git hook.
169 |
170 | ### Git pre-commit Hook
171 |
172 | In `bin/git/hooks`, you'll find a `pre-commit` hook that you can add to git that will automatically run the `php-cs-fixer` everytime you commit. The result is that, after the commit is made, any changes that fixer has made are left as unstaged changes. You can review them, then add and commit them.
173 |
174 | To install the hook, go to `.git/hooks` and `ln -s ../../bin/git/hooks/pre-commit`.
175 |
176 | ## License
177 |
178 | Distributed under the [MIT](LICENSE) license.
179 |
--------------------------------------------------------------------------------