Code Monkey home page Code Monkey logo

laravel-twitch's People

Contributors

alanaktion avatar bjornar97 avatar bluetidepro avatar derpierre65 avatar dherran avatar dimzeta avatar erwinweber96 avatar ghostzero avatar katzen48 avatar kurir avatar romanmartushev avatar romanzipp avatar simivar avatar thedeadcode avatar tylerfiekens avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

laravel-twitch's Issues

bug

image
I already wrote that eventsub is not confirmed. It turned out that secret is not transmitted

GuzzleHttp\Psr7\Response Error

Hi, I'm getting this error when I try to use the functions in the examples:

Argument 1 passed to romanzipp\Twitch\Result::__construct() must be an instance of GuzzleHttp\Psr7\Response, null given, called in ...\vendor\romanzipp\laravel-twitch\src\Twitch.php on line 258

composer show -i
beyondcode/laravel-dump-server        1.2.2    Symfony Var-Dump Server for Laravel
dnoegel/php-xdg-base-dir              0.1      implementation of xdg base directory specification for php
doctrine/inflector                    v1.3.0   Common String Manipulations with regard to casing and singular/plural ru...
doctrine/instantiator                 1.1.0    A small, lightweight utility to instantiate objects in PHP without invok...
doctrine/lexer                        v1.0.1   Base library for a lexer that can be used in Top-Down, Recursive Descent...
dragonmantank/cron-expression         v2.2.0   CRON for PHP: Calculate the next or previous run date and determine if a...
egulias/email-validator               2.1.6    A library for validating emails against several RFCs
erusev/parsedown                      1.7.1    Parser for Markdown.
fideloper/proxy                       4.0.0    Set trusted proxies for Laravel
filp/whoops                           2.2.1    php error handling for cool kids
fzaninotto/faker                      v1.8.0   Faker is a PHP library that generates fake data for you.
guzzlehttp/guzzle                     6.3.3    Guzzle is a PHP HTTP client library
guzzlehttp/promises                   v1.3.1   Guzzle promises library
guzzlehttp/psr7                       1.4.2    PSR-7 message implementation that also provides common utility methods
hamcrest/hamcrest-php                 v2.0.0   This is the PHP port of Hamcrest Matchers
jakub-onderka/php-console-color       v0.2
jakub-onderka/php-console-highlighter v0.3.2
laravel/framework                     v5.7.8   The Laravel Framework.
laravel/tinker                        v1.0.7   Powerful REPL for the Laravel framework.
league/flysystem                      1.0.46   Filesystem abstraction: Many filesystems, one API.
mockery/mockery                       1.2.0    Mockery is a simple yet flexible PHP mock object framework
monolog/monolog                       1.23.0   Sends your logs to files, sockets, inboxes, databases and various web se...
myclabs/deep-copy                     1.8.1    Create deep copies (clones) of your objects
nesbot/carbon                         1.34.0   A simple API extension for DateTime.
nikic/php-parser                      v4.0.4   A PHP parser written in PHP
nunomaduro/collision                  v2.1.0   Cli error handling for console/command-line PHP applications.
opis/closure                          3.1.1    A library that can be used to serialize closures (anonymous functions) a...
paragonie/random_compat               v9.99.99 PHP 5.x polyfill for random_bytes() and random_int() from PHP 7
phar-io/manifest                      1.0.3    Component for reading phar.io manifest information from a PHP Archive (P...
phar-io/version                       2.0.1    Library for handling version information and constraints
phpdocumentor/reflection-common       1.0.1    Common reflection classes used by phpdocumentor to reflect the code stru...
phpdocumentor/reflection-docblock     4.3.0    With this component, a library can provide support for annotations via D...
phpdocumentor/type-resolver           0.4.0
phpspec/prophecy                      1.8.0    Highly opinionated mocking framework for PHP 5.3+
phpunit/php-code-coverage             6.0.8    Library that provides collection, processing, and rendering functionalit...
phpunit/php-file-iterator             2.0.2    FilterIterator implementation that filters files based on a list of suff...
phpunit/php-text-template             1.2.1    Simple template engine.
phpunit/php-timer                     2.0.0    Utility class for timing
phpunit/php-token-stream              3.0.0    Wrapper around PHP's tokenizer extension.
phpunit/phpunit                       7.4.0    The PHP Unit Testing framework.
psr/container                         1.0.0    Common Container Interface (PHP FIG PSR-11)
psr/http-message                      1.0.1    Common interface for HTTP messages
psr/log                               1.0.2    Common interface for logging libraries
psr/simple-cache                      1.0.1    Common interfaces for simple caching
psy/psysh                             v0.9.8   An interactive shell for modern PHP.
ramsey/uuid                           3.8.0    Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 versio...
romanzipp/laravel-twitch              1.0.18   Twitch PHP Wrapper for Laravel
sebastian/code-unit-reverse-lookup    1.0.1    Looks up which function or method a line of code belongs to
sebastian/comparator                  3.0.2    Provides the functionality to compare PHP values for equality
sebastian/diff                        3.0.1    Diff implementation
sebastian/environment                 3.1.0    Provides functionality to handle HHVM/PHP environments
sebastian/exporter                    3.1.0    Provides the functionality to export PHP variables for visualization
sebastian/global-state                2.0.0    Snapshotting of global state
sebastian/object-enumerator           3.0.3    Traverses array structures and object graphs to enumerate all referenced...
sebastian/object-reflector            1.1.1    Allows reflection of object attributes, including inherited and non-publ...
sebastian/recursion-context           3.0.0    Provides functionality to recursively process PHP variables
sebastian/resource-operations         2.0.1    Provides a list of PHP built-in functions that operate on resources
sebastian/version                     2.0.1    Library that helps with managing the version number of Git-hosted PHP pr...
swiftmailer/swiftmailer               v6.1.3   Swiftmailer, free feature-rich PHP mailer
symfony/console                       v4.1.6   Symfony Console Component
symfony/css-selector                  v4.1.6   Symfony CssSelector Component
symfony/debug                         v4.1.6   Symfony Debug Component
symfony/event-dispatcher              v4.1.6   Symfony EventDispatcher Component
symfony/finder                        v4.1.6   Symfony Finder Component
symfony/http-foundation               v4.1.6   Symfony HttpFoundation Component
symfony/http-kernel                   v4.1.6   Symfony HttpKernel Component
symfony/polyfill-ctype                v1.9.0   Symfony polyfill for ctype functions
symfony/polyfill-mbstring             v1.9.0   Symfony polyfill for the Mbstring extension
symfony/polyfill-php72                v1.9.0   Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions
symfony/process                       v4.1.6   Symfony Process Component
symfony/routing                       v4.1.6   Symfony Routing Component
symfony/translation                   v4.1.6   Symfony Translation Component
symfony/var-dumper                    v4.1.6   Symfony mechanism for exploring and dumping PHP variables
theseer/tokenizer                     1.1.0    A small library for converting tokenized PHP source code into XML and po...
tijsverkoyen/css-to-inline-styles     2.2.1    CssToInlineStyles is a class that enables you to convert HTML-pages/file...
vlucas/phpdotenv                      v2.5.1   Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SE...
webmozart/assert                      1.3.0    Assertions to validate method input/output with nice error messages.

Unable to extract timestamp and signatures from header

Hey guys,

I'm trying to use this package to check if a user has subscribed to a channel.

To test Eventsub, I did an endpoint to subscribe to receive the event when the Twitch channel get a new follower:

$payload = [
    'type' => 'channel.follow',
    'version' => '1',
    'condition' => [
        'broadcaster_user_id' => '12826', // twitch
    ],
    'transport' => [
        'method' => 'webhook',
        'callback' => config('app.url') . '/v1/twitch/eventsub/webhook',
    ]
];

$result = $twitch->subscribeEventSub([], $payload);

dd($result);

When Twitch calls my webhook /v1/twitch/eventsub/webhook, these are the headers I get (I replaced sensitive informations just in case):

Connection: upgrade
Content-Length: 420
Content-Type: application/json
Host: example.com:443
Twitch-Eventsub-Message-Id: sdfsdf-sdff-1234-1234-1234azer1234
Twitch-Eventsub-Message-Retry: 0
Twitch-Eventsub-Message-Signature: sha256=sdujfgdssdfgkjdhgldfgfdg
Twitch-Eventsub-Message-Timestamp: 2021-03-19T23:51:24.637747359Z
Twitch-Eventsub-Message-Type: webhook_callback_verification
Twitch-Eventsub-Subscription-Type: channel.follow
Twitch-Eventsub-Subscription-Version: 1
Upgrade-Insecure-Requests: 1
User-Agent: Go-http-client/1.1
X-Expose-Request-Id: 999999fe299db
X-Exposed-By: Expose unreleased
X-Forwarded-For: 12.34.56.78
X-Forwarded-Proto: https
X-Original-Host: example.com

And here is the error I have, from romanzipp\Twitch\Objects\EventSubSignature:

Unable to extract timestamp and signatures from header

romanzipp\Twitch\Exceptions\SignatureVerificationException: Unable to extract timestamp and signatures from header in /laravel/vendor/romanzipp/laravel-twitch/src/Objects/EventSubSignature.php:28

It seems Twitch-Eventsub-Message-Timestamp is no longer a timestamp but a date with nanoseconds.

Maybe I don't use the package correctly, feel free to correct me if necessary.

If not, please could you fix that?

Thank you!

Add documentation default parameters

Example

- public function getStreamsByUserId(int $id, array $parameters, Paginator $paginator)
+ public function getStreamsByUserId(int $id, array $parameters = [], Paginator $paginator = null)

How to realize a login?

I plan to login via Twitch.

I have a login view.

    public function login()
    {
        return view('auth.login', [
            'authorize_url' => $this->twitch->getOAuthAuthorizeUrl($responseType = 'code')
        ]);
    }

I can get the code.

    public function callback(Request $request)
    {
        Log::info($request->code);
    }

But how do I get the information like email address, Twitch username & Twitch-ID from this user?

Error when polling lots of streams

When I try to poll streams using the getStreams() method, after iterating over about 40.000 results I get the following error

image

I added a logger to debug the response and this is what I got:
[2020-05-07T16:16:40.964227+00:00] guzzle-log.NOTICE: RESPONSE: NULL NULL cURL error 0: The cURL request was retried 3 times and did not succeed. The most likely reason for the failure is that cURL was unable to rewind the body of the request and subsequent retries resulted in the same error. Turn on the debug option to see what went wrong. See https://bugs.php.net/bug.php?id=47204 for more information. (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) - NULL - NULL [] []

Format: RESPONSE: {code} {phrase} {error} - {res_headers} - {res_body}

Question: Cache Driver

Why do we have to define a cache driver? It is already defined in the store configuration.

/*
 * The cache driver to use for storing Client Credentials.
 */
'cache_driver' => null,

Tolerance

The time zone in laravel is specified in Moscow, in" tolerance " it is specified in 180,but the question is what should be specified in minutes or in seconds?

Undefined property: stdClass::$cursor

Sometimes I've got an error in this row of code
$result = $twitch->getStreams($params, isset($result) ? $result->next() : null);

Undefined property: stdClass::$cursor

A getAppToken() method is missing

Hi there,
I can't find a way to get an App Token with the package. I think this method in romanzipp\Twitch\Trait\OAuthTrait could be useful to do that :

public function getAppToken(array $scopes = []): Result
    {
        $parameters = [
            'client_id'     => $this->getClientId(),
            'client_secret' => $this->getClientSecret($scopes),
            'grant_type'    => "client_credentials",
            'scope'         => $this->buildScopes($scopes)
        ];

        return $this->post(self::OAUTH_BASE_URI . 'token', $parameters);
    }

I'm referring with https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/#oauth-client-credentials-flow

OAuth authorization `force_verify` not working

In OAuth Authorizations there's a field to specify if you want to force user verification, as Twitch docs says:

Specifies whether the user should be re-prompted for authorization. If this is true, the user always is prompted to confirm authorization. This is useful to allow your users to switch Twitch accounts, since there is no way to log users out of the API. Default: false (a given user sees the authorization page for a given set of scopes only the first time through the sequence).

This is not working propertly as PHP is converting the "true" and "false" values to the integers 1 and 0 and what Twitch expects are values as the strings true or false.

Error while running the composer install (memory limit)

Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/local/bin/composer/src/Composer/DependencyResolver
/RuleWatchGraph.php on line 52

So after running:
composer require romanzipp/laravel-twitch

I had a memory limit error and I ran this line to fix it:
COMPOSER_MEMORY_LIMIT=-1 composer require huddledigital/zendesk-laravel

Intial setup question

Laravel 8.83.14
romanzipp/laravel-twitch 4.4

Getting a Invalid content type response from Twitch CLI

twitch event verify-subscription subscribe -F http://localhost:8000/webhooks/twitch/eventsub/ -s 5f1a6e7cd2e7137ccf9e15b2f43fe63949eb84b1db83c1d5a867dc93429de4e4

โœ” Valid response. Received challenge 52c24de5-e8fb-1d6a-e52e-a8c787670fff in body
โœ— Invalid content-type header. Received type text/html with charset UTF-8. Expecting text/plain.
โœ” Valid status code. Received status 200

After revising the code to a manual response, all pass.

โœ” Valid response. Received challenge a9298bcd-e8bf-0327-dc0b-e24d3bfc3171 in body
โœ” Valid content-type header. Received type text/plain with charset UTF-8
โœ” Valid status code. Received status 200

EventSubController.php (original): https://pastebin.com/gQbFaYcX
EventSubController.php (revised): https://pastebin.com/ga3K0jUX

--

Not sure if the aforementioned is related, but also in production env. the status of the event sub is "webhook_callback_verification_failed" with original/revised versions.

Any assistance is appreciated, thanks!

New Twitch Api get authenticated user

Hello,
I couldn't get the current user using only the oauth token, according to documentations if the getUsers endpoint is called with no parameters it will return the current user, but since the parameters on you implementation was required I couldn't get it working.

removing the line:

if ( ! array_key_exists('login', $parameters) && ! array_key_exists('id', $parameters)) { throw new InvalidArgumentException('Parameter required missing: name or id'); }
from UsersTrait.php getUsers method solved this for me with an empty array as parameter.

handleWebhook not Called

Laravel Version: 9.2
Laravel-Twitch Version: 4.4

When creating a Webhook subscription the EventSubController is constructed but the handleWebhook Method is not called.

web.php

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

Route::get('/creating', function()
{
    $twitch = new Twitch;

    $result = $twitch->subscribeEventSub([], [
        'type' => EventSubType::CHANNEL_FOLLOW,
        'version' => '1',
        'condition' => [
            'broadcaster_user_id' => '<id>',
        ],
        'transport' => [
            'method' => 'webhook',
            'callback' => 'https://<URL>/callback/twitch',
        ]
    ]);
    Log::info("Creating!!!");
    var_dump($result->data());

});

In EventSub Controller i made small changes:

class EventSubController extends Controller
{
    public function __construct()
    {
        Log::info("EventSub:__construct()");
        if (config('twitch-api.eventsub.secret')) {
            Log::info("If Case");
            $this->middleware(VerifyEventSubSignature::class);
        }
    }
    [...]
    public function handleWebhook(Request $request): Response
    {
         Log::info("handleWebhook");

==> the handleWebhook is not displayed

and the Log then shows the Following

[2022-06-02 12:20:09] local.INFO: Creating!!!  
[2022-06-02 12:20:11] local.INFO: EventSub:__construct()  
[2022-06-02 12:20:11] local.INFO: If Case
[2022-06-02 12:20:11] local.INFO: Leaving Construct  
[2022-06-02 12:20:21] local.INFO: EventSub:__construct()  
[2022-06-02 12:20:21] local.INFO: If Case
[2022-06-02 12:20:21] local.INFO: Leaving Construct  

and the verification status goes to failed after four tries.

Do i miss something?
Did i make mistakes?

Using buildWebhookTopic

When I use buildWebhookTopic in new lib version I've got an error 400 Bed Request.
I've spent a some debug execution and reason that you have double json_encode
One of them in

 if (null !== $body) {
            $jsonBody = json_encode($body);
        }

and another then you call a Guzzle request, cause 'json' param in Guzzle request must be an array. So Guzzle by himself encode data.

Result "status"

I'm going to keep this short, privatising "status" does nothing but add more work on someone using your package, for example getting a users subscribers, $var->status == 200/404, why make it more of a pain? Honestly......

Request: Add Validate endpoint

Hello,
Just getting started with this package and it's working nicely so far. I see in the pull requests you are working on adding some missing endpoints, I have one more that I would love for you to add.

It's the oauth validate endpoint for validating tokens (More info here).

Thanks for your work
-Casey

Bug: Auto Generate does not work properly.

I have the feeling that the oauth client credentials cache does not renew expired keys.

I have the problem almost every month that I get the response Invalid OAuth token from the Twitch API.

Unfortunately I could not look at it. Workaround was: Change cache key.

Fix composer laravel requirements

composer.json

 "require": {
     "php": ">=7.0",
-    "laravel/framework": "^5.3",
+    "illuminate/support": "^5.3",
     "guzzlehttp/guzzle": "^6.2@dev"
 },

webhook_callback_verification_pending

Hey guys,

I'm trying to use this package to check if a user has subscribed to a channel.

To test Eventsub, I did an endpoint to subscribe and receive the event when the Twitch channel get a new follower. Here is my code:

routes/web.php

...
Route::post('twitch/eventsub/webhook', 'EventSubController@handleWebhook');
Route::get('twitch/test', 'TwitchController@test');

EventSubController.php

<?php

namespace App\Http\Controllers\Web\Twitch;

use Illuminate\Http\Request;
use Illuminate\Http\Response;
use romanzipp\Twitch\Http\Controllers\EventSubController as BaseController;


class EventSubController extends BaseController
{
    /**
     * Handle a EventSub notification call.
     *
     * @param array $payload
     *
     * @return Response
     */
    protected function handleNotification(array $payload): Response
    {
        return $this->successMethod();
    }

    /**
     * Handle a EventSub revocation call.
     *
     * @param array $payload
     *
     * @return Response
     */
    protected function handleRevocation(array $payload): Response
    {
        return $this->successMethod();
    }
}

TwitchController.php

<?php

namespace App\Http\Controllers\Web\Twitch;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

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

class TwitchController extends Controller
{
    public function test(Request $request)
    {
        $twitch = new Twitch;

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

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

        $payload = [
            'type' => EventSubType::CHANNEL_FOLLOW,
            'version' => '1',
            'condition' => [
                'broadcaster_user_id' => '12826', // twitch
            ],
            'transport' => [
                'method' => 'webhook',
                'callback' => config('app.url') . '/twitch/eventsub/webhook',
            ]
        ];

        $result = $twitch->withToken($token)->subscribeEventSub([], $payload);

        dd($payload, $result);
    }
}

When I call /twitch/test everything is fine. The subscription status is webhook_callback_verification_pending.

Next the endpoint /twitch/eventsub/webhook is called. In my log file, I can see handleWebhookCallbackVerification is called, and return challenge.
But the webhook is called again, and after the subscription status is webhook_callback_verification_failed.

Please can you tell me what's wrong here ?

Thank you !

Button "Connection with twich"

Hello, I am a beginner of Laravel.
I would like to create a "Connect with Twich" button. The goal is to retrieve the twitch id and twitch username of the user who wants to connect.

I followed your documentation but I cannot create my controller using your code.

I have correctly set the "clientid", "clientsecret", "redirect" information.

Can you explain the procedure to me in detail?

I work with Laravel 8.
Thank you so much.

Suggestion: Add IGDB endpoints

Twitch switched their game lookup from Giant Bomb to IGDB (which they bought a while ago).
See https://twitter.com/TwitchSupport/status/1310625492274470912
With that switch, IGDB's API now uses Twitch' OAuth2 Tokens (https://medium.com/igdb/igdb-api-v4-is-coming-6ba97874edbc).

I think, it would be nice, if IGDB (which is now technically part of Twitch) could be integrated into this package.
Generating and handling Bearer Tokens for the same authentication system twice, seems a like a big overhead.

Additionally, by integrating the IGDB API, more information regarding the games, returned by Twitch's API, can be obtained without handling another authentication system.

Secret for EventSub (Question)

maybe is a dumb question but...

how can i create a secret for my EventSub? i need to get it from twitch or just i need to write a simple word like a password?

Problem with laravel timezone

First of all, thanks for the amazing package.

When I set app.php's zime zone to my local time zone, the eventsub webhook URL keeps throwing SignatureVerificationException with the message Timestamp outside the tolerance zone, it works when I set it back to Laravel's default though.

Is this perhaps a problem on my side?

Fix composer guzzle requirement

composer.json

 "require": {
     "php": ">=7.0",
     "laravel/framework": "^5.3",
-    "guzzlehttp/guzzle": "^6.2@dev"
+    "guzzlehttp/guzzle": "^6.3"
 },

How to get the oauth token from getOAuthToken()

How do I get the OAuth token with a given "code"? The "token" response here is NULL

I'm not sure how I'm supposed to parse the data to get the token out?

From within Laravel I'm doing the following:

        twitch::setClientId('REDACTED');
        twitch::setClientSecret('REDACTED');
        $r=twitch::getOAuthToken($code);

        var_dump($r);

The response is:


object(romanzipp\Twitch\Result)#360 (9) {
  ["success"]=>
  bool(true)
  ["exception"]=>
  NULL
  ["data"]=>
  array(0) {
  }
  ["total"]=>
  int(0)
  ["status"]=>
  int(200)
  ["pagination"]=>
  NULL
  ["paginator"]=>
  object(romanzipp\Twitch\Helpers\Paginator)#344 (2) {
    ["pagination":"romanzipp\Twitch\Helpers\Paginator":private]=>
    NULL
    ["action"]=>
    NULL
  }
  ["response"]=>
  object(GuzzleHttp\Psr7\Response)#355 (6) {
    ["reasonPhrase":"GuzzleHttp\Psr7\Response":private]=>
    string(2) "OK"
    ["statusCode":"GuzzleHttp\Psr7\Response":private]=>
    int(200)
    ["headers":"GuzzleHttp\Psr7\Response":private]=>
    array(7) {
      ["Date"]=>
      array(1) {
        [0]=>
        string(29) "Mon, 02 Sep 2019 19:41:34 GMT"
      }
      ["Content-Type"]=>
      array(1) {
        [0]=>
        string(16) "application/json"
      }
      ["Content-Length"]=>
      array(1) {
        [0]=>
        string(3) "229"
      }
      ["Connection"]=>
      array(1) {
        [0]=>
        string(10) "keep-alive"
      }
      ["Server"]=>
      array(1) {
        [0]=>
        string(12) "nginx/1.14.1"
      }
      ["Access-Control-Allow-Origin"]=>
      array(1) {
        [0]=>
        string(1) "*"
      }
      ["X-Ctxlog-Logid"]=>
      array(1) {
        [0]=>
        string(35) "1-5d6d706e-3de0be8f72fd6342123a563e"
      }
    }
    ["headerNames":"GuzzleHttp\Psr7\Response":private]=>
    array(7) {
      ["date"]=>
      string(4) "Date"
      ["content-type"]=>
      string(12) "Content-Type"
      ["content-length"]=>
      string(14) "Content-Length"
      ["connection"]=>
      string(10) "Connection"
      ["server"]=>
      string(6) "Server"
      ["access-control-allow-origin"]=>
      string(27) "Access-Control-Allow-Origin"
      ["x-ctxlog-logid"]=>
      string(14) "X-Ctxlog-Logid"
    }
    ["protocol":"GuzzleHttp\Psr7\Response":private]=>
    string(3) "1.1"
    ["stream":"GuzzleHttp\Psr7\Response":private]=>
    object(GuzzleHttp\Psr7\Stream)#353 (7) {
      ["stream":"GuzzleHttp\Psr7\Stream":private]=>
      resource(274) of type (stream)
      ["size":"GuzzleHttp\Psr7\Stream":private]=>
      NULL
      ["seekable":"GuzzleHttp\Psr7\Stream":private]=>
      bool(true)
      ["readable":"GuzzleHttp\Psr7\Stream":private]=>
      bool(true)
      ["writable":"GuzzleHttp\Psr7\Stream":private]=>
      bool(true)
      ["uri":"GuzzleHttp\Psr7\Stream":private]=>
      string(10) "php://temp"
      ["customMetadata":"GuzzleHttp\Psr7\Stream":private]=>
      array(0) {
      }
    }
  }
  ["twitch"]=>
  object(romanzipp\Twitch\Twitch)#329 (6) {
    ["client":protected]=>
    object(GuzzleHttp\Client)#324 (1) {
      ["config":"GuzzleHttp\Client":private]=>
      array(8) {
        ["base_uri"]=>
        object(GuzzleHttp\Psr7\Uri)#342 (7) {
          ["scheme":"GuzzleHttp\Psr7\Uri":private]=>
          string(5) "https"
          ["userInfo":"GuzzleHttp\Psr7\Uri":private]=>
          string(0) ""
          ["host":"GuzzleHttp\Psr7\Uri":private]=>
          string(13) "api.twitch.tv"
          ["port":"GuzzleHttp\Psr7\Uri":private]=>
          NULL
          ["path":"GuzzleHttp\Psr7\Uri":private]=>
          string(7) "/helix/"
          ["query":"GuzzleHttp\Psr7\Uri":private]=>
          string(0) ""
          ["fragment":"GuzzleHttp\Psr7\Uri":private]=>
          string(0) ""
        }
        ["handler"]=>
        object(GuzzleHttp\HandlerStack)#325 (3) {
          ["handler":"GuzzleHttp\HandlerStack":private]=>
          object(Closure)#337 (2) {
            ["static"]=>
            array(2) {
              ["default"]=>
              object(Closure)#335 (2) {
                ["static"]=>
                array(2) {
                  ["default"]=>
                  object(GuzzleHttp\Handler\CurlMultiHandler)#331 (5) {
                    ["factory":"GuzzleHttp\Handler\CurlMultiHandler":private]=>
                    object(GuzzleHttp\Handler\CurlFactory)#332 (2) {
                      ["handles":"GuzzleHttp\Handler\CurlFactory":private]=>
                      array(0) {
                      }
                      ["maxHandles":"GuzzleHttp\Handler\CurlFactory":private]=>
                      int(50)
                    }
                    ["selectTimeout":"GuzzleHttp\Handler\CurlMultiHandler":private]=>
                    int(1)
                    ["active":"GuzzleHttp\Handler\CurlMultiHandler":private]=>
                    NULL
                    ["handles":"GuzzleHttp\Handler\CurlMultiHandler":private]=>
                    array(0) {
                    }
                    ["delays":"GuzzleHttp\Handler\CurlMultiHandler":private]=>
                    array(0) {
                    }
                  }
                  ["sync"]=>
                  object(GuzzleHttp\Handler\CurlHandler)#333 (1) {
                    ["factory":"GuzzleHttp\Handler\CurlHandler":private]=>
                    object(GuzzleHttp\Handler\CurlFactory)#334 (2) {
                      ["handles":"GuzzleHttp\Handler\CurlFactory":private]=>
                      array(1) {
                        [0]=>
                        resource(276) of type (curl)
                      }
                      ["maxHandles":"GuzzleHttp\Handler\CurlFactory":private]=>
                      int(3)
                    }
                  }
                }
                ["parameter"]=>
                array(2) {
                  ["$request"]=>
                  string(10) "<required>"
                  ["$options"]=>
                  string(10) "<required>"
                }
              }
              ["streaming"]=>
              object(GuzzleHttp\Handler\StreamHandler)#336 (1) {
                ["lastHeaders":"GuzzleHttp\Handler\StreamHandler":private]=>
                array(0) {
                }
              }
            }
            ["parameter"]=>
            array(2) {
              ["$request"]=>
              string(10) "<required>"
              ["$options"]=>
              string(10) "<required>"
            }
          }
          ["stack":"GuzzleHttp\HandlerStack":private]=>
          array(4) {
            [0]=>
            array(2) {
              [0]=>
              object(Closure)#338 (1) {
                ["parameter"]=>
                array(1) {
                  ["$handler"]=>
                  string(10) "<required>"
                }
              }
              [1]=>
              string(11) "http_errors"
            }
            [1]=>
            array(2) {
              [0]=>
              object(Closure)#339 (1) {
                ["parameter"]=>
                array(1) {
                  ["$handler"]=>
                  string(10) "<required>"
                }
              }
              [1]=>
              string(15) "allow_redirects"
            }
            [2]=>
            array(2) {
              [0]=>
              object(Closure)#340 (1) {
                ["parameter"]=>
                array(1) {
                  ["$handler"]=>
                  string(10) "<required>"
                }
              }
              [1]=>
              string(7) "cookies"
            }
            [3]=>
            array(2) {
              [0]=>
              object(Closure)#341 (1) {
                ["parameter"]=>
                array(1) {
                  ["$handler"]=>
                  string(10) "<required>"
                }
              }
              [1]=>
              string(12) "prepare_body"
            }
          }
          ["cached":"GuzzleHttp\HandlerStack":private]=>
          object(Closure)#351 (2) {
            ["static"]=>
            array(1) {
              ["handler"]=>
              object(GuzzleHttp\RedirectMiddleware)#350 (1) {
                ["nextHandler":"GuzzleHttp\RedirectMiddleware":private]=>
                object(Closure)#349 (2) {
                  ["static"]=>
                  array(1) {
                    ["handler"]=>
                    object(GuzzleHttp\PrepareBodyMiddleware)#346 (1) {
                      ["nextHandler":"GuzzleHttp\PrepareBodyMiddleware":private]=>
                      object(Closure)#337 (2) {
                        ["static"]=>
                        array(2) {
                          ["default"]=>
                          object(Closure)#335 (2) {
                            ["static"]=>
                            array(2) {
                              ["default"]=>
                              object(GuzzleHttp\Handler\CurlMultiHandler)#331 (5) {
                                ["factory":"GuzzleHttp\Handler\CurlMultiHandler":private]=>
                                object(GuzzleHttp\Handler\CurlFactory)#332 (2) {
                                  ["handles":"GuzzleHttp\Handler\CurlFactory":private]=>
                                  array(0) {
                                  }
                                  ["maxHandles":"GuzzleHttp\Handler\CurlFactory":private]=>
                                  int(50)
                                }
                                ["selectTimeout":"GuzzleHttp\Handler\CurlMultiHandler":private]=>
                                int(1)
                                ["active":"GuzzleHttp\Handler\CurlMultiHandler":private]=>
                                NULL
                                ["handles":"GuzzleHttp\Handler\CurlMultiHandler":private]=>
                                array(0) {
                                }
                                ["delays":"GuzzleHttp\Handler\CurlMultiHandler":private]=>
                                array(0) {
                                }
                              }
                              ["sync"]=>
                              object(GuzzleHttp\Handler\CurlHandler)#333 (1) {
                                ["factory":"GuzzleHttp\Handler\CurlHandler":private]=>
                                object(GuzzleHttp\Handler\CurlFactory)#334 (2) {
                                  ["handles":"GuzzleHttp\Handler\CurlFactory":private]=>
                                  array(1) {
                                    [0]=>
                                    resource(276) of type (curl)
                                  }
                                  ["maxHandles":"GuzzleHttp\Handler\CurlFactory":private]=>
                                  int(3)
                                }
                              }
                            }
                            ["parameter"]=>
                            array(2) {
                              ["$request"]=>
                              string(10) "<required>"
                              ["$options"]=>
                              string(10) "<required>"
                            }
                          }
                          ["streaming"]=>
                          object(GuzzleHttp\Handler\StreamHandler)#336 (1) {
                            ["lastHeaders":"GuzzleHttp\Handler\StreamHandler":private]=>
                            array(0) {
                            }
                          }
                        }
                        ["parameter"]=>
                        array(2) {
                          ["$request"]=>
                          string(10) "<required>"
                          ["$options"]=>
                          string(10) "<required>"
                        }
                      }
                    }
                  }
                  ["parameter"]=>
                  array(2) {
                    ["$request"]=>
                    string(10) "<required>"
                    ["$options"]=>
                    string(10) "<required>"
                  }
                }
              }
            }
            ["parameter"]=>
            array(2) {
              ["$request"]=>
              string(10) "<required>"
              ["$options"]=>
              string(10) "<required>"
            }
          }
        }
        ["allow_redirects"]=>
        array(5) {
          ["max"]=>
          int(5)
          ["protocols"]=>
          array(2) {
            [0]=>
            string(4) "http"
            [1]=>
            string(5) "https"
          }
          ["strict"]=>
          bool(false)
          ["referer"]=>
          bool(false)
          ["track_redirects"]=>
          bool(false)
        }
        ["http_errors"]=>
        bool(true)
        ["decode_content"]=>
        bool(true)
        ["verify"]=>
        bool(true)
        ["cookies"]=>
        bool(false)
        ["headers"]=>
        array(1) {
          ["User-Agent"]=>
          string(38) "GuzzleHttp/6.3.3 curl/7.52.1 PHP/7.2.8"
        }
      }
    }
    ["paginator":protected]=>
    NULL
    ["token":protected]=>
    NULL
    ["clientId":protected]=>
    string(30) "REDACTED"
    ["clientSecret":protected]=>
    string(30) "REDACTED"
    ["redirectUri":protected]=>
    string(43) "REDACTED"
  }
}

