import axios from "axios"; import express, { json, query } from "express"; import Queue from "bull"; import Bottleneck from "bottleneck"; const app = express(); app.use(json()); const requestQueue = new Queue("request-queue"); const limiter = new Bottleneck({ maxConcurrent: 2, // Number of concurrent requests minTime: 1, // Minimum time between requests (in milliseconds) }); async function sendRequest(data) { const botToken = data.botToken; const chatId = data.chatId; const text = data.text; try { const response = await axios.post( `https://api.telegram.org/bot${botToken}/sendMessage`, { chat_id: chatId, text: text, } ); } catch (error) { console.error( "Error:", error.response ? error.response.data : error.message ); } } requestQueue.process(async (job) => { try { const result = await limiter.schedule(() => sendRequest(job.data)); return result; } catch (error) { throw new Error(`Request failed: ${error.message}`); } }); // Handle job completion requestQueue.on("completed", (job) => { console.log(`Job ${job.id} completed successfully.`); }); // Handle job failure and retry requestQueue.on("failed", (job, error) => { console.log(`Job ${job.id} failed with error: ${error.message}`); if (job.attemptsMade < 3) { // Retry up to 3 times job.retry(); } else { console.error( `Job ${job.id} moved to dead-letter queue after ${job.attemptsMade} attempts` ); } }); app.get("/bot:token/*", async (req, res) => { const url = req.url const botTokenEndIndex = url.indexOf("/", 1) const botToken = url.substring(4, botTokenEndIndex) const queryParams = req.query; const data = { botToken: botToken, chatId: queryParams.chat_id, text: queryParams.text, }; try { const job = await requestQueue.add(data, { attempts: 3, backoff: 5000, }); res.status(202).send({ jobId: job.id }); } catch (error) { res.status(500).send({ error: error.message }); } }); // Endpoint to add a request to the queue app.post("/sendMessage", async (req, res) => { try { const job = await requestQueue.add(req.body, { attempts: 3, backoff: 5000, }); res.status(202).send({ jobId: job.id }); } catch (error) { res.status(500).send({ error: error.message }); } }); // Start the server app.listen(3000, () => { console.log("Microservice listening on port 3000"); });