From 28d21fbd94e517fb52970eb46d80b1e5a606955d Mon Sep 17 00:00:00 2001 From: StarAppeal Date: Mon, 25 Nov 2024 18:06:47 +0100 Subject: [PATCH] add openweathermap api calls and send them to websocket --- package-lock.json | 12 +++++ package.json | 1 + src/db/models/user.ts | 12 ++++- src/db/services/owmApiService.ts | 12 +++++ src/interfaces/extendedWebsocket.ts | 2 +- src/utils/websocket/websocketEventHandler.ts | 47 ++++++++++++++++---- src/websocket.ts | 2 +- 7 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 src/db/services/owmApiService.ts diff --git a/package-lock.json b/package-lock.json index af32973..d065599 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "express": "5.0.0", "jsonwebtoken": "^9.0.2", "mongoose": "^8.8.2", + "openweather-api-node": "^3.1.5", "rimraf": "^5.0.5", "typescript": "^5.3.3", "ws": "8.17.1" @@ -1344,6 +1345,12 @@ "wrappy": "1" } }, + "node_modules/openweather-api-node": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/openweather-api-node/-/openweather-api-node-3.1.5.tgz", + "integrity": "sha512-FGLE0bWOTvp4XHaswmzMfisYMMEtwEwOEJR0vaS07L31OUcutV/UUO5/vRuktkRPoqfk3KZOoqddsRTGTxT7Aw==", + "license": "MIT" + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -3008,6 +3015,11 @@ "wrappy": "1" } }, + "openweather-api-node": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/openweather-api-node/-/openweather-api-node-3.1.5.tgz", + "integrity": "sha512-FGLE0bWOTvp4XHaswmzMfisYMMEtwEwOEJR0vaS07L31OUcutV/UUO5/vRuktkRPoqfk3KZOoqddsRTGTxT7Aw==" + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", diff --git a/package.json b/package.json index c56c715..4967cbb 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "express": "5.0.0", "jsonwebtoken": "^9.0.2", "mongoose": "^8.8.2", + "openweather-api-node": "^3.1.5", "rimraf": "^5.0.5", "typescript": "^5.3.3", "ws": "8.17.1" diff --git a/src/db/models/user.ts b/src/db/models/user.ts index dc65382..c5706ff 100644 --- a/src/db/models/user.ts +++ b/src/db/models/user.ts @@ -10,7 +10,9 @@ export interface IUser { id: ObjectId, config: UserConfig, lastState: MatrixState, - spotifyConfig: SpotifyConfig + spotifyConfig: SpotifyConfig, + timezone: string + location: string } export interface UserConfig { @@ -142,6 +144,14 @@ const userSchema = new mongoose.Schema({ required: true, }, }, + timezone: { + type: String, + required: true, + }, + location: { + type: String, + required: true, + } }); diff --git a/src/db/services/owmApiService.ts b/src/db/services/owmApiService.ts new file mode 100644 index 0000000..cfb8b1c --- /dev/null +++ b/src/db/services/owmApiService.ts @@ -0,0 +1,12 @@ +import OpenWeatherAPI from "openweather-api-node" + +const weather = new OpenWeatherAPI({ + key: process.env.OWM_API_KEY, +}); + +export async function getCurrentWeather(location: string) { + return weather.getCurrent({ + locationName: location, + units: "metric" + }); +} diff --git a/src/interfaces/extendedWebsocket.ts b/src/interfaces/extendedWebsocket.ts index 981deba..ae9c7e0 100644 --- a/src/interfaces/extendedWebsocket.ts +++ b/src/interfaces/extendedWebsocket.ts @@ -6,5 +6,5 @@ export interface ExtendedWebSocket extends WebSocket { payload: DecodedToken; isAlive: boolean; user:IUser; - spotifyUpdate?: NodeJS.Timeout + asyncUpdates?: NodeJS.Timeout } diff --git a/src/utils/websocket/websocketEventHandler.ts b/src/utils/websocket/websocketEventHandler.ts index f7e9f38..4e36998 100644 --- a/src/utils/websocket/websocketEventHandler.ts +++ b/src/utils/websocket/websocketEventHandler.ts @@ -2,6 +2,7 @@ import {ExtendedWebSocket} from "../../interfaces/extendedWebsocket"; import {getCurrentlyPlaying} from "../../db/services/spotifyApiService"; import {SpotifyTokenService} from "../../db/services/spotifyTokenService"; import {UserService} from "../../db/services/db/UserService"; +import {getCurrentWeather} from "../../db/services/owmApiService"; export class WebsocketEventHandler { constructor(private webSocket: ExtendedWebSocket) { @@ -23,9 +24,9 @@ export class WebsocketEventHandler { this.webSocket.onclose = (event) => { console.log("WebSocket closed:", event.code, event.reason, event.wasClean, event.type); console.log(`User: ${this.webSocket.payload.name} disconnected`); - if (this.webSocket.spotifyUpdate) { - clearInterval(this.webSocket.spotifyUpdate); - console.log("Spotify updates stopped"); + if (this.webSocket.asyncUpdates) { + clearInterval(this.webSocket.asyncUpdates); + console.log("Async updates stopped"); } callback(); }; @@ -38,6 +39,15 @@ export class WebsocketEventHandler { const {type} = messageJson; console.log("Received message:", message); + if (type === "GET_SETTINGS") { + this.webSocket.send(JSON.stringify({ + type: "SETTINGS", + payload: { + timezone: this.webSocket.user.timezone, + }, + }), {binary: false}); + } + if (type === "GET_STATE") { const messageToSend = { type: "STATE", @@ -52,16 +62,25 @@ export class WebsocketEventHandler { this.spotifyUpdates() .then(() => { // then set the interval - this.webSocket.spotifyUpdate = setInterval(() => { + this.webSocket.asyncUpdates = setInterval(() => { this.spotifyUpdates(); }, 1000); }); } + if (type === "GET_WEATHER_UPDATES") { + console.log("Starting weather updates"); + this.weatherUpdates().then(() => { + this.webSocket.asyncUpdates = setInterval(() => { + this.weatherUpdates(); + }, 1000 * 60); + } + ) + } - if (type === "STOP_SPOTIFY_UPDATES") { - if (this.webSocket.spotifyUpdate) { - clearInterval(this.webSocket.spotifyUpdate); - console.log("Spotify updates stopped"); + if (type === "STOP_SPOTIFY_UPDATES" || type === "STOP_WEATHER_UPDATES") { + if (this.webSocket.asyncUpdates) { + clearInterval(this.webSocket.asyncUpdates); + console.log("Async updates stopped"); } } @@ -100,4 +119,16 @@ export class WebsocketEventHandler { payload: musicData, }), {binary: false}); } + + private async weatherUpdates() { + console.log("Checking weather") + const user = this.webSocket.user; + const weather = await getCurrentWeather(user.location); + console.log(weather); + + this.webSocket.send(JSON.stringify({ + type: "WEATHER_UPDATE", + payload: weather, + }), {binary: false}); + } } diff --git a/src/websocket.ts b/src/websocket.ts index b741b21..ccee64a 100644 --- a/src/websocket.ts +++ b/src/websocket.ts @@ -59,7 +59,6 @@ export class ExtendedWebSocketServer { socketEventHandler.enablePongEvent(); socketEventHandler.enableMessageEvent(); - // update user every 30 seconds const updateUserInterval = setInterval(async () => { console.log("Updating user") const userService = await UserService.create(); @@ -70,6 +69,7 @@ export class ExtendedWebSocketServer { }, 15000); socketEventHandler.enableDisconnectEvent(() => { clearInterval(updateUserInterval); + console.log("stopped updating user"); }); });