romanzipp/laravel-twitch

Twitch PHP Wrapper for Laravel

Fund package maintenance!
romanzipp

4.3.1 2021-10-13 09:19 UTC

README

Latest Stable Version Total Downloads License GitHub Build Status

PHP Twitch Helix API Wrapper for Laravel 5+

⚠️ Changes on May 01, 2020

Since May 01, 2020, Twitch requires all requests to contain a valid OAuth Access Token. This can be achieved by requesting an OAuth Token using the Client Credentials Flow.

If you don't handle this by yourself, be sure to enable the built-in Access Token generation feature via the oauth_client_credentials.auto_generate configuration entry.

You will need define a valid Client ID and Client Secret via your config or the available setters! See the full config for more details.

Table of contents

  1. Installation
  2. Configuration
  3. Examples
  4. Documentation
  5. Upgrading
  6. Development

Installation

composer require romanzipp/laravel-twitch

Configuration

Copy configuration to project:

php artisan vendor:publish --provider="romanzipp\Twitch\Providers\TwitchServiceProvider"

Add environmental variables to your .env:

TWITCH_HELIX_KEY=
TWITCH_HELIX_SECRET=
TWITCH_HELIX_REDIRECT_URI=http://localhost

If you want to use the EventSub with the Webhook transport, then you are required to define a secret. This secret is a string between 10 and 100 characters.

TWITCH_HELIX_EVENTSUB_SECRET=

Examples

Basic

$twitch = new romanzipp\Twitch\Twitch;

$twitch->setClientId('abc123');

// Get User by Username
$result = $twitch->getUsers(['login' => 'herrausragend']);

// Check, if the query was successful
if ( ! $result->success()) {
    return null;
}

// Shift result to get single user data
$user = $result->shift();

return $user->id;

Setters

$twitch = new romanzipp\Twitch\Twitch;

$twitch->setClientId('abc123');
$twitch->setClientSecret('abc456');
$twitch->setToken('abcdef123456');

$twitch = $twitch->withClientId('abc123');
$twitch = $twitch->withClientSecret('abc123');
$twitch = $twitch->withToken('abcdef123456');

OAuth Tokens

$twitch = new romanzipp\Twitch\Twitch;

$twitch->setClientId('abc123');
$twitch->setToken('abcdef123456');

$result = $twitch->getUsers(['login' => 'herrausragend']);

OAuth Client Credentials Flow

Since May 01, 2020, every request requires an OAuth token which can be issued using the OAuth Client Credentials Flow.

use romanzipp\Twitch\Enums\GrantType;
use romanzipp\Twitch\Twitch;

$twitch = new Twitch;

$twitch->setClientId('abc123');
$twitch->setClientSecret('def123');
$twitch->setToken('abcdef123456');

$result = $twitch->getOAuthToken(null, GrantType::CLIENT_CREDENTIALS, ['user:read']);

if ( ! $result->success()) {
    return;
}

$accessToken = $result->data()->access_token;

Pagination

The Twitch API returns a paginator field with paginated results like /streams, /followsor /games. To jump between pages, the given cursor must be appended to the following query using the direction attributes after or before.

In this example, we will fetch a set of streams and use the provided cursor to switch to the next/previous set of data.

❗️ To prevent infinite loops or errors, use the Result::hasMoreResults() method to check if there are more results available.

$twitch = new romanzipp\Twitch\Twitch;

// Page 1
$firstResult = $twitch->getStreams(['language' => 'de']);

// Page 2
$secondResult = $twitch->getStreams(['language' => 'de'], $firstResult->next());

// Page 1 (again)
$thirdResult = $twitch->getStreams(['language' => 'de'], $secondResult->back());

Facade

use romanzipp\Twitch\Facades\Twitch;

Twitch::withClientId('abc123')->withToken('abcdef123456')->getUsers();

Pagination Loop Example

This example fetches all Twitch Games and stores them into a database.

use romanzipp\Twitch\Twitch;

$twitch = new Twitch;

do {
    $nextCursor = null;

    // If this is not the first iteration, get the page cursor to the next set of results
    if (isset($result)) {
        $nextCursor = $result->next();
    }

    // Query the API with an optional cursor to the next results page
    $result = $twitch->getTopGames(['first' => 100], $nextCursor);

    foreach ($result->data() as $item) {
        // Process the games result data
    }

    // Continue until there are no results left
} while ($result->hasMoreResults());

