HelpStackDokumenti

Integracije

Vgraditev widgeta

Vgradite widget za spletni klepet HelpStack na katero koli spletno stran z eno samo oznako script.

Hitre dejstvice#

Nalagalnikhttps://helpstack.eu/widget.js
AvtentikacijaNi — končne točke widgeta so javne
TransportSocket.IO (primarni) + HTTP rezerva
Vrsta kanalaWEBSITE_CHAT
Omejitev hitrosti~30 zahtev/min/IP za config/FAQ/status; ~20 sporočil/min/obiskovalec za HTTP rezervo sporočil
Nadzor izvoraNeobvezni seznam dovoljenih domen po kanalu (403, če ni dovoljen)

Nalagalnik izpelje svojo lastnost baseUrl iz izvora lastne oznake <script src>, zato widget.js, ki ga streže helpstack.eu, samodejno komunicira s HelpStack — ni treba konfigurirati ničesar drugega.

Odrezek za vgraditev#

<script src="https://helpstack.eu/widget.js?id=CHANNEL_ID" async></script>

CHANNEL_ID je id vašega kanala WEBSITE_CHAT. Nalagalnik se samodejno inicializira iz parametra poizvedbe ?id= — dodatnega JavaScripta ni potrebno.

Kje dobiti CHANNEL_ID#

Na nadzorni plošči pojdite na Nastavitve → Kanali, odprite (ali ustvarite) kanal Spletni klepet in kopirajte njegov id z gumbom za kopiranje poleg kanala. Ta id posredujete kot ?id=CHANNEL_ID.

