/** Hawesko Affiliate Katalog – Frontend + API in einer Web-App * Ersetzt iONOS-Beschränkungen: iFrame lädt diese Web-App. * Affiliate-Kennung fest: awinaffid=1603746 */ const CFG = { SHEET_NAME: 'Tabelle1', // ggf. anpassen AWINMID: '14179', AWINAFFID: '1603746', TITLE: 'Wein-Katalog' }; // ---- Web-App Entry ---- function doGet(e) { const action = (e.parameter.action || '').toLowerCase(); if (action === 'search' || action === 'product') { return api(e); // JSON API } return html(); // Frontend-UI } // ---- JSON API ---- function api(e) { const p = e.parameter || {}; const data = readRows(); let items = data; if ((p.action || '').toLowerCase() === 'search') { const q = (p.q || '').toLowerCase(); const country = p.country || ''; const color = p.color || ''; const maxprice = parseFloat(p.maxprice || '0'); items = data.filter(x => { if (q && !(`${x.name} ${x.vintage} ${x.region} ${x.winery}`.toLowerCase().includes(q))) return false; if (country && x.country !== country) return false; if (color && x.color && x.color !== color) return false; if (!isNaN(maxprice) && maxprice>0 && Number(x.price) > maxprice) return false; return true; }).slice(0, 200); return json({ items }); } if ((p.action || '').toLowerCase() === 'product') { const sku = p.sku || ''; const item = data.find(x => x.sku === sku) || null; return json({ item }); } return json({ error: 'unknown action' }, 400); } function readRows() { const sh = SpreadsheetApp.getActive().getSheetByName(CFG.SHEET_NAME); const values = sh.getDataRange().getValues(); const head = values.shift().map(String); const idx = Object.fromEntries(head.map((h,i)=>[h,i])); const get = (r,k) => (idx[k]!=null ? String(r[idx[k]]||'') : ''); return values.map(r => ({ sku: get(r,'sku'), name: get(r,'name'), vintage: get(r,'vintage'), winery: get(r,'winery') || 'Weingut', country: get(r,'country'), region: get(r,'region'), color: get(r,'color'), price: parseFloat(get(r,'price')||'0'), currency: get(r,'currency') || 'EUR', image_url: get(r,'image_url'), hawesko_url: get(r,'hawesko_url'), description: get(r,'description'), pairing: get(r,'pairing') || 'Passt zu Pasta, Lamm, gereiftem Käse, gegrilltem Gemüse.', story: get(r,'story'), availability: get(r,'availability') || 'in_stock', deeplink: buildDeep(get(r,'hawesko_url')) })); } function buildDeep(url) { if (!url) return ''; const enc = encodeURIComponent(url); return `https://www.awin1.com/cread.php?awinmid=${CFG.AWINMID}&awinaffid=${CFG.AWINAFFID}&ued=${enc}`; } function json(obj, code) { const out = ContentService.createTextOutput(JSON.stringify(obj)); out.setMimeType(ContentService.MimeType.JSON); return out; } // ---- HTML Frontend (UI + JS inliner, keine externen Libs) ---- function html() { const tpl = HtmlService.createTemplate(` <?= CFG.TITLE ?>
Hinweis: Enthält Werbelinks (Affiliate). Preise inkl. MwSt., Daten ohne Gewähr.
`); return tpl.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL); }