EventSub - How to? Stucked

Just got this code here, I guess from @BarryCarlyon …again… :slight_smile:

Simple thing. I just want to receive callbacks from twitch when a certain broadcast_id goes live. Or maybe use it for other things in my App later. But got this 400 bad request. Whats wrong here?

This is the code (for testing).

<?php
include_once(dirname(__DIR__, 2) . '/***/class.php');
$mod = new mod_raidpal();
require_once($mod->settingsFile); //call the settings, also for the const. variables from TWITCH

$ch = curl_init('https://id.twitch.tv/oauth2/token?client_id=' . TWITCH_CLIENT_ID . '&client_secret=' . TWITCH_CLIENT_SECRET . '&grant_type=client_credentials');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, true);

$r = curl_exec($ch);
$i = curl_getinfo($ch);
curl_close($ch);

if ($i['http_code'] == 200) {

    $keys = json_decode($r);

    if (json_last_error() == JSON_ERROR_NONE) {

        $post = json_encode(
            array(
                'type' => 'stream.online',
                'version' => '1',
                'condition' => array(
                    'broadcaster_user_id' =>*** (my test account)
                ),
                'transport' => array(
                    'method' => 'webhook',
                    'callback' => 'https://***/callback',
                    'secret' => '23k4hstertfueu'
                )
            )
        );

        $headers = array(
            'Client-ID: ' . TWITCH_CLIENT_ID,
            'Authorization: Bearer ' . $keys->access_token,
            'Content-Type: application/json'
        );

        $ch = curl_init('https://api.twitch.tv/helix/eventsub/subscriptions');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $r = curl_exec($ch);
        $i = curl_getinfo($ch);
        curl_close($ch);

        echo print_r($i, true);

        if ($i['http_code'] == 200) {

            // created sub OK
            echo 'created sub OK.';

        } else {

            echo 'created sub FAILED: ' . $r;
        }

    } else {

        echo 'Failed to parse JSON';
    }

} else {

    echo 'Failed with ' . $i['http_code'] . ' ' . $r;

}

400 bad request and what

Which called is failing token generation or the eventsub call?
It should spit out the body of the response and which call failed, not just a HTTP code

The reply from curl:

Array
(
    [url] => https://id.twitch.tv/oauth2/token?client_id=***f&client_secret=***&grant_type=client_credentials
    [content_type] => text/html
    [http_code] => 400
    [header_size] => 150
    [request_size] => 271
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.816135
    [namelookup_time] => 0.028959
    [connect_time] => 0.188394
    [pretransfer_time] => 0.65653
    [size_upload] => 0
    [size_download] => 122
    [speed_download] => 149
    [speed_upload] => 0
    [download_content_length] => 122
    [upload_content_length] => -1
    [starttransfer_time] => 0.816076
    [redirect_time] => 0
    [redirect_url] => 
    [primary_ip] => 35.82.117.112
    [certinfo] => Array
        (
        )

    [primary_port] => 443
    [local_ip] => 185.110.173.101
    [local_port] => 50338
)

That should be the output of


} else {

    echo 'Failed with ' . $i['http_code'] . ' ' . $r;

}

So $r should have something. You have provided the output of $i which doesn’t contain the bit of info we need

You token generation for a client credentails token seems to have failed.

With Postman on my local mac, I immediately get the access_token with this http post command.
{
“access_token”: “***”,
“expires_in”: 4773532,
“token_type”: “bearer”
}

Then we still need the output of $r from the script to determine the issue.

Got a nice one on my MAMP:

result:{"access_token":"***","expires_in":4788564,"token_type":"bearer"} Array ( [url] => https://api.twitch.tv/helix/eventsub/subscriptions [content_type] => application/json; charset=utf-8 [http_code] => 400 [header_size] => 471 [request_size] => 229 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.23778 [namelookup_time] => 0.002058 [connect_time] => 0.008459 [pretransfer_time] => 0.050223 [size_upload] => 192 [size_download] => 94 [speed_download] => 396 [speed_upload] => 810 [download_content_length] => 94 [upload_content_length] => 192 [starttransfer_time] => 0.05023 [redirect_time] => 0 [redirect_url] => [primary_ip] => 199.232.150.214 [certinfo] => Array ( ) [primary_port] => 443 [local_ip] => 192.168.68.120 [local_port] => 65161 [http_version] => 3 [protocol] => 2 [ssl_verifyresult] => 0 [scheme] => HTTPS [appconnect_time_us] => 49884 [connect_time_us] => 8459 [namelookup_time_us] => 2058 [pretransfer_time_us] => 50223 [redirect_time_us] => 0 [starttransfer_time_us] => 50230 [total_time_us] => 237780 ) created sub FAILED: {"error":"Bad Request","status":400,"message":"missing or unparseable subscription condition"}

On the server it fails. Code seems to be okay then.

So whats the code you are currently using on the server?

Since the MAMP eror is a different error to the earlier error which was token generation

same code!

But the output error is not what the code should output.

This is what I get:
HTTP/1.1 400 Bad Request Server: awselb/2.0 Date: Mon, 26 Sep 2022 19:59:42 GMT Content-Type: text/html Content-Length: 122 Connection: close

When I use Postman, its also fine, get access_code. So the post request is ok.

But it should output

created sub FAILED: BODYHERE

or

Failed with HTTPCODE BODYHERE

for either of the two calls

Yes, so it seems like a server behaviour Barry. Already tested, logs no errors. All seems good, but still not working. Strange thing is, the website RaidPal.com works like a charm. With CURL! Thanks for your assistance so fast.

@BarryCarlyon Found out that the cURL Host Header important. Without this one in Postman, got the same 400 error. Now to find out Which header I need to set in cURL exactly. Any suggestion?

The code presented in your OP, should not need a header of key Host.

SOLVED! From url params to postfields did the job:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.