//const { GraphQLClient, gql } = require('graphql-request'); import { GraphQLClient, gql } from 'graphql-request'; async function getStoreDevicesStatus(storeNumber, apiKey) { const endpoint = 'https://graphql-gateway.optisigns.com/graphql'; const client = new GraphQLClient(endpoint, { headers: { Authorization: `Bearer ${apiKey}` }, }); const paddedStore = storeNumber.toString().padStart(6, '0'); const query = gql` query GetDevices($first: Int, $after: String) { devices(query: {}, first: $first, after: $after) { page { edges { node { _id deviceName UUID pairingCode currentType currentAssetId currentPlaylistId localAppVersion lastHeartBeat # Confirmed field! # status # still null in sample, but can keep if it populates sometimes # updatedAt # if you see it later } } pageInfo { hasNextPage endCursor } } } } `; let allDevices = []; let after = null; const pageSize = 50; try { do { const data = await client.request(query, { first: pageSize, after }); allDevices = allDevices.concat(data.devices.page.edges.map(e => e.node)); after = data.devices.page.pageInfo.hasNextPage ? data.devices.page.pageInfo.endCursor : null; } while (after); const storeDevices = allDevices.filter(d => d.deviceName?.includes(paddedStore)); if (storeDevices.length === 0) { return []; } return storeDevices; /* storeDevices.forEach(device => { let statusLine = '• **Playback Status:** Idle / Not playing'; let details = ''; if (device.currentPlaylistId || device.currentAssetId) { const isPlaylist = device.currentType === 'PLAYLIST' || !!device.currentPlaylistId; statusLine = `• **Playback Status:** Active - Playing content (${isPlaylist ? 'Playlist' : 'Asset/Single'})`; details = `\n - Assigned ID: ${device.currentPlaylistId || device.currentAssetId || 'N/A'}\n - Type: ${device.currentType || 'unknown'}\n - App Version: ${device.localAppVersion || 'N/A'}`; } // Heartbeat / Connectivity Status let heartbeatInfo = ''; if (device.lastHeartBeat) { const hbDate = new Date(device.lastHeartBeat); const now = new Date(); // Current time in UTC, then we'll adjust display const minutesAgo = Math.round((now - hbDate) / 60000); const hbLocal = hbDate.toLocaleString('en-US', { timeZone: 'America/New_York' }); heartbeatInfo = `\n - Last Heartbeat: ${hbLocal} (${minutesAgo} min ago)`; if (minutesAgo <= 10) { heartbeatInfo += ' 🟢 **Online & checking in** (likely synced)'; } else if (minutesAgo <= 30) { heartbeatInfo += ' 🟡 **Possibly delayed**'; } else { heartbeatInfo += ' 🔴 **Offline / not checking in**'; } } else { heartbeatInfo = '\n - No heartbeat data available'; } md += `**${device.deviceName}** (${device.UUID.substring(0, 8)}...)\n`; md += `${statusLine}\n`; md += `${details}${heartbeatInfo}\n\n`; }); md += `**Last checked:** ${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} EST\n`; md += `(via OptiSigns API)`; console.log(md); return md; */ } catch (error) { const errMd = `**Error:** ${error.message}`; console.error(errMd); return errMd; } } // Example usage const apiKey = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJnaEF3SEhKdTdkS3RmcEdkTSIsImNpZCI6Ilk2cXlaZXAzSE1NeHBuYXRMIiwiYWlkIjoidHh1NGhUcnZEMkdaM25tOU0iLCJpYXQiOjE3NDc0MTAxNjgsImV4cCI6MTc0NzQxMzc2OCwiaXNzIjoidHh1NGhUcnZEMkdaM25tOU0ifQ.TZRzzV6-QejdW4H3vppeypzExv4ppHdIKHSHpZXbKmpDhktlWrOQLQf4sNeX-UPa0bKKQcp9b8qHGpeu163bhmQAnnkWROqMD2z8tZ2kKgW34iXH5B_Ur1TbylvUS_ZsfFDQiUnT1Lf9waMAhZJeYKP4j70ak7BclMFf7XMGNGy75vSknzi1x7nvB1AOS5kEcPIV_oZNXlBVLLnEM1t3Edk6K-jXDmR_XHqN0lI3t0NX0yr2VTgt2KSqDRPaGcNBmuXHUgeB8xsEW4Dlk8rIin7qW4WkrvycnjyL2ZpT9EFZWYjaQNyJoTmJjxeywl9JrzrO1sIoYJ0QdHAOmgsnIDiYnw_eR73Mi0l3QUC9fZfgD91gidwKMWt3LIm4KCkynRNPOlBz7UGTp_wb4qCSFCNiYB6fGhWT1u7rcoR1g7sCHwCX6pkSMhKs1ZSOprTZSUFeFloqE3ufCNACQMa5I8QYi4Lz7KdEOn9yK2UM13Te1Shs3fD2HS23pyiLjznBMQg9z5TWTzbPWteR7FyKIRZjtdF1Foe5BJp-EmN_FR74Ndz1lo-0b10stszQE18ob9HSWsmWu_Tqg_KG4wBxOzKM-V8Eksx4eFyHeh8lzGXESzH2pGYfs7M3Y5Dvy1a3Hy9Xh7O0n82EW9MUHTXiny3yycD9vuUyG4FNQ7K2NuY'; // Replace with your actual key const storeNumber = "002248"; const deviceName = 'US000629VW02'; // Replace with your device name (e.g., incorporating the 6-digit store number) getStoreDevicesStatus(storeNumber, apiKey);