Skip to content

Instantly share code, notes, and snippets.

@harish2704
Created October 19, 2023 18:09
Show Gist options
  • Save harish2704/f1cb8e7b1669def7f9a51e481dbb0681 to your computer and use it in GitHub Desktop.
Save harish2704/f1cb8e7b1669def7f9a51e481dbb0681 to your computer and use it in GitHub Desktop.
Simple PHP based web-hook multiplexer / relay service
<?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