如何通过PHP接收Webhook触发OBS浏览器源页面的JS函数?
自定义OBS直播提醒:通过Webhook触发浏览器源JS函数
问题描述
我正在制作一个自定义直播提醒页面,将其作为OBS直播的浏览器源使用。目前该页面已可通过JavaScript函数传递变量触发内容变化;我需要从自定义捐赠系统的Webhook接收捐赠或订阅事件,通过处理Webhook的PHP页面触发OBS加载的页面展示对应事件。请问如何调用目标页面的JS函数,让事件在OBS源中显示?
现有提醒页面代码
<div class="center"> <h1 id="title"></h1> <h2 id="user-amount"></h2> <p id="message"></p> </div> <style> .center { padding: 70px 0; text-align: center; color: white; } </style> <script> async function DonateAlert(title, user, amount, message){ document.getElementById("title").innerHTML = title; document.getElementById("user-amount").innerHTML = "£" + amount + " from " + user; document.getElementById("message").innerHTML = message; await new Promise(resolve => setTimeout(resolve, 5000)); document.getElementById("title").innerHTML = ""; document.getElementById("user-amount").innerHTML = ""; document.getElementById("message").innerHTML = ""; } async function SubAlert(title, user, message){ document.getElementById("title").innerHTML = title; document.getElementById("user-amount").innerHTML = user; document.getElementById("message").innerHTML = message; await new Promise(resolve => setTimeout(resolve, 5000)); document.getElementById("title").innerHTML = ""; document.getElementById("user-amount").innerHTML = ""; document.getElementById("message").innerHTML = ""; } function sleep() { return new Promise(resolve => setTimeout(resolve, 10000)); }; async function triggerTest(){ DonateAlert("Donation", "John", 10, "Thank you for the donation!"); await sleep(); SubAlert("Subscription", "John", "Thank you for the subscription!"); } </script>
失败的尝试(PHP Webhook页面)
echo("<script type='text/javascript' src='https://cdn.jconet.co.uk/alerts'>SubAlert('SUBSCRIPTION', '".$discordName."', 'Subscribed to the ".$name." plan!')</script>");
解决方案
核心问题说明
你之前的写法完全错误:Webhook处理页面是被捐赠系统服务器请求的独立页面,和OBS加载的浏览器源页面没有上下文关联,直接输出script标签根本无法跨页面调用JS函数。必须通过实时通信机制让OBS页面主动监听事件。
方案一:PHP+文件存储的轮询实现(简单易上手)
适合小流量场景,实现成本低:
- 改造Webhook处理页面:收到事件时将数据写入JSON文件
<?php // webhook-handler.php // 接收Webhook原始数据(根据你的捐赠系统格式调整) $rawData = file_get_contents('php://input'); $eventData = json_decode($rawData, true); // 整理为前端需要的提醒数据 $alertData = []; if ($eventData['type'] === 'donation') { $alertData = [ 'id' => time(), // 用时间戳做唯一ID,避免重复触发 'type' => 'donate', 'title' => 'Donation', 'user' => $eventData['user'], 'amount' => $eventData['amount'], 'message' => $eventData['message'] ?? '' ]; } elseif ($eventData['type'] === 'subscription') { $alertData = [ 'id' => time(), 'type' => 'sub', 'title' => 'Subscription', 'user' => $eventData['discordName'], 'message' => "Subscribed to the {$eventData['name']} plan!" ]; } // 将数据写入JSON文件(覆盖旧数据,若需排队可改为数组追加) file_put_contents('alert-data.json', json_encode($alertData)); // 返回Webhook响应 http_response_code(200); echo json_encode(['status' => 'success']); ?>
- 改造OBS提醒页面:添加轮询逻辑,定期检查并触发提醒
<div class="center"> <h1 id="title"></h1> <h2 id="user-amount"></h2> <p id="message"></p> </div> <style> .center { padding: 70px 0; text-align: center; color: white; } </style> <script> let lastEventId = null; // 记录最后处理的事件ID,防止重复触发 async function DonateAlert(title, user, amount, message){ document.getElementById("title").innerHTML = title; document.getElementById("user-amount").innerHTML = "£" + amount + " from " + user; document.getElementById("message").innerHTML = message; await new Promise(resolve => setTimeout(resolve, 5000)); // 清空内容 document.getElementById("title").innerHTML = ""; document.getElementById("user-amount").innerHTML = ""; document.getElementById("message").innerHTML = ""; } async function SubAlert(title, user, message){ document.getElementById("title").innerHTML = title; document.getElementById("user-amount").innerHTML = user; document.getElementById("message").innerHTML = message; await new Promise(resolve => setTimeout(resolve, 5000)); // 清空内容 document.getElementById("title").innerHTML = ""; document.getElementById("user-amount").innerHTML = ""; document.getElementById("message").innerHTML = ""; } // 轮询检查新事件 async function checkForAlerts() { try { // 加时间戳避免浏览器缓存 const response = await fetch('alert-data.json?' + Date.now()); if (!response.ok) throw new Error('请求失败'); const data = await response.json(); // 检查是否是未处理的新事件 if (data && data.id !== lastEventId) { lastEventId = data.id; // 根据事件类型触发对应提醒 if (data.type === 'donate') { await DonateAlert(data.title, data.user, data.amount, data.message); } else if (data.type === 'sub') { await SubAlert(data.title, data.user, data.message); } } } catch (error) { console.error('检查提醒失败:', error); } finally { // 2秒后再次检查 setTimeout(checkForAlerts, 2000); } } // 启动轮询 checkForAlerts(); // 保留测试函数 function sleep() { return new Promise(resolve => setTimeout(resolve, 10000)); }; async function triggerTest(){ DonateAlert("Donation", "John", 10, "Thank you for the donation!"); await sleep(); SubAlert("Subscription", "John", "Thank you for the subscription!"); } </script>
方案二:WebSocket实时通信(适合高频率事件)
如果直播事件较多,轮询效率低,可以采用WebSocket实现实时推送。比如使用PHP的Ratchet库或Node.js的Socket.io,实现后端主动向OBS页面推送事件。这种方式延迟更低,但实现复杂度稍高,适合有一定后端开发基础的场景。
内容的提问来源于stack exchange,提问作者JCoDog
相关产品推荐
相关产品推荐

