-
-
Save bpmct/1f7ca6387b3b34ccafdec31a5c88359c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bun | |
| const fs = require("fs"); | |
| const axios = require("axios"); | |
| // Command code for getting events | |
| const COMMAND_GET_EVENTS = 7; | |
| // Load JSON file utility | |
| const loadJson = (path) => { | |
| try { | |
| return fs.existsSync(path) ? JSON.parse(fs.readFileSync(path, "utf8")) : null; | |
| } catch (error) { | |
| console.error(`Error loading ${path}:`, error.message); | |
| return null; | |
| } | |
| }; | |
| // Format timestamp to human-readable form (e.g., "5 seconds ago") | |
| const formatTimestamp = (timestamp) => { | |
| if (!timestamp) return "Never seen"; | |
| const lastSeen = new Date(timestamp); | |
| const now = new Date(); | |
| const diffSec = Math.floor((now - lastSeen) / 1000); | |
| if (diffSec < 60) return `${diffSec} second${diffSec !== 1 ? 's' : ''} ago`; | |
| if (diffSec < 3600) return `${Math.floor(diffSec / 60)} minute${Math.floor(diffSec / 60) !== 1 ? 's' : ''} ago`; | |
| if (diffSec < 86400) return `${Math.floor(diffSec / 3600)} hour${Math.floor(diffSec / 3600) !== 1 ? 's' : ''} ago`; | |
| return `${Math.floor(diffSec / 86400)} day${Math.floor(diffSec / 86400) !== 1 ? 's' : ''} ago`; | |
| }; | |
| // Main function | |
| async function main() { | |
| // Load configuration files | |
| const config = loadJson(`${process.env.HOME}/.config/artemis/config`); | |
| const fleetJson = loadJson("fleet.json"); | |
| const devicesJson = loadJson("devices.json") || {}; | |
| // Exit if required files are missing | |
| if (!config || !fleetJson) { | |
| console.error("Error: Required configuration files missing"); | |
| process.exit(1); | |
| } | |
| // Get authentication token | |
| const accessToken = config.auths?.Artemis?.access_token || config.access_token || config.token; | |
| if (!accessToken) { | |
| console.error("Error: No valid authentication token found"); | |
| process.exit(1); | |
| } | |
| // Get Supabase info | |
| const supabaseUrl = "https://voisfafsfolxhqpkudzd.supabase.co"; | |
| const anonKey = fleetJson.servers?.Artemis?.anon; | |
| const organizationId = config.organization?.default; | |
| try { | |
| // Get device IDs from devices.json | |
| const deviceIds = Object.keys(devicesJson); | |
| if (deviceIds.length === 0) { | |
| console.error("No devices found in devices.json"); | |
| process.exit(1); | |
| } | |
| // Call Supabase binary endpoint for events | |
| const url = `${supabaseUrl}/functions/v1/b`; | |
| const params = { | |
| "_device_ids": deviceIds.map(id => String(id)), | |
| "_limit": 1, | |
| "_types": null | |
| }; | |
| // Create binary payload | |
| const commandBuffer = Buffer.alloc(1); | |
| commandBuffer.writeUint8(COMMAND_GET_EVENTS); | |
| const paramsBuffer = Buffer.from(JSON.stringify(params)); | |
| const payload = Buffer.concat([commandBuffer, paramsBuffer]); | |
| // Make API request | |
| const response = await axios.post(url, payload, { | |
| headers: { | |
| Authorization: `Bearer ${accessToken}`, | |
| "Content-Type": "application/octet-stream", | |
| apikey: anonKey | |
| }, | |
| responseType: "arraybuffer" | |
| }); | |
| // Parse response | |
| const jsonString = Buffer.from(response.data).toString("utf-8"); | |
| const data = JSON.parse(jsonString); | |
| // Process events for each device | |
| const devices = deviceIds.map(deviceId => { | |
| // Extract events for this device | |
| let lastEvent = null; | |
| if (Array.isArray(data)) { | |
| // If response is an array, find events for this device | |
| lastEvent = data.find(event => event.device_id === deviceId); | |
| } else if (data && data[deviceId] && Array.isArray(data[deviceId]) && data[deviceId].length > 0) { | |
| // If response is organized by device ID | |
| lastEvent = data[deviceId][0]; | |
| } | |
| // Get last seen timestamp | |
| const timestamp = lastEvent?.timestamp || lastEvent?.ts || lastEvent?.created_at; | |
| // Pod information | |
| const podVersion = fleetJson.groups?.default?.pod || "my-pod@latest"; | |
| return { | |
| device_id: deviceId, | |
| name: devicesJson[deviceId]?.name || "unknown", | |
| last_seen: timestamp || null, | |
| last_seen_human: timestamp ? formatTimestamp(timestamp) : "Never seen", | |
| never_seen: !timestamp, | |
| pod: { | |
| name: "my-pod", | |
| version: podVersion.includes('@') ? podVersion.split('@')[1] : "latest" | |
| } | |
| }; | |
| }); | |
| // Sort by device name | |
| devices.sort((a, b) => (a.name || "").localeCompare(b.name || "")); | |
| // Output the results | |
| console.log(JSON.stringify({ | |
| organization_id: organizationId, | |
| fleet_id: fleetJson.id, | |
| device_count: devices.length, | |
| devices | |
| }, null, 2)); | |
| } catch (error) { | |
| console.error('Error getting fleet status:', error.message); | |
| process.exit(1); | |
| } | |
| } | |
| main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment