/** 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 ?>
`);
return tpl.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
Hinweis: Enthält Werbelinks (Affiliate). Preise inkl. MwSt., Daten ohne Gewähr.