{ "name": "get_shipping_data", "description": "IMPORTANT: Always reply to the customer in their own language — the exact language they write in. Never switch to Polish unless the customer writes in Polish.\n\nPobierz metody i koszty wysyłki ze sklepu. Wywołaj gdy użytkownik pyta o wysyłkę, dostawę lub koszty dostawy. Nigdy nie zgaduj kosztów ani metod — zawsze wywołaj to narzędzie.\n\nPodaj parametr country jako dwuliterowy kod ISO 3166-1 alpha-2 (np. PL, DE, GB, FR, CZ, SE). Kod jest niezależny od języka — zawsze działa niezależnie od tego jak użytkownik napisał nazwę kraju. Bez country zwraca listę dostępnych stref.\nPodaj parametr language z wykrytym językiem klienta (kod WPML, np. pl, de, en) — wymagany do kosztów w odpowiedniej walucie.", "color": "linear-gradient(rgb(120,180,120), rgb(60,140,80))", "iconSrc": "", "schema": "[{\"id\":0,\"property\":\"country\",\"description\":\"Kod kraju ISO 3166-1 alpha-2 (np. PL, DE, GB, FR, CZ, HU, SE, DK, NO, RO, BG, AE). Zawsze używaj kodu dwuliterowego — jest jednoznaczny niezależnie od języka konwersacji.\",\"type\":\"string\",\"required\":false},{\"id\":1,\"property\":\"language\",\"description\":\"Kod języka WPML wykryty z wiadomości klienta (np. pl, de, en, fr, cs, tr). Wymagany do podania kosztów wysyłki w odpowiedniej walucie.\",\"type\":\"string\",\"required\":false},{\"id\":2,\"property\":\"currency\",\"description\":\"Nadpisanie waluty — podaj kod ISO 4217 (np. EUR, CZK, PLN) gdy użytkownik wyraźnie prosi o koszty wysyłki w konkretnej walucie. Opcjonalne.\",\"type\":\"string\",\"required\":false}]", "func": "const fetch = require('node-fetch')\n\nconst base = String(($vars && ($vars.relay_base || $vars.webhook_base)) || 'http://localhost:8080').replace(/\\/$/,'')\nconst secret = String(($vars && $vars.relay_shared_secret) || '')\nconst countryRaw = typeof $country !== 'undefined' && $country ? String($country).trim() : ''\nconst language = typeof $language !== 'undefined' && $language ? String($language) : ''\nconst currency = typeof $currency !== 'undefined' && $currency ? String($currency).toUpperCase().trim() : ''\n\n// Normalize to ISO 2-letter code (uppercase)\nconst countryCode = countryRaw.toUpperCase().replace(/[^A-Z]/g, '')\n\nif (!secret) return 'Error: missing $vars.relay_shared_secret'\n\ntry {\n const fetchData = async (body) => {\n const res = await fetch(`${base}/tools/get_shipping_data`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${secret}` },\n body: JSON.stringify(body)\n })\n return await res.json()\n }\n\n const zonesResp = await fetchData(language ? { language } : {})\n if (!zonesResp.ok || !Array.isArray(zonesResp.data)) return 'Error fetching shipping data.'\n const zones = zonesResp.data\n\n if (countryCode) {\n // Match by ISO country code — language-independent and reliable\n let zone = zones.find(z => Array.isArray(z.countries) && z.countries.includes(countryCode))\n\n // Fallback to zone id=0 (Rest of the World) if no specific zone found\n if (!zone) {\n zone = zones.find(z => z.id === 0)\n }\n\n if (!zone) {\n const available = zones\n .filter(z => Array.isArray(z.countries) && z.countries.length > 0)\n .map(z => z.countries.join('/'))\n .join(', ')\n return `No shipping zone found for country code ${countryCode}. Available zones: ${available}`\n }\n\n const bodyM = { zoneId: zone.id }\n if (language) bodyM.language = language\n if (currency) bodyM.currency = currency\n const methodsResp = await fetchData(bodyM)\n if (!methodsResp.ok || !methodsResp.data || !Array.isArray(methodsResp.data.methods)) return 'No shipping data available for ' + zone.name + '.'\n\n const methods = methodsResp.data.methods\n if (!methods.length) return 'No active shipping methods for ' + zone.name + '.'\n\n const currencyNote = methodsResp.currency_fallback && methodsResp.currency_note ? '\\n[NOTE: ' + methodsResp.currency_note + ']' : ''\n const lines = methods.map(m => {\n const cost = m.cost || null\n const costCurrency = m.cost_currency || methodsResp.data.currency || methodsResp.currency || 'PLN'\n return '- ' + (m.title || m.method_id) + (cost && cost !== '0' ? ' — ' + cost + ' ' + costCurrency : '')\n }).join('\\n')\n\n return 'Shipping methods to ' + zone.name + ' (' + countryCode + '):\\n' + lines + currencyNote\n }\n\n // No country given — return list of available zones with their country codes\n const list = zones\n .filter(z => z.id !== 0)\n .map(z => {\n const codes = Array.isArray(z.countries) && z.countries.length > 0 ? ' (' + z.countries.join(', ') + ')' : ''\n return z.name + codes\n })\n .join(', ')\n const hasWorld = zones.some(z => z.id === 0)\n return 'Shipping available to: ' + list + (hasWorld ? ', and other countries (Rest of the World)' : '') + '.\\n[INSTRUCTION: If the user asked about a specific country, call the tool again with the country parameter set to the ISO 3166-1 alpha-2 country code (e.g. country=GB for Great Britain, country=DE for Germany). Never expose technical identifiers to the user.]'\n} catch (error) {\n return 'Connection error: ' + (error?.message || String(error))\n}\n" }