import express, { Request, Response } from "express"; import { container } from "tsyringe"; import { validateData } from "../middleware/validationMiddleware"; import { TtnMessage } from "../models/ttnMessage"; import { LocationService } from "../services/locationService"; import { LpTtnEndDeviceUplinksService } from "../services/lpTtnEndDeviceUplinksService"; import { TtnGatewayReceptionService } from "../services/ttnGatewayReceptionService"; import { WifiScanService } from "../services/wifiScanService"; import { ttnMessageValidator } from "../validation/ttn/ttnMessageValidation"; const lpTtnEndDeviceUplinksService = container.resolve( LpTtnEndDeviceUplinksService ); const ttnGatewayReceptionService = container.resolve( TtnGatewayReceptionService ); const wifiScanService = container.resolve(WifiScanService); const locationService = container.resolve(LocationService); const router = express.Router(); router.post( "/webhook", validateData(ttnMessageValidator), async (req: Request, res: Response) => { try { const authorizationHeader = req.headers['authorization']; if (!authorizationHeader) { console.log("Authorization header is missing!"); res.status(401).json({ error: "Authentication failed" }); return; } else { const token = authorizationHeader.split(' ')[1]; // Get the token after 'Bearer' if (!token) { console.log("Bearer token is missing!"); res.status(401).json({ error: "Authentication failed" }); return; } else { console.log(token) if (token !== process.env.WEBHOOK_TOKEN) { console.log("Bearer token is wrong!"); res.status(401).json({ error: "Authentication failed" }); return; } else { console.log("Bearer token is correct!"); } } } } catch (error) { console.log(error); res.status(401).json({ error: "Authentication failed" }); return; } try { const message = req.body as TtnMessage; const { lp_ttn_end_device_uplinks_id } = await lpTtnEndDeviceUplinksService.createUplink({ device_id: message.end_device_ids.device_id, application_ids: message.end_device_ids.application_ids.application_id, dev_eui: message.end_device_ids.dev_eui, join_eui: message.end_device_ids.join_eui, dev_addr: message.end_device_ids.dev_addr, received_at_utc: new Date(message.received_at), battery: message.uplink_message.decoded_payload?.messages[0].find( (e) => e.type === "Battery" )?.measurementValue, }); const gnnsLocation = { latitude: message.uplink_message.decoded_payload?.messages[0].find( (e) => e.type === "Latitude" )?.measurementValue, longitude: message.uplink_message.decoded_payload?.messages[0].find( (e) => e.type === "Longitude" )?.measurementValue, }; const wifiScans = message.uplink_message.decoded_payload?.messages[0] .find((e) => e.type === "Wi-Fi Scan") ?.measurementValue?.map((w) => ({ lp_ttn_end_device_uplinks_id, mac: w.mac, rssi: w.rssi, })) ?? []; console.log(wifiScans); const ttnGatewayReceptions = message.uplink_message.rx_metadata.map( (g) => ({ lp_ttn_end_device_uplinks_id, gateway_id: g.gateway_ids.gateway_id, eui: g.gateway_ids.eui, rssi: g.rssi, latitude: g.location?.latitude, longitude: g.location?.longitude, altitude: g.location?.altitude, }) ); const createDatabaseEntries = async () => { const [wifiResults, gatewayResults] = await Promise.all([ wifiScanService.createWifiScans(wifiScans), ttnGatewayReceptionService.filterAndInsertGatewayReception( ttnGatewayReceptions ), ]); locationService.createLocationFromTriangulation({ lp_ttn_end_device_uplinks_id, wifi: wifiResults.map(({ latitude, longitude, rssi }) => ({ latitude, longitude, rssi, })), ttn_gw: gatewayResults.map(({ latitude, longitude, rssi }) => ({ latitude, longitude, rssi, })), gnss: gnnsLocation.latitude && gnnsLocation.longitude ? { latitude: gnnsLocation.latitude, longitude: gnnsLocation.longitude, } : undefined, }); }; createDatabaseEntries().then(); res.status(200); } catch (error) { console.log(error); res.status(500).json({ error: "Error creating uplink" }); } } ); export default router;