Eventsub Webhooks Revoked/Challenge Issues

Can someone please take a look at this callback script for webhooks and let me know if there’s something off? I didn’t write it, it’s been working fine since last year up until a few days ago and then apparently it’s been failing to respond to some of the incoming data, and then today we had our hype train progress and cheers subs revoked. I have tried re-subbing, I had a saved query using Postman which has all the correct data and had previously worked - the app token is up to date, I got the pending verification message, but nothing has happened after that and I’m clueless as to what might have gone wrong. I’ve taken out our secret word and the database connection details - otherwise it’s all there.

$date = new DateTime(NULL, new DateTimeZone( "UTC" ));
$timenow = $date->getTimeStamp();  
$GD = getdate($timenow);
$logid = "-".$GD['month']."-".$GD['year'];

$logfile = "/home/fatstrs/shaminc/web/logs/webhook".$logid.".log";
$has = "";
$lh = fopen($logfile, 'a');
$sql = "";
$body = file_get_contents("php://input");
$data = json_decode($body, true);
fwrite($lh, $date->format('Y-m-d H:i:s T') . "\n");

fwrite($lh, "Headers: " . json_encode(getallheaders()) . "\n");
fwrite($lh, "Body: " . json_encode($data) . "\n");
fwrite($lh, "Get: " . json_encode($_GET) . "\n");
fwrite($lh, "Post: " . json_encode($_POST) . "\n\n\n");

if(isset(getallheaders()['Twitch-Eventsub-Message-Signature'])) {
    $hdrs = getallheaders();
    $hmac_message = $hdrs['Twitch-Eventsub-Message-Id'] . $hdrs['Twitch-Eventsub-Message-Timestamp'] . $body;
    fwrite($lh, "HashedMessage:\n" .$hmac_message . "\n\n");
    $signature = hash_hmac("sha256", $hmac_message, "XXXXXXXXXX");
    $hash = 'sha256=' . $signature;
    $validation = $hdrs['Twitch-Eventsub-Message-Signature'];
    fwrite($lh, "Hashes:\n Calculated: " . $hash . "\n Supplied:   " .$validation . "\n");
    if($validation == $hash) {
        fwrite($lh, "Validated HASH\n\n");
        if(isset($data["challenge"])) {
            fwrite($lh, "\"challenge\" included, responding:\n" . $data["challenge"] . "\n\n");
            echo $data["challenge"];
    } else {
        fwrite($lh, "Invalid HASH\n\n");

    $conn = new mysqli($servername, $username, $password, $dbname);
    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);

    $headers = $conn->real_escape_string(json_encode($hdrs));
    $body = $conn->real_escape_string(json_encode($data));
    $twitch_id = $hdrs['Twitch-Eventsub-Message-Id'];
    $twitch_ts = $hdrs['Twitch-Eventsub-Message-Timestamp'];
    $twitch_ts = preg_replace("/\.[0-9]*/", "", $twitch_ts);
    $twitch_ts = New DateTime($twitch_ts);
    $twitch_ts = $twitch_ts->getTimestamp();
    $received_ts = $date->getTimestamp();
    $topic = $hdrs["Twitch-Eventsub-Subscription-Type"];
    $sql = "INSERT INTO `TWITCH_Webhooks` (TwitchID, TwitchTS, ReceivedTS, Topic, Headers, Body) VALUES " . 
           "('" .$twitch_id . "', '" . $twitch_ts . "', '" . $received_ts . "', '" . $topic . "', '" . $headers . "', '" . $body . "')";
    fwrite($lh, "SQL: " . $sql . "\n\n\n");

    $result = $conn->query($sql);


Check your server access/error logs to see if the request even got to your server.

if your callback script hasn’t been touched then the issue is something else, as it was previously working as you have stated.

Common issue would perhaps be an issue with SSL or something in front of your server such as cloudflare bot defence.

Or the fact that today cloudflare has been having issues.

The only issue I see is that you would want to be getallheaders()-ing and converting all the keys to lowercase to comply with HTTP Spec, which you are not doing. (As the case of a header key is not important to the data so you should lowercase for sanity, PHP doesn’t do this by default like other languages/libs)

But you can check your webhook$logid.log to see what you are receiving. thats if the request is even hitting your server.

You can also use the TwitchCli test/trigger functions to test in case

SSL seems to be all in place (ssllabs gives us an A rating and it’s not due to expire for another few months). I do recall getting a Cloudflare message the last time I royally mucked up writing a script to auto-generate pages for some of our content about 18 months ago, so I guess that could be a factor. The log file does show the subscription request was received but there’s nothing after that.

When you say keys - what specifically are you referring to? Google was not as helpful as I had hoped!

getallheaders() returns an associative array, the items in the array are referred to by the name of the item which is commonly referred to as a key

You can see here

I do

    $input_headers = getallheaders();
    // save our soul headers
    // HTTP Spec suggests they should be lower case always
    // so we'll convert to save some sanity
    $headers = [];
    foreach ($input_headers as $header => $value) {
        $headers[strtolower($header)] = $value;
    // save our soul headers

To ensure that I sanity check the key names on the header to ensure all lower case in case for any weirdness

Yes I realized when I woke up this morning that keys is obviously the keys of the array! I shall impliment that and have a look at the command line stuff - see if I can make any sense of that.

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