已验证Google WebSub订阅,上传YouTube视频后无通知求助
问题:WebSub订阅验证成功,但上传YouTube视频后未触发钩子脚本
我有一个测试YouTube频道,搭建了WebSub钩子,目的是在频道上传视频时,触发PHP脚本向Telegram机器人发送数据。对应的index.php代码如下:
file_put_contents(__DIR__.'/debug.php',"<?php die(); /*\n".$_SERVER['REQUEST_METHOD']."\n*/",FILE_APPEND); // Bootstrap Sentry require_once "./lib/sentry.php"; \Sentry\captureMessage("Request ".$_SERVER['REQUEST_METHOD'],\Sentry\Severity::info()); // Sentry also requires Settings as well therefore we use require $settings = require("./config.php"); $traceId = rand(); if(!isset($settings['YT_CHANNEL_ID'])){ http_response_code(500); \Sentry\captureMessage("$traceId : No youtube channel Id has been Configured",\Sentry\Severity::error()); exit(0); } // Hub sends a GET request for subscription Then a post methos is if($_SERVER['REQUEST_METHOD'] == "GET"){ if(!isset($_GET['hub_mode']) || $_GET['hub_mode']!=='subscribe'){ http_response_code(204); exit(0); } if(!isset($_GET['hub_topic'])){ http_response_code(400); \Sentry\captureMessage("$traceId : Topic has not been provided",\Sentry\Severity::error()); exit(0); } $expected_topic = "https://www.youtube.com/feeds/videos.xml?channel_id=".$settings['YT_CHANNEL_ID']; if($expected_topic!=trim($_GET['hub_topic'])){ http_response_code(403); \Sentry\captureMessage("$traceId : Googlwe websub provided wrong channel id",\Sentry\Severity::error()); exit(0); } if(!isset($_GET['hub_challenge'])){ http_response_code(400); exit(0); } http_response_code(200); header("Content-Type: text/plain"); echo $_GET['hub_challenge']; \Sentry\captureMessage("Hub Is Subscribed",\Sentry\Severity::info()); exit(0); } // Post handling begins here $string = file_get_contents('php://input'); \Sentry\captureMessage("BODY:\n".$string,\Sentry\Severity::info()); file_put_contents(__DIR__.'/debug.php',PHP_EOL."/*".$string."*/",FILE_APPEND); require_once "./lib/requestHandler.php"; if(empty($string)){ http_response_code(400); \Sentry\captureMessage("$traceId : Input is empty",\Sentry\Severity::error()); exit(0); } try{ $ytInfo = parseRequest($string); if($ytInfo->channelId != $settings['YT_CHANNEL_ID']){ // Despite input is valid we no need to send message for a channel that we have not confirued to do so. http_response_code(204); \Sentry\captureMessage("Channel Missmatch Skipping",\Sentry\Severity::info()); exit(0); } } catch(\InvalidArgumentException $e){ http_response_code(400); \Sentry\captureException($e); exit(0); } require_once "./lib/bot_actions.php"; try{ sendMessageToChannel($settings['TELEGRAM_CHANNEL_ID'],$settings['BOT_TOKEN'],$ytInfo->videoUrl,$ytInfo->videoTitle); http_response_code(204); }catch(\Exception $e){ \Sentry\captureException($e); http_response_code(500); }
订阅已经验证通过,但向频道上传视频后,WebSub并未调用该脚本。
为排查问题,我简化了脚本:
// Hub sends a GET request for subscription Then a post methos is if($_SERVER['REQUEST_METHOD'] == "GET"){ if(!isset($_GET['hub_challenge'])){ http_response_code(400); exit(0); } http_response_code(200); header("Content-Type: text/plain"); echo $_GET['hub_challenge']; exit(0); } // Post handling begins here $string = file_get_contents('php://input'); file_put_contents(__DIR__.'/debug.txt',PHP_EOL.$string,FILE_APPEND); http_response_code(204);
重新订阅频道后,debug.txt始终没有内容,pubsubhubbub仍未调用新脚本。这是已知问题吗?该如何解决?
解决建议
- 检查回调URL的可访问性:确保回调URL是公网可访问的,且使用HTTPS(YouTube要求WebSub回调必须用HTTPS,本地测试除外),路径没有拼写错误。
- 验证视频状态:上传的视频必须是公开可见的,私有或未列出的视频不会触发通知;同时要等视频完成转码、审核流程,这个过程可能需要几分钟。
- 排查服务器拦截规则:检查服务器防火墙、安全组,以及CDN/WAF是否拦截了YouTube的POST请求;查看服务器访问日志,确认是否有来自YouTube的请求到达。
- 重新确认订阅参数:发起订阅时,确保
hub.topic是正确的频道Feed地址,且hub.lease_seconds设置合理,避免租期到期未续约导致通知中断。 - 优化脚本调试:给简化版脚本添加更详细的日志,比如记录请求时间、请求头,同时确保脚本所在目录有PHP进程的写入权限:
// 在POST处理部分添加 $logData = date('Y-m-d H:i:s') . " - 请求已接收\n"; $logData .= "请求头:\n" . print_r(getallheaders(), true) . "\n"; $logData .= "请求体:\n" . $string . "\n\n"; file_put_contents(__DIR__.'/debug.txt', $logData, FILE_APPEND); - 检查服务状态:查看YouTube开发者状态页面,确认WebSub服务是否存在故障或维护。
内容的提问来源于stack exchange,提问作者Dimitrios Desyllas
相关产品推荐
相关产品推荐

