Files
intelligence-terminal/apis/sources/who.mjs
calesthio ef2c6470fb Initial release — Crucix Intelligence Engine v2.0.0
26-source OSINT intelligence engine with live Jarvis dashboard,
auto-refresh via SSE, optional LLM layer (4 providers), delta/memory
system, and Telegram breaking news alerts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:45:46 -07:00

90 lines
2.8 KiB
JavaScript

// WHO — World Health Organization Global Health Observatory
// No auth required. Disease outbreak monitoring.
import { safeFetch } from '../utils/fetch.mjs';
const GHO_BASE = 'https://ghoapi.azureedge.net/api';
const DON_API = 'https://www.who.int/api/news/diseaseoutbreaknews';
// Get GHO indicator data
export async function getIndicator(code, opts = {}) {
const { filter = '', top = 20 } = opts;
let url = `${GHO_BASE}/${code}?$top=${top}&$orderby=TimeDim desc`;
if (filter) url += `&$filter=${filter}`;
return safeFetch(url);
}
// Key health indicators
const INDICATORS = {
MDG_0000000020: 'TB incidence (per 100k)',
MALARIA_EST_CASES: 'Malaria estimated cases',
WHOSIS_000001: 'Life expectancy at birth',
UHC_INDEX_REPORTED: 'UHC Service Coverage Index',
};
// Get Disease Outbreak News via WHO JSON API
// The old RSS feed at /feeds/entity/don/en/rss.xml returns 404.
// This JSON endpoint returns ~50 items; OData $orderby is ignored by
// the server, so we sort client-side by PublicationDate descending.
export async function getOutbreakNews() {
try {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 15000);
const res = await fetch(DON_API, {
signal: controller.signal,
headers: { 'User-Agent': 'Crucix/1.0' },
});
clearTimeout(timer);
if (!res.ok) {
const body = await res.text().catch(() => '');
throw new Error(`HTTP ${res.status}: ${body.slice(0, 200)}`);
}
const data = await res.json();
const items = data?.value || [];
// Sort by PublicationDate descending (server ignores $orderby)
items.sort((a, b) => {
const da = new Date(a.PublicationDate || 0);
const db = new Date(b.PublicationDate || 0);
return db - da;
});
return items.map(item => ({
title: item.Title,
date: item.PublicationDate,
donId: item.DonId || null,
url: item.ItemDefaultUrl
? `https://www.who.int/emergencies/disease-outbreak-news${item.ItemDefaultUrl}`
: null,
summary: (item.Summary || item.Overview || '').replace(/<[^>]*>/g, '').slice(0, 300) || null,
}));
} catch (e) {
return { error: e.message };
}
}
// Briefing
export async function briefing() {
const outbreaks = await getOutbreakNews();
return {
source: 'WHO',
timestamp: new Date().toISOString(),
diseaseOutbreakNews: Array.isArray(outbreaks) ? outbreaks.slice(0, 15) : [],
outbreakError: Array.isArray(outbreaks) ? null : outbreaks.error,
monitoringCapabilities: [
'Disease Outbreak News (DONs)',
'Global health indicators (GHO)',
'Pandemic early warning signals',
'Cross-reference with GDELT health event mentions',
],
};
}
if (process.argv[1]?.endsWith('who.mjs')) {
const data = await briefing();
console.log(JSON.stringify(data, null, 2));
}