Prod: Unable to extract timestamp and signatures from header

With #77, everything works fine when I test with Twitch CLI, but in production I have the error:

Unable to extract timestamp and signatures from header

Because the Timestamp is not the same between Twitch CLI and the real Twitch call:

CLI: Twitch-Eventsub-Message-Timestamp: 2021-04-11T09:40:55.902801Z

Twitch: Twitch-Eventsub-Message-Timestamp: 2021-04-11T09:49:55.813Z

I've updated TIMESTAMP_PATTERN but i'm not sure if it's correct:

const TIMESTAMP_PATTERN = '/^(?<pre>[\d\-:.T]+)\.(?<nano>\d{3,9})Z$/';

Double encoding in $twitch->unsubscribeWebhook

Hi, use the last version of Laravel Twitch:
$twitch->unsubscribeWebhook(
"https://***/twitch/callback/7",
$twitch->webhookTopicStreamMonitor(190203376)
);
After execute I've got a {"error":"Bad Request","status":400,"message":"hub.topic unsupported topic"}

Looked at params in request and saw:
hub.topic=https%253A%252F%252Fapi.twitch.tv%252Fhelix%252Fstreams%253Fuser_id%253D190203376

%253A%252F%252F
It's not the same as %3A%2F%2F as it get after urlencode()
Could you fix it?

BTW: use
"name": "guzzlehttp/guzzle",
"version": "6.3.3",

Webhooks no longer available

EventSub replaced the Webhooks system.
The endpoints in the /webhooks namespace are no longer available.

It may be good, to remove them from the lib.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.