utility-api/routes/price-history.min.js

2 lines
2.5 KiB
JavaScript

const express=require("express"),router=express.Router(),cron=require("node-cron"),axios=require("axios"),fs=require("fs"),path=require("path"),csv=require("csv-parser"),PriceHistory=require("../models/price-history");function logWithTimestamp(e){console.log(`[${(new Date).toISOString()}] ${e}`)}function errorWithTimestamp(e,t){console.error(`[${(new Date).toISOString()}] ERROR: ${e}`,t)}function parseDateString(e){const t=e.split("-"),r=parseInt(t[0]),s=parseInt(t[1])-1,a=parseInt(t[2]);return new Date(r,s,a).setHours(0,0,0,0)}async function fetchBtcPrices(){try{const e=(await axios.get("https://bitpay.com/api/rates")).data,t=e.find((e=>"USD"===e.code&&"US Dollar"===e.name)).rate;return{usd:t,inr:e.find((e=>"INR"===e.code&&"Indian Rupee"===e.name)).rate}}catch(e){return errorWithTimestamp("Error fetching BTC prices from BitPay:",e),null}}async function updateDailyAverage(e){const t=new Date;t.setHours(0,0,0,0);try{const r=await PriceHistory.findOne({date:t,asset:"btc"});if(r){const s=(r.usd*r.count+e.usd)/(r.count+1),a=(r.inr*r.count+e.inr)/(r.count+1);await PriceHistory.updateOne({date:t,asset:"btc"},{$set:{usd:s,inr:a,count:r.count+1}})}else await PriceHistory.create({date:t,asset:"btc",usd:e.usd,inr:e.inr,count:1});logWithTimestamp("Daily average updated successfully.")}catch(e){errorWithTimestamp("Error updating daily average:",e)}}async function collectAndUpdatePrices(){const e=await fetchBtcPrices();e&&await updateDailyAverage(e)}router.get("/",(async(e,t)=>{try{let{from:r,to:s,on:a,limit:i=100,asset:n="btc",currency:c,sort:o,dates:d}=e.query;const u={asset:n};if(r&&s&&(r=parseDateString(r),s=parseDateString(s),r>s)){const e=r;r=s,s=e}if(r&&(u.date={$gte:r}),s&&(u.date={...u.date,$lte:s}),d){const e=d.split(",").map((e=>parseDateString(e.trim())));u.date={$in:e}}if(a){const e=parseDateString(a);u.date={$eq:e}}if(c&&(u[c]={$exists:!0}),o){if(!["asc","desc","ascending","descending","1","-1"].includes(o))return t.status(400).json({error:"Invalid sort. Valid values are asc | desc | ascending | descending | 1 | -1"});o={date:"asc"===o||"ascending"===o||"1"===o?1:-1}}else o={date:-1};const l={_id:0,__v:0,asset:0};"inr"===c&&(l.usd=0),"usd"===c&&(l.inr=0);const p=await PriceHistory.find(u,l).sort(o).limit("all"===i?0:parseInt(i)).lean();if(!p||0===p.length)return t.status(404).json({message:"No data found"});t.json(p)}catch(e){errorWithTimestamp("Error serving data",e),t.status(500).json({error:e})}})),cron.schedule("0 */4 * * *",(async()=>{logWithTimestamp("Starting price collection for daily averaging..."),await collectAndUpdatePrices()})),module.exports=router;