diff --git a/backend/src/api/slack/controllers/slack.js b/backend/src/api/slack/controllers/slack.js index 7986e5d..831ec38 100644 --- a/backend/src/api/slack/controllers/slack.js +++ b/backend/src/api/slack/controllers/slack.js @@ -8,18 +8,46 @@ const fetchImagesFromSlack = require("../services/slack"); const fetch = require("node-fetch"); +let cachedImage = null; +let cacheTimestamp = null; + module.exports = { fetchImages: async (ctx) => { + const CACHE_DURATION = 60 * 1000; // 1 minute + const now = Date.now(); + + if ( + cachedImage && + cacheTimestamp && + now - cacheTimestamp < CACHE_DURATION + ) { + ctx.body = cachedImage; + return; + } try { - const images = await strapi - .service("api::slack.slack") - .fetchImagesFromSlack(); - return ctx.send(images); + const { satName } = ctx.request.body; + + const message = await fetchImagesFromSlack.fetchImagesFromSlack(satName); + cachedImage = { + success: true, + message: { + id: message.files[0].id, + name: message.files[0].name, + permalink_public: message.files[0].permalink_public, + }, + }; + cacheTimestamp = now; + if (message) { + ctx.body = cachedImage; + } else { + ctx.body = { + success: false, + error: "No message found", + }; + } } catch (error) { - return ctx.throw( - 500, - "Error fetching images from Slack: " + error.message - ); + ctx.status = 500; + ctx.body = { error: error.message }; } }, getSharedURL: async (ctx) => { diff --git a/backend/src/api/slack/routes/slack.js b/backend/src/api/slack/routes/slack.js index 73dd28f..b356529 100644 --- a/backend/src/api/slack/routes/slack.js +++ b/backend/src/api/slack/routes/slack.js @@ -6,7 +6,7 @@ module.exports = { routes: [ { - method: "GET", + method: "POST", path: "/slack-images", handler: "slack.fetchImages", config: { diff --git a/backend/src/api/slack/services/slack.js b/backend/src/api/slack/services/slack.js index 148cc2c..01dacbd 100644 --- a/backend/src/api/slack/services/slack.js +++ b/backend/src/api/slack/services/slack.js @@ -7,37 +7,39 @@ const slack = new WebClient(process.env.SLACK_BOT_TOKEN); * slack service */ -let cachedImages = null; -let cacheTimestamp = null; - module.exports = { - fetchImagesFromSlack: async () => { - const CACHE_DURATION = 60 * 1000; // 1 minute - const now = Date.now(); - - if ( - cachedImages && - cacheTimestamp && - now - cacheTimestamp < CACHE_DURATION - ) { - console.log("Returning cached images"); - return cachedImages; - } - + fetchImagesFromSlack: async (satellite) => { try { - const result = await slack.conversations.history({ - channel: process.env.SLACK_CHANNEL_ID, - limit: 15, - }); - console.log("Fetched images from Slack:", result.messages.length); - cachedImages = result.messages.filter( - (msg) => - msg.bot_profile?.name === "hypso1bot" && - msg.files && - msg.files.some((file) => file.mimetype.startsWith("image/")) - ); - cacheTimestamp = now; - return cachedImages; + let cursor = null; + let hasMore = true; + let image = null; + while (hasMore) { + const result = await slack.conversations.history({ + channel: process.env.SLACK_CHANNEL_ID, + limit: 15, + cursor: cursor, + oldest: "0", + inclusive: true, + }); + if (!result.messages || result.messages.length === 0) { + console.log("No messages found in the channel."); + return null; + } + for (const message of result.messages) { + if (message.text && message.text.includes(satellite)) { + if (!image) { + image = message; + break; + } + } + } + hasMore = result.has_more; + cursor = result.response_metadata + ? result.response_metadata.next_cursor + : null; + if (image) break; + } + return image; } catch (error) { console.error("Error fetching images from Slack:", error); throw error; diff --git a/frontend/src/app/satellites/[satelliteSlug]/_infoSat/satImage.tsx b/frontend/src/app/satellites/[satelliteSlug]/_infoSat/satImage.tsx index 68cb0e9..952cd89 100644 --- a/frontend/src/app/satellites/[satelliteSlug]/_infoSat/satImage.tsx +++ b/frontend/src/app/satellites/[satelliteSlug]/_infoSat/satImage.tsx @@ -63,54 +63,52 @@ export default function SatImage({ [], ); + const getMesasgeBySatellite = useCallback( + async (satName: string) => { + const requestDetails = { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + satName: satName, + }), + }; + + const response = await fetch( + STRAPI_URL + "/api/slack-images", + requestDetails, + ); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + return data.message; + }, + [STRAPI_URL], + ); + useEffect(() => { async function fetchSlackImages() { try { setLoading(true); - const response = await fetch(STRAPI_URL + "/api/slack-images"); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - - const data = await response.json(); + const satName = satNumToEntry[noradID as SatelliteNumber]?.name; interface SlackFile { id: number; name: string; permalink_public: string; } - - interface SlackMessage { - text: string; - files: SlackFile[]; - } - - const rightMessage: SlackMessage | undefined = ( - data as SlackMessage[] - ).find((message: SlackMessage) => { - if (noradID !== undefined) { - const satName: string | undefined = - satNumToEntry[noradID as SatelliteNumber]?.name; - if (satName && message.text.includes(satName)) { - return true; - } - } - return false; - }); - if (!rightMessage) { - console.warn("No matching satellite image found."); - setError( - "No matching satellite image found. Try again later when a new image is uploaded.", - ); - return; - } - const rightFile: SlackFile | undefined = rightMessage?.files[0]; - makeTheImagePublic(rightFile?.id as number).catch((err) => { + const message = (await getMesasgeBySatellite( + satName as string, + )) as SlackFile; + makeTheImagePublic(message?.id as number).catch((err) => { console.error("Error making image public:", err); setError("Failed to make image public."); }); const imageUrl = createImageUrl( - rightFile?.permalink_public as string, - rightFile?.name as string, + message?.permalink_public as string, + message?.name as string, ); setSatImage(imageUrl ?? null); } catch (err) { diff --git a/frontend/src/app/satellites/[satelliteSlug]/_infoSat/satTelemetry.tsx b/frontend/src/app/satellites/[satelliteSlug]/_infoSat/satTelemetry.tsx index 5583ea3..58cedbc 100644 --- a/frontend/src/app/satellites/[satelliteSlug]/_infoSat/satTelemetry.tsx +++ b/frontend/src/app/satellites/[satelliteSlug]/_infoSat/satTelemetry.tsx @@ -173,7 +173,7 @@ export default function SatTelemetry({ const chartConfigs = [ { - title: "Battery Voltage", + title: "EPS Battery Voltage", yAxisTitle: "Voltage (V)", series: [ { @@ -185,20 +185,20 @@ export default function SatTelemetry({ valueSuffix: " V", }, { - title: "Battery Current", + title: "EPS Battery Current", yAxisTitle: "Current (A)", series: chartDataIBatt, valueSuffix: " A", }, { - title: "Panel Temperatures", + title: "EPS Panel Temperatures", yAxisTitle: "Temperature (°C)", series: tempPanelChart, valueSuffix: " °C", }, { - title: "Solar Panel Temperatures", + title: "EPS Solar Panel Temperatures", yAxisTitle: "Temperature (°C)", series: solarPanelChartData, valueSuffix: " °C", @@ -206,7 +206,7 @@ export default function SatTelemetry({ "There is that much difference in temperature between some solar panels because those panels point more or less towards the sun.", }, { - title: "Uptime", + title: "EPS Uptime", yAxisTitle: "Uptime (weeks)", series: [ { name: "Uptime", data: chartDataUptime, color: "orange" }, diff --git a/frontend/src/app/satellites/[satelliteSlug]/orbitDataGraph.tsx b/frontend/src/app/satellites/[satelliteSlug]/orbitDataGraph.tsx index 644e69e..6d1407f 100644 --- a/frontend/src/app/satellites/[satelliteSlug]/orbitDataGraph.tsx +++ b/frontend/src/app/satellites/[satelliteSlug]/orbitDataGraph.tsx @@ -38,13 +38,6 @@ const OrbitDataGraph: React.FC = ({ orbitalData }) => { data.semiMajorAxis, ]); - console.log( - "Filtered orbital data:", - filteredData.map((data: ChartData) => [ - data.epoch.getTime(), - parseFloat(data.inclination), - ]), - ); const optChart = createStockChartBaseConfig({ title: "Orbital Graph Data", yAxisArray: [