Insert user objects

The new API does not include the user objects in endpoints like followers or bits.

[
  {
    "from_id": "123456",
    "to_id": "654321",
    "followed_at": "2018-01-01 12:00:00"
  }
]

You can just call the insertUsers method to insert all user data identified by from_id into from_user

use romanzipp\Twitch\Twitch;

$twitch = new Twitch;

$result = $twitch->getUsersFollows(['to_id' => 654321]);

$result->insertUsers($twitch, 'from_id', 'from_user');

New Result data:

[
  {
    "from_id": "123456",
    "to_id": "654321",
    "followed_at": "2018-01-01 12:00:00",
    "from_user": {
      "id": "123456",
      "display_name": "HerrAusragend",
      "login": "herrausragend"
    }
  }
]

Defining EventSub Handlers

By default, the EventSub webhook controller will automatically handle all EventSub notification and revocation calls; however, if you have additional webhook events you would like to handle, you may do so by extending the EventSub webhook controller.

To ensure your application can handle EventSub webhooks, be sure to configure the webhook callback url in the transport payload.

Your controller's method names should correspond to Laravel Twitch's controller conventions. Specifically, methods should be prefixed with handle, suffixed with Notification and the "camel case" name of the EventSub Type you wish to handle. For example, if you wish to handle the channel.follow type, you should add a handleChannelFollowNotification method to the controller:

<?php

namespace App\Http\Controllers;

use romanzipp\Twitch\Http\Controllers\EventSubController as BaseController;
use Symfony\Component\HttpFoundation\Response;

class EventSubController extends BaseController
{
    public function handleChannelFollowNotification(array $payload): Response
    {
        return $this->successMethod(); // handle the channel follow notification...
    }

    protected function handleNotification(array $payload): Response
    {
        return $this->successMethod(); // handle all other incoming notifications...
    }

    protected function handleRevocation(array $payload): Response
    {
        return $this->successMethod(); // handle the subscription revocation...
    }
}

Next, define a route to your EventSub webhook controller within your application's routes/api.php file.

use App\Http\Controllers\EventSubController;

Route::post(
    'twitch/eventsub/webhook',
    [EventSubController::class, 'handleWebhook']
);

Create EventSub Subscription

Important: When creating a subscription, you must specify a secret for purposes of verification, described above in “Configuration”. This secret is automatically attached to the webhook transport if it is not explicitly defined.

use romanzipp\Twitch\Enums\EventSubType;
use romanzipp\Twitch\Twitch;

$twitch = new Twitch;


$twitch->subscribeEventSub([], [
    'type' => EventSubType::STREAM_ONLINE,
    'version' => '1',
    'condition' => [
        'broadcaster_user_id' => '1337',
    ],
    'transport' => [
        'method' => 'webhook',
        'callback' => 'https://example.com/api/twitch/eventsub/webhook',
    ]
]);

List EventSub Subscription

use romanzipp\Twitch\Twitch;

$twitch = new Twitch;

$result = $twitch->getEventSubs(['status' => 'notification_failures_exceeded']);

foreach ($result->data() as $item) {
    // process the subscription
}

Delete EventSub Subscription

use romanzipp\Twitch\Twitch;

$twitch = new Twitch;

$twitch->unsubscribeEventSub([
    'id' => '932b34ad-821a-490f-af43-b327187d0f5c'
]);

Documentation

Twitch Helix API Documentation: https://dev.twitch.tv/docs/api/reference

OAuth

public function getOAuthAuthorizeUrl(string $responseType = 'code', array $scopes = [], ?string $state = NULL, bool $forceVerify = false)
public function getOAuthToken(?string $code = NULL, string $grantType = 'authorization_code', array $scopes = [])

Ads

public function startCommercial(array $parameters = [])

Analytics

public function getExtensionAnalytics(array $parameters = [])
public function getGameAnalytics(array $parameters = [])

Bits

public function getCheermotes(array $parameters = [])
public function getBitsLeaderboard(array $parameters = [])
public function getExtensionTransactions(array $parameters = [])

ChannelPoints

public function createCustomRewards(array $parameters = [], array $body = [])
public function deleteCustomReward(array $parameters = [])
public function getCustomReward(array $parameters = [])
public function getCustomRewardRedemption(array $parameters = [], ?Paginator $paginator = NULL)
public function updateCustomReward(array $parameters = [])
public function updateRedemptionStatus(array $parameters = [], array $body = [])

