init push

This commit is contained in:
nadja
2026-08-25 20:29:14 +02:00
commit 2bb9aab82c
42 changed files with 3966 additions and 0 deletions

39
backend/services/ai.js Normal file
View File

@@ -0,0 +1,39 @@
import { SYSTEM_PROMPT } from '../prompts/extractRecipe.js';
const OLLAMA_URL = process.env.OLLAMA_URL || 'http://localhost:11434';
const MODEL = process.env.OLLAMA_MODEL || 'mistral';
export async function isOllamaAvailable() {
try {
const res = await fetch(`${OLLAMA_URL}/api/tags`, { signal: AbortSignal.timeout(3000) });
return res.ok;
} catch {
return false;
}
}
export async function extractRecipe(description) {
const response = await fetch(`${OLLAMA_URL}/api/generate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: MODEL,
system: SYSTEM_PROMPT,
prompt: `Extrahiere ein Rezept aus dieser TikTok-Videobeschreibung:\n\n${description}`,
stream: false,
}),
});
if (!response.ok) {
throw new Error(`Ollama Fehler: ${response.status}`);
}
const data = await response.json();
let text = data.response.trim();
if (text.startsWith('```')) {
text = text.replace(/^```(?:json)?\n?/, '').replace(/\n?```$/, '');
}
return JSON.parse(text);
}

View File

@@ -0,0 +1,20 @@
import fetch from 'node-fetch';
export async function getTikTokData(url) {
const oembedUrl = `https://www.tiktok.com/oembed?url=${encodeURIComponent(url)}`;
const response = await fetch(oembedUrl);
if (!response.ok) {
throw new Error(`TikTok oEmbed Fehler: ${response.status}`);
}
const data = await response.json();
return {
title: data.title || '',
author: data.author_name || '',
authorUrl: data.author_url || '',
thumbnail: data.thumbnail_url || '',
embedHtml: data.html || '',
};
}