45af56d9cf
Also added: - Memory API endpoints - Briefs API endpoints - AnveVoice stats API - Claude spawn API - TTS proxy - Cleopatra voice widget - api-auth middleware
104 lines
3.1 KiB
TypeScript
104 lines
3.1 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import fs from "fs";
|
|
import path from "path";
|
|
|
|
const API_SECRET = process.env.API_SECRET || 'horus-mc-secret-2026';
|
|
const STORAGE_FILE = path.join(process.cwd(), "data", "morning_briefs.json");
|
|
|
|
const DISCORD_BOT_TOKEN = process.env.DISCORD_BOT_TOKEN || "MTQ3MTk4OTUzNjE1MzQwMzU5Nw.Ghtj4n.g-tl-Ijhfn9cg6zUCUIVd94EdwL32KmlVgRoSc";
|
|
const MORNING_CHANNEL = "1476344610493042698";
|
|
|
|
function ensureStorage() {
|
|
const dir = path.dirname(STORAGE_FILE);
|
|
if (!fs.existsSync(dir)) {
|
|
fs.mkdirSync(dir, { recursive: true });
|
|
}
|
|
if (!fs.existsSync(STORAGE_FILE)) {
|
|
fs.writeFileSync(STORAGE_FILE, "[]");
|
|
}
|
|
}
|
|
|
|
function getBriefs() {
|
|
ensureStorage();
|
|
return JSON.parse(fs.readFileSync(STORAGE_FILE, "utf-8"));
|
|
}
|
|
|
|
function saveBriefs(data: any[]) {
|
|
ensureStorage();
|
|
fs.writeFileSync(STORAGE_FILE, JSON.stringify(data, null, 2));
|
|
}
|
|
|
|
function formatMorningBrief(data: any): string {
|
|
return `☀️ MORNING BRIEF - ${data.date || new Date().toISOString().split('T')[0]}
|
|
|
|
🌤️ WEATHER
|
|
${data.weather || 'N/A'}
|
|
|
|
📊 MARKET
|
|
BTC: $${data.market?.BTC || 'N/A'} (${data.market?.btcChange || '0%'})
|
|
ETH: $${data.market?.ETH || 'N/A'} (${data.market?.ethChange || '0%'})
|
|
SOL: $${data.market?.SOL || 'N/A'} (${data.market?.solChange || '0%'})
|
|
|
|
🎯 PRIORITIES
|
|
${(data.priorities || []).map((p: string, i: number) => `${i + 1}. ${p}`).join('\n')}
|
|
|
|
💰 GOAL: ${data.goal || 'N/A'}
|
|
|
|
🔥 HOT LEADS
|
|
${(data.leads || []).map((l: string) => `- ${l}`).join('\n')}`;
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
// Check auth
|
|
const authHeader = request.headers.get('authorization');
|
|
if (authHeader !== `Bearer ${API_SECRET}`) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
const briefs = getBriefs();
|
|
return NextResponse.json(briefs);
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
// Check auth
|
|
const authHeader = request.headers.get('authorization');
|
|
if (authHeader !== `Bearer ${API_SECRET}`) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
try {
|
|
const body = await request.json();
|
|
|
|
const brief = {
|
|
id: `morning-${Date.now()}`,
|
|
date: body.date || new Date().toISOString().split('T')[0],
|
|
weather: body.weather,
|
|
market: body.market,
|
|
priorities: body.priorities || [],
|
|
goal: body.goal,
|
|
leads: body.leads || [],
|
|
created_at: new Date().toISOString()
|
|
};
|
|
|
|
const briefs = getBriefs();
|
|
briefs.unshift(brief);
|
|
saveBriefs(briefs);
|
|
|
|
// Send to Discord
|
|
const discordMessage = formatMorningBrief(body);
|
|
await fetch(`https://discord.com/api/v10/channels/${MORNING_CHANNEL}/messages`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Authorization": `Bot ${DISCORD_BOT_TOKEN}`,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({ content: discordMessage }),
|
|
});
|
|
|
|
return NextResponse.json({ success: true, brief });
|
|
} catch (error) {
|
|
console.error("Morning brief error:", error);
|
|
return NextResponse.json({ error: "Failed to save brief" }, { status: 500 });
|
|
}
|
|
}
|