
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
@telemetryx/sdk
Advanced tools
The official TelemetryX application API package. Use it to build applications that run on the TelemetryX platform
Welcome to the TelemetryX Applications SDK! This document will guide you through building applications for TelemetryX.
TelemetryX is a platform for running web applications on devices connected to displays, such as TVs and touch screen kiosks. It can manage thousands of devices per account, enabling organizations to create, manage, and deploy dynamic content and interactive applications across their physical locations.
Key features of the platform include:
Standard applications are web applications that run within TelemetryX's Freeform Editor. The Freeform Editor is our default visual content composition tool that allows users to create layouts by positioning applications alongside media, text, and other visual elements.
Your standard application will be embedded as an iframe within the Freeform Editor and can be positioned, resized, and scheduled as part of content playlists that display on physical devices like digital signage and kiosks.
Standard applications define mount points in their telemetry.config.json
file:
settings
- The configuration interface that appears in the Freeform Editor's sidebar when your application is selected. This runs in the administration UI where customers configure your app.render
- The actual content that displays on devices and in the Freeform Editor's canvas. This is what end users see.And optionally a worker script:
background
- A worker that runs continuously in the background, even when your application is not currently visible in the playlist rotation.Since your application runs within the Freeform Editor, you get additional capabilities:
To get started, add the SDK to your project:
With npm:
npm install @telemetryx/sdk
Or include it directly in your HTML:
<script src="https://cdn.jsdelivr.net/npm/@telemetryx/sdk"></script>
Import and configure the SDK with your application name:
import { configure } from '@telemetryx/sdk';
// Initialize the SDK - call this early in your application lifecycle
// The application name must match the name in your telemetry.config.json
configure('myAppName')
Or using the global object if you included the script directly:
telemetry.configure('myAppName')
The SDK automatically extracts the application ID from URL parameters, which is essential for proper functioning of the store's local and deviceLocal scopes.
The SDK provides a powerful storage system with multiple scopes:
The applicationId
is automatically provided when your application is embedded, ensuring that multiple instances of your app maintain separate configurations.
Example usage:
import { store } from '@telemetryx/sdk';
// Global scope - shared across all instances of your app
await store().global.set('companyBranding', { logo: 'url', colors: {...} });
// Local scope - specific to this app instance
await store().local.set('city', 'New York');
// DeviceLocal scope - stays on this device only
await store().deviceLocal.set('calibrationData', { brightness: 0.8 });
// Shared scope - communicate with other applications
await store().shared.set('weather-data', 'temperature', '72°F');
// Subscribe to changes for real-time updates
const cityHandler = (newCity) => {
console.log(`City updated to: ${newCity}`);
updateWeatherDisplay(newCity);
};
store().local.subscribe('city', cityHandler);
// Clean up subscriptions when no longer needed
store().local.unsubscribe('city', cityHandler);
Store subscriptions are essential for real-time applications. When a setting is changed (e.g., in the settings mount point), the render mount point will receive immediate updates through store subscriptions.
Applications can discover and embed other applications:
import { applications } from '@telemetryx/sdk';
// Find all applications with a specific mount point
const widgets = await applications().getAllByMountPoint('dashboard-widget');
// Get URL for embedding an application
const url = await applications().getUrl('weather-app', 'render');
// Use this URL in an iframe to embed the application
const iframe = document.createElement('iframe');
iframe.src = url;
document.body.appendChild(iframe);
Access media content uploaded to TelemetryX:
import { media } from '@telemetryx/sdk';
// Get media folders by tag
const folders = await media().getFoldersByTag('marketing');
// Get content from a folder
const content = await media().getMediaContentByFolderId(folderId);
// Access the media file URLs
const mediaItem = await media().getMediaContentById(mediaId);
// Use this URL to display/play the media
const publicUrl = mediaItem.publicUrls[0];
Access information about the current account and user:
import { accounts, users } from '@telemetryx/sdk';
// Get current account
const account = await accounts().getCurrent();
// Get current user
const userResult = await users().getCurrent();
const userId = userResult.user.id;
Control the Freeform Editor's playlist state, allowing your application to navigate through playlist pages and modify timing:
import { playlist } from '@telemetryx/sdk';
// Move to the next page in the playlist
await playlist().nextPage();
// Move to the previous page in the playlist
await playlist().previousPage();
// Set the duration for the current page (in seconds)
await playlist().setDuration(30);
Manage content overrides within the Freeform Editor to temporarily display specific content:
import { overrides } from '@telemetryx/sdk';
// Set an override to display specific content
await overrides().setOverride('emergency-alert');
// Clear an existing override
await overrides().clearOverride('emergency-alert');
The SDK uses a request-response pattern for most operations. All requests have a 30-second timeout by default to prevent hanging promises:
try {
const result = await someAsyncSdkOperation();
// Handle successful result
} catch (error) {
// Handle timeout or other errors
console.error('Operation failed:', error.message);
}
Your applications automatically work offline without any additional code. TelemetryX handles caching for you:
This means users can interact with your application even when devices lose internet connectivity.
Worker scripts run in the background even when your application isn't currently visible in the playlist rotation. For standard applications, they start automatically when a playlist containing your application is loaded (on devices) or opened for editing (in the administration UI). Define them in your telemetry.config.json
:
{
"name": "my-application",
"version": "1.0.0",
"workers": [
{
"script": "./workers/background-sync.js"
}
]
}
Worker scripts can access the SDK by importing and configuring it just like the main application. They're ideal for:
Containers allow you to run more complex backend services alongside your application. They run in a local Docker instance, with traffic to specific hostnames automatically tunneled to the appropriate container.
Define containers in your telemetry.config.json
:
{
"name": "my-application",
"version": "1.0.0",
"containers": [
{
"name": "my-backend",
"image": "mybackend:latest",
"port": 3000
}
]
}
Access the container from your application (containers only run on devices):
// Container name becomes hostname - requests to my-backend are routed to your container
fetch('https://my-backend/api/data')
.then(response => response.json())
.then(data => console.log(data));
// Your app should handle cases where containers aren't available (e.g., in administration UI)
telemetry.config.json
ConfigurationYour application must include a telemetry.config.json
file at the root level:
{
"name": "my-application",
"version": "1.0.0",
"displayName": "My Application",
"description": "A TelemetryX application that does amazing things",
"mountPoints": {
"render": {
"path": "/render"
},
"settings": {
"path": "/settings"
}
},
"workers": [
{
"name": "background",
"script": "./workers/background.js"
}
],
"containers": []
}
This configuration:
Store Usage
Application Structure
Performance
Error Handling
Responsive Design
This section provides structured examples of common implementation patterns to help you build effective TelemetryX applications.
postMessage
API for communication with TelemetryX.configure()
before using any SDK features.import { media } from '@telemetryx/sdk';
async function displayMedia(mediaId) {
const mediaItem = await media().getMediaContentById(mediaId);
const mediaElement = document.createElement('img');
mediaElement.src = mediaItem.publicUrls[0];
document.body.appendChild(mediaElement);
}
import { store } from '@telemetryx/sdk';
// In settings mount point
async function saveSettings(city) {
await store().local.set('city', city);
}
// In render mount point
function setupSettingsListener() {
store().local.subscribe('city', (city) => {
updateWeatherDisplay(city);
});
// Initial load
store().local.get('city').then(city => {
if (city) updateWeatherDisplay(city);
});
}
import { applications } from '@telemetryx/sdk';
async function embedWeatherWidget(containerId) {
const url = await applications().getUrl('weather-app', 'render');
const container = document.getElementById(containerId);
const iframe = document.createElement('iframe');
iframe.src = url;
iframe.style.border = 'none';
iframe.style.width = '100%';
iframe.style.height = '100%';
container.appendChild(iframe);
}
// In worker.js - defined in telemetry.config.json
import { configure, store } from '@telemetryx/sdk';
configure('myApp');
// Run periodic synchronization
async function syncData() {
try {
const data = await fetchExternalData();
await store().global.set('latestData', data);
} catch (error) {
console.error('Sync failed:', error);
}
// Schedule next sync
setTimeout(syncData, 60000);
}
// Start sync process
syncData();
Always implement proper error handling for SDK operations:
try {
const result = await media().getFoldersByTag('marketing');
displayFolders(result);
} catch (error) {
// Check for timeout errors
if (error.message.includes('timed out')) {
showTimeoutMessage();
} else {
showGenericError();
}
// Provide fallback content or retry strategy
displayCachedContent();
}
// In settings.js (settings mount point)
import { configure, store } from '@telemetryx/sdk';
configure('weather-app');
document.getElementById('cityForm').addEventListener('submit', async (e) => {
e.preventDefault();
const city = document.getElementById('cityInput').value;
await store().local.set('city', city);
showSuccessMessage('City saved successfully');
});
// Initial load of current value
store().local.get('city').then(city => {
if (city) {
document.getElementById('cityInput').value = city;
}
});
// In render.js (render mount point)
import { configure, store } from '@telemetryx/sdk';
configure('weather-app');
// Subscribe to city changes
store().local.subscribe('city', (city) => {
if (city) {
fetchAndDisplayWeather(city);
} else {
showConfigurationMessage();
}
});
// Initial load
store().local.get('city').then(city => {
if (city) {
fetchAndDisplayWeather(city);
} else {
showConfigurationMessage();
}
});
async function fetchAndDisplayWeather(city) {
try {
const weather = await fetchWeatherData(city);
renderWeatherUI(weather);
} catch (error) {
showErrorMessage('Could not load weather data');
}
}
import { configure, applications } from '@telemetryx/sdk';
configure('dashboard-app');
async function initializeDashboard() {
try {
// Discover all dashboard widget applications
const widgets = await applications().getAllByMountPoint('dashboard-widget');
if (widgets.length === 0) {
showNoWidgetsMessage();
return;
}
const container = document.getElementById('widgetsContainer');
// Create a grid layout for widgets
for (const widget of widgets) {
const widgetElement = document.createElement('div');
widgetElement.className = 'widget-container';
// Get embeddable URL for this widget
const url = await applications().getUrl(widget.name, 'dashboard-widget');
// Create and configure iframe
const iframe = document.createElement('iframe');
iframe.src = url;
iframe.title = widget.name;
iframe.frameBorder = '0';
iframe.style.width = '100%';
iframe.style.height = '100%';
widgetElement.appendChild(iframe);
container.appendChild(widgetElement);
}
} catch (error) {
console.error('Failed to initialize dashboard:', error);
showErrorMessage();
}
}
// Initialize dashboard when DOM is ready
document.addEventListener('DOMContentLoaded', initializeDashboard);
For more information or support, please visit our documentation or contact our support team.
Happy building!
FAQs
The official TelemetryX application API package. Use it to build applications that run on the TelemetryX platform
The npm package @telemetryx/sdk receives a total of 264 weekly downloads. As such, @telemetryx/sdk popularity was classified as not popular.
We found that @telemetryx/sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.