Overview
Stratolink uses webhooks to receive telemetry data from The Things Network (TTN). The system processes incoming data and stores it in Supabase for real-time dashboard visualization.
TTN Webhook Integration
Endpoint
POST https://your-domain.com/api/ttn-webhookConfiguration
Configure the webhook in The Things Network Console:
- Navigate to Applications → Your Application → Integrations → Webhooks
- Add a new webhook with format: JSON
- Set the webhook URL to your deployed endpoint
- Save the configuration
Webhook Payload
The webhook receives JSON payloads from TTN with the following structure:
{
"end_device_ids": {
"device_id": "balloon-001",
"dev_eui": "...",
"application_ids": {
"application_id": "..."
}
},
"received_at": "2024-01-01T12:00:00Z",
"uplink_message": {
"frm_payload": "base64_encoded_payload",
"decoded_payload": {
"lat": 40.7128,
"lon": -74.0060,
"altitude_m": 30000,
"battery_voltage": 3.72,
"temperature": -45.2,
"pressure": 120.5
},
"rx_metadata": [{
"rssi": -112,
"snr": 8.5
}]
}
}Payload Decoding
The webhook handler automatically decodes base64-encoded payloads. Ensure your firmware encodes telemetry data in a format compatible with the decoder in web/app/api/ttn-webhook/route.ts.
Data Storage
Telemetry data is stored in Supabase with the following schema:
Telemetry Table
CREATE TABLE telemetry (
id BIGSERIAL PRIMARY KEY,
device_id TEXT NOT NULL,
time TIMESTAMPTZ NOT NULL,
lat DOUBLE PRECISION NOT NULL,
lon DOUBLE PRECISION NOT NULL,
altitude_m DOUBLE PRECISION,
battery_voltage DOUBLE PRECISION,
temperature DOUBLE PRECISION,
pressure DOUBLE PRECISION,
rssi DOUBLE PRECISION,
velocity_x DOUBLE PRECISION,
velocity_y DOUBLE PRECISION,
raw_payload JSONB,
location GEOGRAPHY(POINT, 4326)
);Querying Data
Access telemetry data directly from Supabase using SQL or the Supabase client libraries.
Example: Get Latest Telemetry
SELECT * FROM telemetry
WHERE device_id = 'balloon-001'
ORDER BY time DESC
LIMIT 1;Example: Get Flight Path
SELECT lat, lon, time, altitude_m
FROM telemetry
WHERE device_id = 'balloon-001'
AND time >= NOW() - INTERVAL '24 hours'
ORDER BY time ASC;Example: Active Balloons
SELECT DISTINCT device_id
FROM telemetry
WHERE time >= NOW() - INTERVAL '2 hours'
AND altitude_m > 100;Supabase Client Integration
Use the Supabase JavaScript client to query data programmatically:
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
);
// Query latest telemetry
const { data, error } = await supabase
.from('telemetry')
.select('*')
.eq('device_id', 'balloon-001')
.order('time', { ascending: false })
.limit(1);Security
- Webhook endpoints should validate incoming requests
- Use Supabase Row Level Security (RLS) policies to control data access
- Never expose service role keys in client-side code
- Validate and sanitize all incoming telemetry data
Rate Limiting
Consider implementing rate limiting for webhook endpoints to prevent abuse. Vercel provides built-in rate limiting for API routes.
Need Help?
For integration support, check the troubleshooting guide or contact us.