Kako deluje nalagalnik#

  1. Skripta prebere svojo lastno <script src>, da ugotovi:
    • baseUrl — izvor skripte (npr. https://helpstack.eu)
    • channelId — parameter poizvedbe ?id=
  2. Vstavi lebdeči mehurček klepeta in <iframe>, ki kaže na:
    {baseUrl}/widget/{channelId}?visitorId={visitorId}
    
  3. Iframe odpre povezavo Socket.IO za sporočanje v realnem času, z HTTP rezervo, ko WebSocket ni na voljo.

Identiteta obiskovalca#

Nalagalnik ustvari trajni id obiskovalca, shranjen v localStorage:

KljučOblika vrednosti
chat_widget_visitor_idvisitor_<uuid>

Isti visitorId se znova uporablja pri nalaganju strani in sejah v tem brskalniku, zato se vračajoči obiskovalec znova poveže s svojim obstoječim pogovorom. Brisanje localStorage (ali drug brskalnik/naprava) ustvari novega obiskovalca in novo nit pogovora.

Programski API#

Nalagalnik izpostavi globalni objekt window.ChatWidget:

window.ChatWidget.init('CHANNEL_ID'); // ročna inicializacija (če ne uporabljate ?id=)
window.ChatWidget.open();             // odpre ploščo klepeta
window.ChatWidget.close();            // zapre ploščo klepeta
window.ChatWidget.toggle();           // preklopi med odprtim/zaprtim

Na voljo je tudi pomočnik s čakalno vrsto ukazov za odloženo obliko, ki se uporablja v komentarju odrezka:

window.chat('init', 'CHANNEL_ID');

Kadar koli povejte, s kom govorite, da UI tega ni treba spraševati:

window.ChatWidget.identify({ name: 'Ana Novak', email: 'ana@example.com' },
                           { plan: 'pro', account_id: '1234' });

Registrirajte orodje agenta na strani odjemalca, da lahko UI pokliče kodo, ki teče na vaši strani:

window.HelpStack('registerTool', 'highlight', async ({ section }) => {
  document.querySelector(`#${section}`)?.scrollIntoView({ behavior: 'smooth' });
  return { highlighted: section };
});

Kar rokovalnik vrne, je tisto, kar prebere UI. V ozadju iframe pripomočka s postMessage pošlje TOOL_EXECUTE nadrejenemu oknu in čaka na TOOL_RESULT ali TOOL_ERROR z isto callId; registerTool to odgovori namesto vas. Za ime orodja, za katero nima rokovalnika, pripomoček ostane tiho, zato vaš obstoječi poslušalec message deluje naprej. Glejte Orodja agenta po meri.

Konfiguracija videza#

Videz je konfiguriran na nadzorni plošči ali prek MCP (get_widget_config / update_widget_config, glej MCP), ne prek odrezka za vgraditev. Widget ga pridobi s strežnika (GET /api/widget/[channelId]/config) in ga uporabi prek spremenljivk CSS. Preverjene nastavljive možnosti:

PoljeOpombe
primaryColorBarva v šestnajstiškem zapisu. Privzeto #247f7c (znamčna turkizna)
positionbottom-right | bottom-left | top-right | top-left
mobilePositionIsti nabor vrednosti kot position, uporabljen na mobilnih zaslonih
bubbleIconTypecustom ali prednastavitev
bubbleIconNameEna od: message, help, smile, headphone, zap, heart
bubbleOffsetXVodoravni odmik mehurčka
bubbleOffsetYNavpični odmik mehurčka
greetingMessagePozdravno besedilo, prikazano ko se plošča odpre
avatarUrlAvatar agenta/blagovne znamke
showOnlineStatusAli prikazati stanje na spletu/izven spleta
offlineMessageSporočilo, prikazano ko je kanal izven spleta
productCardsPrikaz povezav do izdelkov v odgovorih kot kartic. Privzeto true. Glejte Kartice izdelkov

Javne končne točke widgeta#

Vse končne točke so javne (brez avtentikacije) in omejene po hitrosti glede na IP/obiskovalca.

MetodaPotNamen
GET/api/widget/[channelId]/configKonfiguracija widgeta (barve, položaj, pozdrav, avatar, status). ~30 zahtev/min/IP
GET/api/widget/[channelId]/faqsDo 5 žetonov s pogostimi vprašanji za pozdrav. ~30 zahtev/min/IP
GET/api/widget/[channelId]/statusAli je kanal trenutno v spletu
POST/api/widget/[channelId]/uploadNalaganje datoteke multipart/form-data
POST/api/widget/messageHTTP rezerva za pošiljanje sporočila, ko WebSocket ni na voljo. ~20 sporočil/min/obiskovalec

Odgovor pri nalaganju (POST /api/widget/[channelId]/upload):

{
  "storagePath": "...",
  "publicUrl": "...",
  "fileName": "...",
  "fileSize": 12345,
  "contentType": "image/png",
  "width": 800,
  "height": 600
}

width in height sta prisotna samo za slike.

Rezerva za sporočila (POST /api/widget/message) — telo zahteve:

{
  "channelId": "CHANNEL_ID",
  "visitorId": "visitor_<uuid>",
  "content": "Hello, I need help",
  "visitorInfo": {
    "userAgent": "...",
    "currentUrl": "https://example.com/pricing",
    "referrer": "https://google.com"
  }
}

visitorInfo je neobvezen, prav tako metadata (ista neobvezna ovojnica, ki jo sprejme tudi dogodek join na socketu). Kanal mora biti vrste WEBSITE_CHAT, sicer je zahteva zavrnjena. Ob uspehu ovojnica odgovora v polju data vsebuje { messageId, conversationId, createdAt }. Pogovor obiskovalca se ustvari ob njegovem prvem sporočilu, zato je prvi uspešen klic tisti, ob katerem conversationId nastane; kasnejši klici istega obiskovalca ga ponovno uporabijo.

Dogodki v realnem času (Socket.IO)#

Iframe komunicira s strežnikom prek Socket.IO.

Widget → strežnik

DogodekKoristna obremenitev
joinchannelId, visitorId, visitorInfo { userAgent, currentUrl, referrer }
messageOdhodno sporočilo obiskovalca
typingIndikator tipkanja obiskovalca
heartbeatOhranjevalnik prisotnosti
tool:resultRezultat izvajanja orodja na strani odjemalca
tool:errorNapaka pri izvajanju orodja na strani odjemalca

Strežnik → widget

DogodekKoristna obremenitev
joinedconversationId, začetna messages, config widgeta, faqs. Pogovor se ustvari šele, ko obiskovalec pošlje prvo sporočilo, zato je pri novem obiskovalcu conversationId enak null in messages prazen; vračajoči se obiskovalec z odprtim pogovorom dobi njegov id in zgodovino. Pred prvim sporočilom se ne zanašajte na id.
messageNovo sporočilo agenta
agent_typingIndikator tipkanja agenta
tool:executeZahteva za zagon orodja na strani odjemalca v brskalniku

Kartice izdelkov#

Ko odgovor vsebuje povezavo do izdelka v vaši trgovini, jo widget prikaže kot kartico: slika, ime, cena, zaloga in gumb V košarico. Deluje kot predogled povezave in ne zahteva nobenih nastavitev. Kartice dobijo odgovori UI, odobreni osnutki in odgovori, ki jih napiše vaša ekipa.

Kartice izdelkov pod odgovorom v klepetu in ista kartica po dotiku gumba V košarico
Kartice izdelkov pod odgovorom v klepetu in ista kartica po dotiku gumba V košarico

Od kod so podatki. Ko je odgovor dostavljen, HelpStack odpre povezano stran in prebere podatke o izdelku, ki jih trgovina že objavlja za iskalnike: strukturirane podatke schema.org Product (JSON-LD ali mikropodatki), kot rezervo pa oznake Open Graph (og:title, og:image, product:price:amount). WooCommerce jih izpiše privzeto, prav tako večina tem Shopify. Kartica nikoli ne nastane iz besedila odgovora, zato si UI cene ne more izmisliti: povezava, ki se ne naloži, ali stran, ki ni izdelek (stran o dostavi, objava na blogu), ostane navadna povezava.

Povezane trgovine Shopify beremo prek Shopify Admin API namesto s strani: cena, zaloga in različice pridejo naravnost iz Shopifyja, deluje pa tudi v razvojni trgovini, zaščiteni z geslom.

Katere povezave se odprejo. Samo povezave na vaših straneh: domene s seznama dovoljenih domen widgeta, stran, na kateri je obiskovalec, in povezana trgovina Shopify ali WooCommerce. Vsaka zahteva gre skozi isto zaščito pred zasebnimi naslovi kot orodja po meri, tudi pri preusmeritvah. Strani so v predpomnilniku eno uro, zato priljubljen izdelek stane eno zahtevo na uro.

Omejitve. Največ 3 kartice na odgovor. Če trgovina ne odgovori v nekaj sekundah, je odgovor poslan brez kartic, ne pozneje.

Gumbi

Kartica ima največ dva gumba. Prvi je:

PrimerGlavni gumb
Ni na zalogiNi na zalogi (onemogočen)
Obiskovalec mora najprej izbrati velikost ali barvoIzberi možnosti: odpre stran izdelka
Vaša stran ga lahko doda v košaricoV košarico
SicerPoglej izdelek

Drugi gumb je vaš lasten (glejte spodaj) ali Poglej izdelek. Ko V košarico uspe, se gumb spremeni v Dodano · Odpri košarico. Povezave do vaše trgovine se odprejo v istem zavihku, kot vsaka povezava v trgovini; klepet po menjavi strani ostane v pogovoru.

Shopify in WooCommerce delujeta brez nastavitev. V trgovini Shopify widget doda različico prek lastnega /cart/add.js trgovine, v WooCommerce pa uporabi WooCommerce Store API, ki jo imajo tako teme z bloki kot klasične teme (kot rezervo klasično končno točko za dodajanje v košarico), in mini košarici sporoči, naj se osveži. Izdelek Shopify z več različicami pokaže Izberi možnosti, razen če povezava kaže na eno različico (?variant=123). Vgrajena košarica doda samo izdelke trgovine, na kateri je obiskovalec.

Vaši lastni gumbi

Registrirajte upravljalnik z forProducts: true in prikazal se bo na vsaki kartici. Prejme izdelek:

<script>
  window.HelpStack = window.HelpStack || function () {
    (window.HelpStack.q = window.HelpStack.q || []).push(arguments);
  };

  window.HelpStack('registerAction', 'wishlist', async (product) => {
    // product: { url, title, productId, variantId, price, currency, platform, quantity }
    await myWishlist.add(product.productId);
    return { ok: true };
  }, { forProducts: true, label: { en: 'Save for later', sl: 'Shrani za pozneje' } });
</script>
Možnost
forProductstrue naredi iz tega gumb na kartici namesto gumba »Pokaži mi«
labelBesedilo gumba: niz ali eno na jezik ({ en, sl, de, ... }), izbrano po jeziku obiskovalčevega brskalnika. Največ 40 znakov
primarytrue postavi vaš gumb na prvo mesto, pred V košarico

Ime add_to_cart je posebno: postane gumb V košarico na kartici in nadomesti vgrajenega za Shopify/WooCommerce. Uporabite ga v kateri koli drugi spletni trgovini. Vrnite { ok: true, cartUrl: '/cart' }, da Odpri košarico vodi na vašo stran košarice, ali { ok: false, message }, da se pod kartico prikaže neuspeh.

Za upravljalnike veljajo enaka pravila kot za gumbe za dejanja: 10 sekund na dotik, vržena napaka šteje kot neuspeh.

Kaj izve UI

V spletnem klepetu UI dobi navodilo, naj doda povezavo do vsakega izdelka, ki ga priporoči, in sicer samo povezave, ki jih je dobil iz orodja ali baze znanja, in največ 3 na odgovor. Ko se obiskovalec dotakne gumba na kartici, UI to prebere v naslednjem koraku (»tapnil V košarico na kartici za Gorsko kolo 29" in je uspelo«), da lahko nadaljuje. Vsak dotik se zapiše kot vrstica CLIENT_ACTION v dnevnik orodij, poimenovana po gumbu (add_to_cart, view_product, choose_options, view_cart ali vaš).

Izklop kartic

Kanali → Videz → Kartice izdelkov ali update_widget_config s productCards: false. Povezave potem ostanejo navadne povezave.

Seznam dovoljenih domen#

Kanal lahko omeji, kateri izvori smejo naložiti widget. Ko je seznam dovoljen konfiguriran in zahtevani izvor ni na njem, strežnik odgovori s 403. Konfigurirajte seznam dovoljenih v nastavitvah kanala na nadzorni plošči. Pustite prazno, da dovolite kateri koli izvor.

Primer minimalne strani#

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>HelpStack Widget Demo</title>
  </head>
  <body>
    <h1>My website</h1>
    <button onclick="window.ChatWidget.open()">Need help?</button>

    <!-- HelpStack widget -->
    <script
      src="https://helpstack.eu/widget.js?id=CHANNEL_ID"
      async
    ></script>
  </body>
</html>

Sorodne teme#