
interactive-mcp
Integrujte FlowHunt s interactive-mcp a umožněte bezpečnou, interaktivní komunikaci v reálném čase mezi velkými jazykovými modely a uživateli na lokálních stroj...

Kompletni reference pro integraci FlowHunt JS API v2. Vlozte chatbota, odebirejte vsech 11 udalosti, pouzivejte promenne toku, spoustejte trigger Chat Hook behem konverzace pomoci sendHook(), sledujte interakce pres URL parametry a programove ovladejte okno chatu.
FlowHunt JS API vam dava plnou kontrolu nad tim, jak se chatbot integruje s vasim webem. Pomoci integracniho kodu v2 muzete vlozit chatbota, odebirat udalosti zivotniho cyklu a interakci, predavat dynamicka data prostrednictvim promennych toku, spoustet trigger Chat Hook behem konverzace pomoci sendHook(), sledovat interakce pres URL parametry a programove ovladat okno chatu.
Tento pruvodce pokryva vsechny aspekty JS API s priklady kodu, ktere muzete zkopirovat a prizpusobit svemu projektu.
Zkopirujte a vlozte nasledujici fragment do vaseho HTML tesne pred uzaviraci tag </body>. Nahradte YOUR_CHATBOT_ID a YOUR_WORKSPACE_ID hodnotami z nastaveni vaseho FlowHunt chatbota.
<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
var currentScript = document.currentScript
|| document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');
var script = document.createElement('script');
script.async = true;
script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
+ '?workspace_id=YOUR_WORKSPACE_ID&v=2';
script.onload = function () {
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
// The chatbot is ready — use chatbotManager here
});
};
if (currentScript && currentScript.parentNode) {
currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
} else {
document.head.appendChild(script);
}
</script>
ID chatbota v nazvu globalni promenne (window.FHChatbot_YOUR_CHATBOT_ID) pouziva podtrzitka misto pomlcek.
setConfig()Pred volanim init() muzete prepsat vychozi nastaveni chatbota pomoci setConfig():
<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
var currentScript = document.currentScript
|| document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');
var script = document.createElement('script');
script.async = true;
script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
+ '?workspace_id=YOUR_WORKSPACE_ID&v=2';
script.onload = function () {
window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
headerTitle: 'Support Assistant',
maxWindowWidth: '700px',
showChatButton: false,
flowVariables: {
userId: '12345',
plan: 'enterprise',
},
urlSuffix: '?utm_source=chatbot',
});
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
// Chatbot initialised with custom config
});
};
if (currentScript && currentScript.parentNode) {
currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
} else {
document.head.appendChild(script);
}
</script>
| Moznost | Typ | Popis |
|---|---|---|
headerTitle | string | Vlastni text zahlavi |
maxWindowWidth | string | Maximalni sirka okna chatu (napr. "700px") |
maxWindowHeight | string | Maximalni vyska okna chatu |
inputPlaceholder | string | Zastupny text pole pro zadavani zprav |
showChatButton | boolean | Zobrazit nebo skryt vychozi plovouci tlacitko chatu |
openChatPanel | boolean | Automaticky otevrit panel chatu pri nacteni stranky |
flowVariables | object | Pary klic-hodnota s vlastnimi daty predavanymi do toku. Hodnoty mohou byt jakykoli typ serializovatelny do JSON (string, cislo, boolean, objekt, pole). |
urlSuffix | string | Retezec dotazu pripojeny ke vsem URL adresam generovanym chatbotem |
cookieConsent | boolean | Povolit uchovavani relace pomoci cookies |
embedded | string | Nastavte pro povoleni vlozeneho rezimu (bez tlacitka zavreni) |
theme | string | Rezim motivu |
flowVariables jsou slouceny do kazde relace, kterou chatbot vytvori. Typicky se pouzivaji jako staticky kontext (znamy pri nacteni stranky): ID uzivatele, plan, aktualni jazyk atd.
window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
flowVariables: {
userId: getCurrentUserId(),
userEmail: getCurrentUserEmail(),
currentPage: window.location.pathname,
plan: 'enterprise',
},
});
Pokud uzivatel po otevreni chatu naviguje jinam, hodnoty predane zde se stanou zastaralymi. Pro jejich aktualizaci behem konverzace zavolejte
chatbotManager.sendHook()soptions.flowVariables— viz Komunikace host → tok behem konverzace nize.
Parametr urlSuffix pripoji retezec dotazu ke kazde URL adrese generovane chatbotem. To je uzitecne pro sledovani provozu generovaneho chatbotem v analytickych nastrojich:
window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
urlSuffix: '?utm_source=chatbot&utm_medium=widget',
});
Pripady pouziti:
Pridano v dubnu 2026 jako soucast funkce FlowHunt Chat Hook.
V single-page aplikacich okno chatu obvykle zustava otevrene, zatimco uzivatel naviguje mezi obrazovkami. Jakmile chat bezi, flowVariables predane pres setConfig() se stanou zastaralymi a neexistuje zpusob, jak toku oznamit, ze se neco udalo na hostujici strance. Jedina metoda spravce — sendHook(name, payload, options?) — pokryva oba pripady pouziti: “spustit trigger” i “jen aktualizovat kontext”:
name a (volitelne) payload pro spusteni triggeru Chat Hook v toku. Autor toku vlozi na platno jeden uzel Chat Hook a vetvi se podle {ChatHook.hook_name} k rozhodnuti, co udelat.options.flowVariables pro soucasne sloucenim promennych relace — hodnoty se uchovaji pred spustenim triggeru a zustavaji k dispozici po zbytek relace.options.flowVariables se presto sloucuji, ale zadny trigger se nespousti a neuctuji se zadne kredity. To znamena, ze hostujici stranky mohou volat sendHook() optimisticky, aniz by vedely, zda autor toku jiz zapojil trigger.sendHook() je bezpecne no-op pred existenci relace (interne se uchovava ve fronte a odesle se po vytvoreni relace) a nikdy nevyhazuje vyjimku smerem k hostujici strance — sitove chyby se pouze loguji pres console.warn.
Limity na strane serveru i klienta, ktere plati pro sendHook(). Jejich poruseni neni havarie — backend vraci HTTP 422 a spravce loguje pres console.warn bez vyhazovani vyjimky.
| Omezeni | Limit | Kde je vynuceno | Pri poruseni |
|---|---|---|---|
Delka name u sendHook | 1–256 znaku | Backend (Pydantic) | HTTP 422, trigger se nespousti |
Pocet klicu v options.flowVariables | ≤ 64 | Backend (Pydantic) | HTTP 422, nic se neuchova |
Delka kazdeho klice v options.flowVariables | ≤ 128 znaku | Backend (Pydantic) | HTTP 422, nic se neuchova |
| Volani pred relaci uchovana ve fronte spravcem | 50 | Widget (v prohlizeci) | Nejstarsi zarazene volani je zahozeno a zaloguje se console.warn |
Limit fronty pred relaci je relevantni pouze na strankach, kde vytvoreni relace selhava trvale (napr. trvala sitova chyba). Za normalnich podminek se fronta odesle, jakmile se spusti onFHChatbotSessionCreated.
onFHError).hook_name, payload, flow_variables) s libovolnymi navaznymi kroky, ktere chcete spustit (Generator, Chat Output, Tool Calls, podminene vetve podle hook_name atd.).name, ktere hostujici stranka predava do sendHook(), je stitek pro vetveni vaseho toku, nikoli smerovaci klic — backend nesparovava nazvy s uzly. Misto toho jediny trigger Chat Hook v toku spusti a vystavi nazev jako {ChatHook.hook_name}, ktery ve sve logice toku odkazujete pri rozhodovani, co udelat.
Priklad systemoveho promptu:
If {ChatHook.hook_name} is "screen_changed", briefly summarise the page at
{ChatHook.payload.url}. If it is "user_action", acknowledge the action and
update memory. Otherwise, continue the conversation normally.
Pro slozitejsi smerovani zapojte podmineny krok na {ChatHook.hook_name} a vetvete do nekolika navaznych cest.
chatbotManager.sendHook(name, payload, options?)chatbotManager.sendHook(
name: string,
payload?: Record<string, unknown>,
options?: { flowVariables?: Record<string, unknown> }
): Promise<void>;
Argumenty
| Argument | Typ | Povinne | Popis |
|---|---|---|---|
name | string | ano | Stitek predany toku jako {ChatHook.hook_name}. Trigger se spousti bez ohledu na hodnotu; logika vaseho toku se podle ni vetvi. |
payload | object | ne | JSON payload predany triggeru jako {ChatHook.payload}. Pokud je povolena, validuje se proti schematu uzlu. Vychozi {}. |
options.flowVariables | object | ne | Promenne relace ke slouceni pred spustenim triggeru. K dispozici navaznym krokum a budoucim uzivatelskym zpravam. |
Chovani
onFHChatbotSessionCreated je bezpecne; volani je uchovano ve fronte a odeslano po vytvoreni relace. Buffer ma limit — viz Vstupni limity vyse.sendHook() optimisticky pred tim, nez autor toku trigger zapoji. options.flowVariables se presto uchovaji, takze stejne volani slouzi i jako aktualizace pouze kontextu.onFHError).name a options.flowVariables jsou omezeny — viz Vstupni limity vyse. Poruseni vraci HTTP 422 a nic se neuchova.onFHChatbotFlowVariablesUpdate, pokud bylo predano options.flowVariables (viz Prehled udalosti).console.warn.Priklad — proaktivni navrh pri SPA navigaci
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
window.addEventListener('hashchange', function () {
chatbotManager.sendHook('screen_changed', {
url: window.location.href,
screen_name: getScreenName(),
}, {
flowVariables: { current_page_url: window.location.href },
});
});
});
Priklad — aktualizace pouze kontextu (bez zapojeneho Chat Hook)
Pokud tok nema trigger Chat Hook, volani je tiche 200 — takze stejne API muze udrzovat flow_variables v synchronizaci, aniz by cokoli spoustelo:
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
window.addEventListener('hashchange', function () {
chatbotManager.sendHook('navigate', {}, {
flowVariables: {
current_page_url: window.location.href,
screen_name: getScreenName(),
},
});
});
});
{ChatHook.hook_name} a {ChatHook.payload.foo} — hodnoty predane pres sendHook('x', { foo: 1 }) jsou vystaveny na vykonavaci ceste triggeru Chat Hook. Pouze dostupne na ceste zapocate spustenim hooku.{flow_variables.foo} — hodnoty predane pres options.flowVariables jsou slouceny do baliku promennych relace pred spustenim triggeru. Kazda vykonavaci cesta (vcetne normalnich uzivatelskych zprav spustenych pres Chat Input) je muze cist.Pokud chcete, aby dalsi uzivatelska zprava videla novou hodnotu, dejte ji do options.flowVariables — samotny payload ovlivnuje pouze beh vykonavani zapocaty timto hookem.
FlowHunt JS API odesila 11 vlastnich udalosti na objektu window. Vsechny udalosti pouzivaji API CustomEvent
s nastavenim bubbles: true a composed: true.
onFHChatbotReadySpustena, kdyz je widget chatbota plne vyrenderovan a pripraven k pouziti.
onFHChatbotSessionCreatedSpustena, kdyz je na serveru vytvorena nova relace chatu.
event.detail.sessionId — ID nove vytvorene relace.onFHChatbotWindowOpenedSpustena, kdyz uzivatel otevre okno chatu. Nespousti se ve vlozenem rezimu.
onFHChatbotWindowClosedSpustena, kdyz uzivatel zavre okno chatu. Nespousti se ve vlozenem rezimu.
onFHMessageSentSpustena, kdyz uzivatel odesle zpravu.
event.detail.metadata = {
content: 'Hello, I need help with...',
createdAt: '2026-02-19T10:30:00.000Z',
};
onFHMessageReceivedSpustena, kdyz chatbot prijme a zobrazi odpoved.
event.detail.metadata = {
flow_id: 'abc123',
message_id: 'msg_456',
message: 'Sure, I can help you with that!',
sender: {
sender_name: 'Support Agent',
sender_avatar: 'https://example.com/avatar.png',
},
};
sender je volitelne a je pritomno pouze tehdy, kdyz je zapojen lidsky agent.
onFHFormDataSentSpustena, kdyz uzivatel odesle data formulare prostrednictvim chatbota.
event.detail.metadata = {
objectData: { name: 'John', email: 'john@example.com' },
createdAt: '2026-02-19T10:31:00.000Z',
};
onFHFeedbackSpustena, kdyz uzivatel da palec nahoru / palec dolu na zpravu chatbota.
event.detail.metadata = {
message_id: 'msg_456',
content: 'Optional feedback text',
feedback: 'P', // 'P' = positive, 'N' = negative
};
onFHToolCallSpustena, kdyz je behem zpracovani toku proveden nastroj nebo akce. Spousti se pouze v rezimech flowAssistant a flowAssistantV3.
event.detail.metadata = {
metadata: {
flow_id: 'abc123',
message_id: 'msg_789',
message: 'Calling search API...',
},
createdAt: '2026-02-19T10:32:00.000Z',
};
onFHErrorSpustena, kdyz behem provozu chatbota dojde k chybe.
event.detail.metadata = {
metadata: {
flow_id: 'abc123',
message_id: 'msg_err',
message: 'Flow execution failed',
},
createdAt: '2026-02-19T10:33:00.000Z',
};
onFHChatbotFlowVariablesUpdatePridano v dubnu 2026.
Spustena po uspesnem volani chatbotManager.sendHook(...), ktere predalo options.flowVariables. Nespousti se pro volani sendHook(), ktera flowVariables neobsahuji.
event.detail = {
variables: {
current_page_url: 'https://example.com/products',
screen_name: 'products',
},
};
Pouzijte ji k pozorovani slouceni promennych (napr. k synchronizaci vlastniho stavu na strane hostitele, pro ladeni nebo pro prerenderovani UI prvku, ktery zavisi na stejnych datech).
Existuji dva zpusoby odberu udalosti chatbota.
Pouzijte window.addEventListener kdekoli na sve strance. Funguje to i pred nactenim chatbota:
<script>
document.addEventListener('DOMContentLoaded', function () {
window.addEventListener('onFHChatbotReady', function () {
console.log('Chatbot is ready');
});
window.addEventListener('onFHChatbotSessionCreated', function (event) {
console.log('Session created:', event.detail.sessionId);
});
window.addEventListener('onFHChatbotWindowOpened', function () {
console.log('Chat window opened');
});
window.addEventListener('onFHChatbotWindowClosed', function () {
console.log('Chat window closed');
});
window.addEventListener('onFHMessageSent', function (event) {
console.log('User sent:', event.detail.metadata.content);
});
window.addEventListener('onFHMessageReceived', function (event) {
console.log('Bot replied:', event.detail.metadata.message);
});
window.addEventListener('onFHFormDataSent', function (event) {
console.log('Form submitted:', event.detail.metadata.objectData);
});
window.addEventListener('onFHFeedback', function (event) {
var fb = event.detail.metadata;
console.log('Feedback on message', fb.message_id, ':', fb.feedback);
});
window.addEventListener('onFHToolCall', function (event) {
console.log('Tool called:', event.detail.metadata);
});
window.addEventListener('onFHError', function (event) {
console.error('Chatbot error:', event.detail.metadata);
});
window.addEventListener('onFHChatbotFlowVariablesUpdate', function (event) {
console.log('Variables merged:', event.detail.variables);
});
});
</script>
Pro odstraneni naslouchace si uchovejte referenci na obsluhu:
var handleMessage = function (event) {
console.log(event.detail.metadata);
};
window.addEventListener('onFHMessageReceived', handleMessage);
// Later …
window.removeEventListener('onFHMessageReceived', handleMessage);
Uvnitr callbacku init() pouzijte vestavene metody spravce chatbota:
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
chatbotManager.onSessionCreated(function () {
console.log('Session created');
});
chatbotManager.onWindowOpened(function () {
console.log('Window opened');
});
chatbotManager.onWindowClosed(function () {
console.log('Window closed');
});
chatbotManager.onMessageSent(function (event) {
console.log('User sent:', event.metadata);
});
chatbotManager.onMessageReceived(function (event) {
console.log('Bot replied:', event.metadata);
});
chatbotManager.onFormDataSent(function (event) {
console.log('Form data:', event.metadata);
});
chatbotManager.onFeedback(function (event) {
console.log('Feedback:', event.metadata);
});
chatbotManager.onToolCall(function (event) {
console.log('Tool call:', event.metadata);
});
chatbotManager.onError(function (event) {
console.error('Error:', event.metadata);
});
});
| Metoda | Parametry | Popis |
|---|---|---|
onSessionCreated(fn) | fn: () => void | Naslouchejte vytvoreni relace |
onWindowOpened(fn) | fn: () => void | Naslouchejte otevreni okna |
onWindowClosed(fn) | fn: () => void | Naslouchejte zavreni okna |
onMessageSent(fn) | fn: (event) => void | Naslouchejte uzivatelskym zpravam |
onMessageReceived(fn) | fn: (event) => void | Naslouchejte odpovedim bota |
onFormDataSent(fn) | fn: (event) => void | Naslouchejte odeslani formularu |
onFeedback(fn) | fn: (event) => void | Naslouchejte zpetne vazbe uzivatelu |
onToolCall(fn) | fn: (event) => void | Naslouchejte spusteni nastroju |
onError(fn) | fn: (event) => void | Naslouchejte chybam |
openChat() | — | Otevre panel chatu |
closeChat() | — | Zavre panel chatu |
sendHook(name, payload?, options?) (nove) | name: string, payload?: object, options?: { flowVariables?: object } | Spusti trigger Chat Hook v bezicim toku (nebo tise sloucuje options.flowVariables, pokud zadny trigger neni zapojen) |
Pro uplnou kontrolu nad tim, kdy se chatbot zobrazi, skryjte vychozi plovouci tlacitko a otevrete chat programove — napriklad z vlastniho tlacitka.
<button id="my-chat-button">Chat with us</button>
<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
var currentScript = document.currentScript
|| document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');
var script = document.createElement('script');
script.async = true;
script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
+ '?workspace_id=YOUR_WORKSPACE_ID&v=2';
script.onload = function () {
window.FHChatbot_YOUR_CHATBOT_ID.setConfig({ showChatButton: false });
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
document.getElementById('my-chat-button')
.addEventListener('click', function () {
chatbotManager.openChat();
});
});
};
if (currentScript && currentScript.parentNode) {
currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
} else {
document.head.appendChild(script);
}
</script>
Muzete kombinovat skrytou aktivaci s naslouchaci udalosti pro vytvoreni pokrocilych interakci:
<button id="open-chat" style="display:none;">Need help?</button>
<script>
window.addEventListener('onFHChatbotReady', function () {
document.getElementById('open-chat').style.display = 'block';
});
</script>
<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
var currentScript = document.currentScript
|| document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');
var script = document.createElement('script');
script.async = true;
script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
+ '?workspace_id=YOUR_WORKSPACE_ID&v=2';
script.onload = function () {
window.FHChatbot_YOUR_CHATBOT_ID.setConfig({ showChatButton: false });
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
document.getElementById('open-chat')
.addEventListener('click', function () {
chatbotManager.openChat();
});
});
};
if (currentScript && currentScript.parentNode) {
currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
} else {
document.head.appendChild(script);
}
</script>
Uplny funkcni priklad demonstrujici prepisy konfigurace, sledovani udalosti, vlastni aktivaci chatu a novou metodu sendHook() dohromady:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FlowHunt Chatbot Integration</title>
</head>
<body>
<h1>My Website</h1>
<button id="open-chat-btn">Talk to our AI assistant</button>
<button id="close-chat-btn">Close chat</button>
<!-- Subscribe to events before the chatbot loads -->
<script>
document.addEventListener('DOMContentLoaded', function () {
window.addEventListener('onFHChatbotReady', function () {
console.log('Chatbot widget is ready');
});
window.addEventListener('onFHChatbotSessionCreated', function (event) {
console.log('New chat session started:', event.detail.sessionId);
});
window.addEventListener('onFHMessageSent', function (event) {
console.log('User message:', event.detail.metadata.content);
});
window.addEventListener('onFHMessageReceived', function (event) {
console.log('Bot response:', event.detail.metadata.message);
});
window.addEventListener('onFHChatbotFlowVariablesUpdate', function (event) {
console.log('Context updated:', event.detail.variables);
});
window.addEventListener('onFHError', function (event) {
console.error('Chatbot error:', event.detail.metadata);
});
});
</script>
<!-- FlowHunt integration -->
<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
var currentScript = document.currentScript
|| document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');
var script = document.createElement('script');
script.async = true;
script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
+ '?workspace_id=YOUR_WORKSPACE_ID&v=2';
script.onload = function () {
window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
showChatButton: false,
headerTitle: 'AI Assistant',
maxWindowWidth: '600px',
flowVariables: {
source: 'website',
current_page_url: window.location.href,
},
urlSuffix: '?utm_source=chatbot',
});
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
// Open / close from custom buttons
document.getElementById('open-chat-btn')
.addEventListener('click', function () {
chatbotManager.openChat();
});
document.getElementById('close-chat-btn')
.addEventListener('click', function () {
chatbotManager.closeChat();
});
// Keep the flow's context in sync with SPA navigation and
// optionally fire the Chat Hook trigger (if the flow has one wired).
// If the flow has no Chat Hook, the call is a silent 200 — the
// flow_variables still get merged, so the same line covers both
// "notify the flow" and "just update context".
window.addEventListener('hashchange', function () {
chatbotManager.sendHook('screen_changed', {
url: window.location.href,
}, {
flowVariables: { current_page_url: window.location.href },
});
});
});
};
if (currentScript && currentScript.parentNode) {
currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
} else {
document.head.appendChild(script);
}
</script>
</body>
</html>

Integrujte FlowHunt s interactive-mcp a umožněte bezpečnou, interaktivní komunikaci v reálném čase mezi velkými jazykovými modely a uživateli na lokálních stroj...

Zjistěte, jak umožnit vašemu chatbotu FlowHunt odpovídat zákazníkům na dotazy ohledně dostupnosti produktů a stavu doručení objednávek pomocí integrace s API v ...

Integrujte FlowHunt s LiveChat a umožněte inteligentní eskalaci AI na člověka. Nasaďte AI chatboty, které automaticky předají rozhovory agentům LiveChat, když j...
Souhlas s cookies
Používáme cookies ke zlepšení vašeho prohlížení a analýze naší návštěvnosti. See our privacy policy.