Created
October 19, 2023 18:09
-
-
Save harish2704/f1cb8e7b1669def7f9a51e481dbb0681 to your computer and use it in GitHub Desktop.
Simple PHP based web-hook multiplexer / relay service
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// A map of "request_path" => Array of target urls. | |
// Any request coming to "request_path" will be forwarded/relayed to all the urls specified in its value | |
// fowarding is done asynchronously and concurrntly. | |
$conf = [ | |
'/mywebook1' => [ | |
'https://testing.myapp.local/webhook/webhook1', | |
'https://dev.myapp.local/webhook/webhook1', | |
], | |
'/mywebook2' => [ | |
'https://testing.myapp.local/hooks/hook2', | |
'https://dev.monitoring.local/webhooklogger/hook2', | |
], | |
]; | |
require_once(__DIR__ . '/../vendor/autoload.php'); | |
use GuzzleHttp\Client; | |
use GuzzleHttp\Promise; | |
/** | |
* | |
* @property Array $relayConf | |
*/ | |
class WebhookRelay | |
{ | |
public function __construct($relayConf) | |
{ | |
$this->relayConf = $relayConf; | |
} | |
function sendReq($url, $method = "GET", $query = [], $body = "", $headers = []) | |
{ | |
return (new Client())->requestAsync($method, $url, [ | |
'query' => $query, | |
'body' => $body, | |
'headers' => $headers, | |
]); | |
} | |
function relayReq($path) | |
{ | |
$relayConf = $this->relayConf; | |
if (!isset($relayConf[$path])) { | |
error_log("webhook: no urls found for " . $path); | |
return; | |
} | |
$headers = getallheaders(); | |
unset($headers['Host']); | |
unset($headers['Accept-Encoding']); | |
$query = $_GET; | |
$method = $_SERVER['REQUEST_METHOD']; | |
$body = file_get_contents('php://input'); | |
$urls = $relayConf[$path]; | |
$allTasks = []; | |
foreach ($urls as $url) { | |
$allTasks[] = $this->sendReq($url, $method, $query, $body, $headers); | |
} | |
return Promise\Utils::unwrap($allTasks); | |
} | |
} | |
// First send response to upstream server | |
ob_start(); | |
echo json_encode(['success' => true]); | |
$size = ob_get_length(); | |
header('Content-type: application/json'); | |
header("Content-Length: {$size}"); | |
header("Connection: close"); | |
ob_end_flush(); | |
ob_flush(); | |
flush(); | |
// Then do the processing | |
$path = $_SERVER['PATH_INFO']; | |
$path = rtrim($path, '/'); | |
$webhookRelay = new WebhookRelay($conf); | |
$webhookRelay->relayReq($path); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment