matterbridge-webhooks
Version:
Matterbridge webhooks plugin
73 lines (72 loc) • 2.79 kB
JavaScript
import http from 'node:http';
import https from 'node:https';
export async function fetch(url, method = 'GET', data = {}, timeout = 5000) {
return new Promise((resolve, reject) => {
const controller = new AbortController();
const timeoutId = setTimeout(() => {
controller.abort();
reject(new Error(`Request timed out after ${timeout / 1000} seconds`));
}, timeout).unref();
let requestUrl = url;
const jsonData = JSON.stringify(data);
if (method === 'GET') {
const queryParams = new URLSearchParams(Object.entries(data).reduce((acc, [key, value]) => {
if (value === null) {
acc[key] = '';
}
else if (typeof value === 'object') {
acc[key] = JSON.stringify(value);
}
else {
acc[key] = String(value);
}
return acc;
}, {})).toString();
if (queryParams) {
const separator = url.includes('?') ? '&' : '?';
requestUrl = `${url}${separator}${queryParams}`;
}
}
const options = {
method,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
...(method === 'POST' && { 'Content-Length': Buffer.byteLength(jsonData) }),
},
signal: controller.signal,
};
const protocol = url.startsWith('https') ? https : http;
const req = protocol.request(requestUrl, options, (res) => {
res.setEncoding('utf8');
let responseData = '';
if (res.statusCode && res.statusCode >= 300) {
clearTimeout(timeoutId);
res.resume();
req.destroy();
reject(new Error(`Request failed with status code: ${res.statusCode}`));
}
res.on('data', (chunk) => {
responseData += chunk;
});
res.on('end', () => {
clearTimeout(timeoutId);
try {
const jsonResponse = JSON.parse(responseData);
resolve(jsonResponse);
}
catch (err) {
reject(new Error(`Failed to parse response JSON: ${err instanceof Error ? err.message : err}`));
}
});
});
req.on('error', (error) => {
clearTimeout(timeoutId);
reject(new Error(`Request failed: ${error instanceof Error ? error.message : error}`));
});
if (method === 'POST') {
req.write(jsonData);
}
req.end();
});
}