Schritt 6 – Funktion erstellen: GetCheapestOffers (EAN-Preissuchagent)
Diese Funktion fordert Claude auf, als websuchender Preisvergleichs-Agent zu agieren. Bei einem einzelnen EAN-Code gibt sie die günstigsten verfügbaren Angebote in einer vollständig typisierten, flachen Struktur zurück.
| Name |
Typ |
Optional |
Standard |
ean |
Zeichenkette |
✅ |
4006381333931 |
userRegion |
Zeichenkette |
✅ |
DE |
currency |
Zeichenkette |
✅ |
EUR |
priority |
Zeichenkette |
✅ |
lowest_total_cost |
Ausgabeparameter
| Name |
Typ |
Beschreibung |
priceSearchResponse |
PriceSearchResponse |
Flaches typisiertes Ergebnis mit Produktinfo und Angeboten |
rawText |
String |
Rohe Claude-Antwort |
usage |
Any |
Token-Nutzung |
Funktionscode
// ── System Prompt ────────────────────────────────────────────────────────────
const SYSTEM_PROMPT = `You are an AI agent whose primary task is to find the
cheapest available offer for products identified by their EAN code.
Output ONLY a single flat valid JSON object with exactly these fields:
{
"ean": "",
"product_name": null,
"product_description": null,
"status": "found",
"exact_match_found": true,
"cheapest_offer": { ...offer object... },
"cheapest_unit_offer": { ...offer object... },
"offers": [ ...up to 3 offer objects... ]
}
Each offer must contain: match_type, seller_name, seller_domain, url,
item_price, shipping_price, total_cost, currency, pack_size, unit,
unit_price, seller_rating { score, scale, ratings_count }, region,
availability, delivery_estimate, last_checked_utc, raw_source, notes.
No wrapping query or meta object. No text outside the JSON. No markdown fences.`;
// ── Default / Sample values ──────────────────────────────────────────────────
const DEFAULT_EAN = "4006381333931";
const DEFAULT_REGION = "DE";
const DEFAULT_CURRENCY = "EUR";
const DEFAULT_PRIORITY = "lowest_total_cost";
// ── Resolve inputs ───────────────────────────────────────────────────────────
const ean = (input.ean && input.ean.trim()) ? input.ean.trim() : DEFAULT_EAN;
const region = (input.userRegion && input.userRegion.trim()) ? input.userRegion.trim() : DEFAULT_REGION;
const currency = (input.currency && input.currency.trim()) ? input.currency.trim() : DEFAULT_CURRENCY;
const priority = (input.priority && input.priority.trim()) ? input.priority.trim() : DEFAULT_PRIORITY;
// ── Build user message ───────────────────────────────────────────────────────
const userMessage = `Search for the cheapest offers for this EAN code:
EAN: ${ean}
User region: ${region}
Preferred currency: ${currency}
Priority: ${priority}
Limit to 3 offers. Return ONLY a single flat JSON object. No text outside the JSON, no markdown fences.`;
// ── Call Claude via the connector ────────────────────────────────────────────
const response = Simplifier.Connector.Claude.SendMessage({
"postBody/model": "claude-sonnet-4-6",
"postBody/max_tokens": 8000,
"postBody/system": SYSTEM_PROMPT,
"postBody/messages": [{ role: "user", content: userMessage }]
});
// ── Extract raw text ─────────────────────────────────────────────────────────
let rawText = "";
if (response && response.content && Array.isArray(response.content)) {
for (const block of response.content) {
if (block.type === "text") { rawText = block.text; break; }
}
} else if (response && response.content) {
rawText = String(response.content);
}
output.rawText = rawText;
output.usage = response ? response.usage : null;
// ── Robust JSON extraction ───────────────────────────────────────────────────
// Strip markdown fences if present
let cleaned = rawText.replace(/^"`(?:json)?\s*/i, "").replace(/\s*"`$/i, "").trim();
// If Claude prefixed the JSON with prose, skip to the first {
if (!cleaned.startsWith("{")) {
const firstBrace = cleaned.indexOf("{");
if (firstBrace !== -1) cleaned = cleaned.substring(firstBrace).trim();
}
try {
const parsed = JSON.parse(cleaned);
// If Claude still wrapped the result in a results array, unwrap first entry
output.priceSearchResponse = (parsed.results && Array.isArray(parsed.results))
? parsed.results[0]
: parsed;
} catch (e) {
output.priceSearchResponse = {
ean: ean,
product_name: null,
product_description: null,
status: "error",
exact_match_found: false,
cheapest_offer: null,
cheapest_unit_offer: null,
offers: []
};
}
Teste die GetCheapestOffers-Funktion
Eingabe:
{
"ean": "4006381333931",
"userRegion": "DE",
"currency": "EUR"
}
Erwartete Ausgabestruktur:
{
"ean": "4006381333931",
"product_name": "Stabilo Boss Original Textmarker",
"product_description": "Classic highlighter pen...",
"status": "found",
"exact_match_found": true,
"cheapest_offer": {
"seller_domain": "amazon.de",
"item_price": 0.79,
"shipping_price": 0.00,
"total_cost": 0.79,
"currency": "EUR"
},
"offers": [ ... ]
}