Chat

public function getChannelChatEmotes(array $parameters = [])
public function getGlobalChatEmotes()
public function getChatEmoteSets(array $parameters = [])
public function getChannelChatBadges(array $parameters = [])
public function getGlobalChatBadges()

Clips

public function createClip(array $parameters = [])
public function getClips(array $parameters = [])

Entitlements

public function createEntitlementUrl(array $parameters = [])
public function getEntitlementsCodeStatus(array $parameters = [])
public function getDropsEntitlements(array $parameters = [])
public function redeemEntitlementsCode(array $parameters = [])

EventSub

public function subscribeEventSub(array $parameters = [], array $body = [])
public function unsubscribeEventSub(array $parameters = [])
public function getEventSubs(array $parameters = [], ?Paginator $paginator = NULL)

Extensions

public function getAuthedUserExtensions()
public function getAuthedUserActiveExtensions()
public function disableAllExtensions()
public function disableUserExtensionById(?string $parameter = NULL)
public function disableUserExtensionByName(?string $parameter = NULL)
public function updateUserExtensions(?string $method = NULL, ?string $parameter = NULL, bool $disabled = false)

Games

public function getTopGames(array $parameters = [], ?Paginator $paginator = NULL)
public function getGames(array $parameters = [])

HypeTrain

public function getHypeTrainEvents(array $parameters = [])

Polls

public function getPolls(array $parameters = [], ?Paginator $paginator = NULL)
public function createPoll(array $parameters = [], array $body = [])
public function endPoll(array $parameters = [], array $body = [])

Predictions

public function getPredictions(array $parameters = [], ?Paginator $paginator = NULL)
public function createPrediction(array $parameters = [], array $body = [])
public function endPrediction(array $parameters = [], array $body = [])

Search

public function searchCategories(array $parameters = [])
public function searchChannels(array $parameters = [])

Streams

public function getStreamKey(array $parameters = [])
public function getStreams(array $parameters = [], ?Paginator $paginator = NULL)
public function getFollowedStreams(array $parameters = [], ?Paginator $paginator = NULL)
public function createStreamMarker(array $parameters = [], array $body = [])
public function getStreamMarkers(array $parameters = [], ?Paginator $paginator = NULL)
public function getChannels(array $parameters = [])
public function updateChannels(array $parameters = [], array $body = [])

Users

public function createUserFollows(array $parameters = [], array $body = [])
public function deleteUserFollows(array $parameters = [])
public function getUsers(array $parameters = [])
public function getUsersFollows(array $parameters = [], ?Paginator $paginator = NULL)
public function updateUser(array $parameters = [])
public function getUserExtensions(array $parameters = [])
public function getUserActiveExtensions(array $parameters = [])
public function updateUserExtension(array $parameters = [], array $body = [])

Videos

public function getVideos(array $parameters = [], ?Paginator $paginator = NULL)

Subscriptions

public function getSubscriptions(array $parameters = [], ?Paginator $paginator = NULL)
public function getUserSubscription(array $parameters = [])

Tags

public function getStreamTags(array $parameters = [])
public function getAllStreamTags(array $parameters = [], ?Paginator $paginator = NULL)
public function replaceStreamTags(array $parameters = [], array $body = [])

Moderation

public function checkAutoModStatus(array $parameters = [], array $body = [])
public function getBannedUsers(array $parameters = [], ?Paginator $paginator = NULL)
public function getBannedEvents(array $parameters = [], ?Paginator $paginator = NULL)
public function getModerators(array $parameters = [], ?Paginator $paginator = NULL)
public function getModeratorEvents(array $parameters = [], ?Paginator $paginator = NULL)

Webhooks

public function getWebhookSubscriptions(array $parameters = [])
public function subscribeWebhook(array $parameters = [], array $body = [])
public function unsubscribeWebhook(array $parameters = [], array $body = [])
public function buildWebhookTopic(string $path, array $parameters = [])

OAuth Scopes Enums

Upgrading

Development

Run Tests

composer test
CLIENT_ID=xxxx composer test
CLIENT_ID=xxxx CLIENT_SECRET=xxxx composer test

Generate Documentation

composer docs

Join the Twitch Dev Discord!

Discord

Discord