Webhooks: What Am I Doing Wrong? PHP

I assume I’m missing something obvious, but this code returns:
{“error”:“Unauthorized”,“status”:401,“message”:“Must provide a valid Client-ID or OAuth token”}
I can make it so that I’m not sending it as json but I thought that was the problem before because I would get the 202 response, but my notifications handler page would never get any notification with a challenge or denied request.

Any help would be appreciated as I’ve been at this for a while with no progress to show for it… haha

$client_id = “<>”;

$mode = “subscribe”;
$callback_url = “<<my website’s url>>/twitch_notifications_handler”;
$target_user_id = “132154945”;
$lease_days = “10”;
$lease_seconds = $lease_days * 24 * 60 * 60;

$subscribe_to_event_url = “https://api.twitch.tv/helix/webhooks/hub”;

$data = array(
‘hub.mode’ => $mode,
‘hub.topic’ => “https://api.twitch.tv/helix/streams?user_id=”.$target_user_id,
‘hub.callback’ => $callback_url,
‘hub.lease_seconds’ => $lease_seconds
$data_string = json_encode($data);

$ch = curl_init($subscribe_to_event_url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, “POST”);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
‘Content-Type: application/json’,
'Content-Length: ’ . strlen($data_string)),
'Client-ID: '.$client_id

$result = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

echo $httpcode."

The parentheses are mismatched in your CURLOPT_HTTPHEADER curl_setopt so you are closing the array prior to adding the Client-ID:

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($data_string),
    'Client-ID: '.$client_id

Thank you for pointing that out. I still don’t seem to be getting a challenge or denied request sent to my handler page though.

And I know it has to be something wrong with this script because I tested the handler code by executing this little script on another page and got back the correct response:

$ch = curl_init();

curl_setopt_array($ch, array(
CURLOPT_URL => ‘<<my website’s url>>/twitch_notifications_handler/?hub.challenge=1234567890’,

$resp = curl_exec($ch);

echo $resp;

If twitch_notifications_handler is a directory, the first one will return a redirect in common web server configurations. The trailing / is important there. Have you checked your access logs to see if the request hits the web server or if it’s lost before that?

Haha I feel like an idiot. That seems to have fixed it. Thanks so much!

What is the advantage of using webhooks with PHP?

There is no advantage to doing it in one language or the other…

If you use php at the web is usless because your app will not be always on for receiving the webhooks data


Citation: I use PHP to capture PayPal Webhooks and never dropped one…

The choice of language/tech to use for a task usually comes down to

  1. your (own/team’s) familiarity with the languages being considered
  2. how well the language/tech fits your use-case (libraries available, language features focused on your kind of data handling)

PHP isn’t designed as an always-on language. It’s designed for a web server to run per-request, like Common Gateway Interface scripts.

1 Like

Can you explain this more in depth please. I haven’t heard of this issue.

Webhooks works like, send a post to a link.
If u are using twitch webhooks in the web they will not work because they will not refreshing

But for recive webhooks your app dont need to be always refreshing?

None of the words you just said in the last two replies made any sense…

If you mean to continue a subscription to a webhook, just setup a cron job to do so like subscribing to a webhook to start with

Webhooks work like:
The user or a client send a POST to the webhook link and the client or the user will request that POST right?


So how it works?

A webhook is (traditionally) a payload of information sent to a callback url when an event occurs.

  1. event happens somewhere on twitch.tv (stream up/down, new follow, subscription, etc.)
  2. Twitch server makes call to YOUR website/service with a payload of information describing the event
  3. Your website/service receives this data and acts on it somehow

After X period, the webhook is discontinued and you must renew it to continue to receive updates.

But when webhook event happen the php website will not recive because it isnt always “online”