const express = require('express'); const axios = require('axios'); const app = express(); const port = 7000; app.use(express.json({ limit: '500mb' })); const API_KEY = process.env.API_KEY || "silly!" const RETRY_ERROR_CODES = [408, 500, 502, 503, 504, 522, 524, 599]; async function main() { const responses = []; app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`); }); async function RegisterResponse(instanceId, response) { if (!responses[instanceId]) { responses[instanceId] = [] } responses[instanceId].push({ id: response.id, data: response.data }) console.log(`Response registered for instance ${instanceId}`); setTimeout(() => { if (!responses[instanceId]) { return; } responses[instanceId] = responses[instanceId].filter(resp => resp.id !== response.id); //console.log(`Response ${response.id} removed from instance ${instanceId}`); }, 60_000); } async function DoRequest(instanceId, requestObj) { const requestParams = requestObj.request || {}; const method = requestParams.Method?.toLowerCase() || 'get'; const url = requestParams.Url || ''; const body = requestParams.Body || ''; let headers = requestParams.Headers || null; // if headers is a an array or is an empty object, convert it to null if (headers && (Array.isArray(headers) || Object.keys(headers).length === 0)) { headers = null; } const shouldHaveBody = ['post', 'put', 'patch'].includes(method); console.log("DoRequest",instanceId,requestObj) try { const response = await axios({ method: method, url: url, headers: headers, data: shouldHaveBody ? body : null }); RegisterResponse(instanceId, { id: requestObj.id, data: response.data }); } catch (error) { if (RETRY_ERROR_CODES.includes(error.response?.status)) { console.log(`Retrying request ${requestObj.id} for instance ${instanceId}`); SetTimeout(() => { DoRequest(instanceId, requestObj); }, 5000); } else { RegisterResponse(instanceId, { id: requestObj.id, data: error.response?.data, error: "yep there was an error" }); } } } function getToSend(instanceId, waiting) { const toSend = []; const instanceResponses = responses[instanceId] || []; instanceResponses.forEach(respObj => { if (waiting.includes(respObj.id)) { toSend.push(respObj); } }); return toSend; } app.post('/:instanceId', async (req, res) => { const apikey = req.headers['X-BatchHttp-Api-Key']; if (apikey !== API_KEY) { res.status(401).send({ error: "Invalid API Key" }); return; } const instanceId = req.params.instanceId; //console.log(`Instance ID: ${instanceId}`); const body = req.body; const requests = body.requests || []; const waiting = body.waiting || [] //console.log(body); requests.forEach(requestObj => { DoRequest(instanceId,requestObj); }); const startTime = Date.now(); let toSend = [] while (toSend.length === 0 && Date.now() - startTime < 1_000) { toSend = getToSend(instanceId, waiting); await new Promise(resolve => setTimeout(resolve, 10)); } console.log(`${toSend.length} responses ready for instance ${instanceId}`); res.send({ responses: toSend }); }) } main();