import { COIN_KEYWORDS } from './watchlist'; export interface TruthPost { url: string; ts: number; // Unix ms text: string; } const esc = (s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); /** RSS-Items per Regex (kein XML-Parser nötig — Feed ist flach und stabil). */ export function parseTruthFeed(xml: string): TruthPost[] { const posts: TruthPost[] = []; for (const item of xml.match(/[\s\S]*?<\/item>/g) ?? []) { const url = item.match(/([^<]+)<\/link>/)?.[1]?.trim(); const pubDate = item.match(/([^<]+)<\/pubDate>/)?.[1]; const descRaw = item.match(/([\s\S]*?)<\/description>/)?.[1] ?? ''; if (!url || !pubDate) continue; const ts = Date.parse(pubDate); if (Number.isNaN(ts)) continue; const text = descRaw .replace(/^$/g, '') .replace(/<[^>]+>/g, ' ') .replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'").replace(/ /g, ' ') .replace(/\s+/g, ' ') .trim(); posts.push({ url, ts, text }); } return posts; } /** Erwähnte Coins (Symbole, dedupliziert, in COIN_KEYWORDS-Reihenfolge). */ export function matchCoins(text: string): string[] { const hits: string[] = []; for (const c of COIN_KEYWORDS) { const nameHit = c.names.some((n) => new RegExp(`\\b${esc(n)}\\b`, 'i').test(text)); const tickerHit = c.tickers.some((t) => new RegExp(`\\b${esc(t)}\\b`).test(text)); // case-sensitive if (nameHit || tickerHit) hits.push(c.symbol); } return hits; }