Sådan opsætter du en Brugerdefineret widget

Vis data fra dine egne systemer i Herodesk med HTML-indhold, handlingsknapper, formularer og underskrevne forespørgsler.

Written by Anders Eiler
Last updated 2026-03-19
På denne side

En Brugerdefineret widget lader dig vise data fra dine egne systemer i widget-panelet ved siden af hver samtale i Herodesk. Når en agent åbner en samtale, spørger Herodesk din server (din "endpoint") om indhold om kunden og viser svaret i panelet.

Eksempler er:

  • Dit eget CRM-, ERP- eller webshop-backend
  • Kontodata fra dit SaaS-produkt (plan, status, brug)
  • Andre tredjepartsværktøjer, som vi ikke har en indbygget widget til

Med en Brugerdefineret widget kan du:

  • Vise tekst, lister, tabeller og accordeoner med dine data
  • Vise dit eget HTML såsom kort, badges, farvede statusetiketter, sammenklappelige sektioner og fremdriftsbjælker (Herodesk Plus)
  • Lade agenter udføre handlinger i dit system, for eksempel "Annuller ordre", "Send bekræftelse igen" eller "Forlæng prøveperiode med 14 dage", eventuelt ved først at spørge agenten om værdier. Resultatet vises i widgeten og registreres i samtalens tidslinje (Herodesk Pro)
  • Modtage udvidet kontekst om kontakt, virksomhed, samtale og agent, så du kan finde kunden via dine egne id'er i stedet for kun via e-mailadresse (Herodesk Plus)
  • Verificere at forespørgsler kommer fra Herodesk med underskrevne forespørgsler, en Authorization-header og unikke forespørgsels-id'er
  • Teste og fejlfinde med indbyggede udviklerværktøjer: send en testforespørgsel, forhåndsvis et svar og se en log over nylige forespørgsler

Eksisterende Brugerdefinerede widgets fortsætter med at fungere som før. Alle nye muligheder er slået fra, indtil en administrator aktiverer dem.

Planer og tilgængelighed

FunktionBasicPlusPro
Brugerdefineret widget med tekst, lister, tabeller og accordeonerJaJaJa
Anmodningssignering, Authorization-header, forespørgsels-id'erJaJaJa
Udviklerværktøjer (testforespørgsel, forhåndsvisning, forespørgselslog)JaJaJa
HTML-indhold og sammenklappelige sektionerNejJaJa
Udvidet kontekstNejJaJa
Handlingsknapper og formularer, "Hvem kan udføre handlinger", tidslinjeindlæg for handlingerNejNejJa

Den Brugerdefinerede widget er ikke tilgængelig på Gratis-planen. Hvis en indstilling ikke er inkluderet i din plan, vises den nedtonet med et opgraderingshint.

Hvis du nedgraderer mens en funktion er aktiveret, stopper Herodesk med at bruge den med det samme, selvom indstillingen stadig siger "Ja":

  • HTML-indhold vises ikke. Widgeten viser "JSON-inputtet indeholder HTML-elementer, som kun er tilgængelige på Herodesk Plus-planen."
  • Udvidet kontekst sendes ikke længere.
  • Handlingsknapper er deaktiverede. Hvis en alligevel aktiveres, ser agenten "Handlingsknapper er kun tilgængelige på Herodesk Pro-planen."

Sådan fungerer det

  1. En agent åbner en samtale.
  2. Herodesk sender en POST-forespørgsel med JSON til URL'en i dine widget-indstillinger.
  3. Din endpoint slår kunden op og svarer med JSON i det format, der er beskrevet nedenfor.
  4. Herodesk viser indholdet i widget-panelet.
  5. (Pro) Hvis agenten klikker på en handlingsknap, sender Herodesk en POST-forespørgsel til knapens URL, og dit system svarer med et resultat som {"status":"success","message":"Ordre #1080 blev annulleret."}. Resultatet vises i widgeten og tilføjes til samtalens tidslinje.

Godt at vide:

  • Herodesks server foretager alle kald, aldrig agentens browser. Din server ser forespørgsler fra Herodesk, ikke fra agenternes computere. Du behøver ikke konfigurere CORS eller eksponere noget til browseren.
  • URL'en skal være en offentlig webadresse (http eller https). Lokale eller interne adresser som localhost eller 192.168.… afvises, når du gemmer indstillingerne.
  • Herodesk venter højst 30 sekunder på et svar og følger ikke redirects. En endpoint, der omdirigerer (for eksempel fra http til https eller til en login-side), vises som en fejl.
  • Widgeten indlæses hver gang en samtale åbnes, så indholdet altid er frisk.

Installer en Brugerdefineret widget

Gå til Indstillinger → Widgets → Tilføj widget og vælg Brugerdefineret widget.

FeltHvad det gør
VisningsnavnNavnet, der vises på widgeten i panelet, så dit team ved, hvilket system dataene kommer fra. Kun bogstaver, tal, mellemrum og _ - & (ingen parenteser).
UrlDin endpoint. Herodesk sender sine forespørgsler hertil. Skal være en offentlig adresse. Bestemmer også, hvilke adresser handlingsknapper må kalde (se Handlingsknapper).
Tillad HTML-indhold (Plus)Lader din endpoint sende html-elementer. Standard: Nej.
Send udvidet kontekst (Plus)Tilføjer et context-objekt med kontakt-, virksomheds-, samtale- og agentdetaljer til hver forespørgsel. Standard: Nej.
SigneringshemmelighedHvis sat, underskrives hver forespørgsel, så din endpoint kan verificere, at den kommer fra Herodesk. Valgfrit, mindst 16 tegn. Gemmes krypteret og vises som ********. Tøm feltet og gem for at fjerne det.
Authorization-headerSendes som Authorization-header på hver forespørgsel, for eksempel Bearer DIN_API_NØGLE. Nyttigt for endpoints bag en API-gateway eller der kræver en API-nøgle. Valgfrit, én linje almindelig tekst, maks 1024 tegn. Gemmes krypteret og vises maskeret. Tøm feltet og gem for at fjerne det.
Hvem kan udføre handlinger (Pro)Alle, der kan se samtalen, kun administratorer eller administratorer og udvalgte teams. Standard: alle. Administratorer kan altid udføre handlinger.
Teams, der kan udføre handlinger (Pro)De teams, der er tilladt, når "Administratorer og udvalgte teams" vælges. Mindst ét team kræves.
Aktiveret / Vis standard / Dynamisk visning / Skjul ved tomSom for alle widgets. "Skjul ved tom" virker med foundItems (se nedenfor). En deaktiveret widget indlæses ikke, og dens knapper afvises.

Under Gem-knappen finder du Udviklerværktøjer og den indbyggede reference "Sådan bruger du en Brugerdefineret widget" med de præcise formater. Den indbyggede reference findes også på dansk og tysk.

Responsformatet

Din endpoint svarer med et JSON-objekt som dette:

{
  "headline": "Nordlys Living shop",
  "foundItems": 1,
  "elements": [
    { "header": "Noter", "type": "text", "content": "**VIP** kunde, foretrækker e-mail" },
    { "header": "Tags", "type": "list", "content": ["Engros", "Danmark"] },
    { "header": "Ordrer", "type": "table", "content": {
        "tableHead": ["Ordre", "Status"],
        "tableBody": [["#1080", "Afsendt"], ["#1074", "Leveret"]]
    }},
    { "header": "Historik", "type": "accordion", "content": [
        { "header": "Returneringer (3)", "content": [
            { "type": "text", "content": "RMA-2207 refunderet" }
        ]}
    ]}
  ]
}
  • headline (påkrævet, streng): vises øverst i widgeten.
  • elements (påkrævet, array): vises i den rækkefølge, de tilføjes. Hvert element har en header, en type og et content. Du kan tilføje så mange elementer, du har brug for.
  • foundItems (valgfri, heltal 0 eller mere): hvor mange resultater du fandt. Hvis det er 0, og Skjul ved tom er aktiveret, skjules widgeten for den samtale.

Elementtyper

  • text: en streng.
  • list: et array af strenge.
  • table: et objekt med tableHead (array af strenge) og tableBody (array af rækker, hver et array af strenge).
  • accordion: sammenklappelige elementer. Alle starter sammenklappede, og kun ét er åbent ad gangen. Indholdet er et array af elementer, og hvert element skal have en header (den klikbare titel) og et content-array af blokke. En blok er et text, list, table eller html-element med en valgfri header, der vises som etiket over det. Accordeoner kan ikke være indlejret i hinanden.
  • html (Plus, kræver "Tillad HTML-indhold"): dit eget HTML. Se HTML-indhold nedenfor.

Formatering i tekst og lister

  • Fed: **fed tekst**
  • Kursiv: *kursiv tekst*
  • Kode: tekst i backticks
  • Links: [linktekst](url)
  • Knap-links: [Gå til Herodesk](https://herodesk.io){:target="_blank" :class="btn btn-primary"}

Linkadresser kan bruge http, https, mailto eller tel. Andre skemaer fjernes af sikkerhedshensyn. Alt, hvad din endpoint sender, vises som indhold: Herodesk kører aldrig kode fra det.

Hvad Herodesk sender

Hver forespørgsel

Herodesk sender en POST-forespørgsel med denne JSON-krop:

{
  "widget_id": 6,
  "contact_email": "ida.skov@example.com",
  "conversation_id": "17"
}

conversation_id sendes som en streng. I PHP kan du læse kroppen sådan her:

$data = json_decode(file_get_contents('php://input'), true);

Headers:

HeaderNårVærdi
Content-TypeAltidapplication/json; charset=UTF-8
User-AgentAltidHerodesk/1.0 (+https://herodesk.io; abuse@herodesk.io) CustomWidget/1.0
X-Herodesk-Request-IdAltidEt unikt id (UUID) for denne forespørgsel. Log det på din side; det gør fejlfinding meget nemmere.
AuthorizationHvis sat i indstillingerneDen konfigurerede værdi, for eksempel Bearer …
X-Herodesk-Timestamp og X-Herodesk-SignatureHvis en signeringshemmelighed er satSe Verificering af forespørgsler nedenfor.

Udvidet kontekst (Plus)

Med Send udvidet kontekst slået til indeholder kroppen også et context-objekt:

"context": {
  "contact": {"id": 1, "name": "Ida Skov", "firstname": "Ida", "lastname": "Skov",
              "email": "ida@example.com", "phone": "+45…",
              "custom_fields": {"external_user_id": "u_123", "plan": "pro"}},
  "company": {"id": 7, "name": "Møbelhuset", "domain": "moebelhuset.dk", "company_number": "DK123",
              "industry": "Retail", "custom_fields": {"account_id": "acc_9"}},
  "conversation": {"id": 17, "subject": "…", "status": "open",
                   "inbox": {"id": 1, "name": "Support"},
                   "channel": {"id": 2, "name": "support@…", "type": "email"},
                   "tags": ["vip"],
                   "assignee": {"id": 4, "name": "…", "email": "…"},
                   "team": {"id": 2, "name": "Customer Care"}},
  "agent": {"id": 1, "name": "…", "email": "…", "role": "admin",
            "teams": [{"id": 2, "name": "Customer Care"}],
            "locale": "da-DK", "timezone": "Europe/Copenhagen"}
}
  • Brugerdefinerede felter listes efter deres slug (se Indstillinger → Brugerdefinerede felter) og inkluderer hvert felt, null når tomt. Multi-select felter er lister.
  • company, assignee og team er null, når de ikke er sat.
  • status er en af: pending, open, closed, spam, merged, snoozed, draft.
  • channel.type er en af: email, chat, facebook_messenger, instagram, flexfone, whatsapp, unitel, three.
  • agent er personen, der ser samtalen. role er admin, manager eller agent.

Typisk brugssag: du gemmer dit eget bruger-id eller konto-id i et kontakt- eller virksomhedsbrugerdefineret felt (via Herodesk API eller en regel), og din endpoint slår kunden op via det id i stedet for via e-mail. Dette løser det almindelige problem "kunden skrev fra en anden e-mailadresse".

Privatliv: med udvidet kontekst til, modtager din endpoint kontaktens navn, e-mail, telefon og brugerdefinerede felter, virksomhedsdetaljer, samtaledetaljer og den seende agents navn, e-mail, rolle og teams. Uden det sendes kun kontaktens e-mail og ovenstående id'er. Handlingsforespørgsler inkluderer altid den klikende agents id og e-mail.

HTML-indhold (Plus)

Slå Tillad HTML-indhold til. Din endpoint kan så sende elementer af typen html, enten på topniveau eller som en blok inde i en accordeon:

{ "header": "Seneste ordre", "type": "html",
  "content": "<p>Ordre <strong>#1080</strong> <span class=\"badge text-bg-success\">Afsendt</span></p>" }

Sådan ser det ud og opfører sig

  • HTML'en renses og vises i en isoleret ramme i panelet, med samme skrifttype og farver som resten af Herodesk.
  • Rammen passer altid: den vokser til præcis højden af indholdet (ingen scrollbar), følger panellets bredde og bryder lange ord, links og brede tabeller, så intet stikker ud i siderne. Den ændrer også størrelse, når en sammenklappelig sektion åbnes eller lukkes.
  • Links åbnes altid i en ny browserfane, så agenten aldrig forlader samtalen.

Hvad er tilladt

  • Tekst og formatering: afsnit, overskrifter (h1 til h6), fed, kursiv, understregning, gennemstregning, lille skrift, sub- og superscript, citater, linjeskift, vandrette linjer, pre og code.
  • Lister (punkt-, nummererede, definitionslister) og tabeller (med header, body, footer, caption og kolonnebredder).
  • Billeder med https-adresser eller små PNG-, GIF- eller JPEG-billeder indlejret som data, med bredde og højde.
  • div og span med class og style-attributter, så du kan bygge kort, rækker, badges og farvet tekst.
  • Sammenklappelige sektioner med <details> og <summary>, for eksempel <details><summary>Returneringer (3)</summary><p>RMA-2207 refunderet</p></details>. Tilføj open for at vise en sektion udvidet.
  • Inline-stilarter for farver, baggrunde, kanter, afrundede hjørner, marginer og padding, skrifttyper, tekstjustering, bredder og højder, float, linjehøjde, bogstavafstand og liste-stilarter.
  • <style>-blokke. Disse konverteres automatisk til inline-stilarter, så du kan skrive normal CSS.
  • Handlingsknapper og formularfelter (Pro, se nedenfor).

Hvad fjernes

Disse fjernes uden varsel:

  • Al JavaScript: <script>, event handlers som onclick og javascript:-links.
  • Formularer, der sender sig selv, iframes, indlejrede objekter, SVG, <meta>, <link> og <base>.
  • Positionering (position, z-index), display og størrelser i viewport-enheder (vh, vw og lignende).
  • Relative adresser som /orders/1. Links og billeder skal bruge fulde adresser (https://…).
  • Billeder og CSS-baggrunde, der peger på Herodesk selv.

Færdiglavede klasser

Du kan bruge disse klasser, som spejler velkendte Bootstrap-navne:

text-muted small fw-bold text-start text-center text-end text-success text-warning text-danger m-0 mb-0 mb-1 mb-2 mb-3 mt-2 d-flex justify-content-between align-items-center flex-grow-1 badge text-bg-primary text-bg-success text-bg-warning text-bg-danger text-bg-secondary btn btn-primary btn-success btn-danger btn-outline-secondary btn-sm alert alert-success alert-warning alert-danger alert-info table-borderless

Grænser

Maks 100 KB per html-element og 300 KB HTML per svar i alt. Større svar viser "JSON-inputtet stemmer ikke overens med specifikationerne".

Handlingsknapper (Pro)

Knapper inde i et html-element kan udløse en handling i dit system. Handlingsknapper kræver, at Tillad HTML-indhold er slået til.

<button class="btn btn-danger btn-sm"
        data-hd-action-url="https://shop.example/herodesk/orders/1080/cancel"
        data-hd-payload='{"order":1080,"reason":"customer request"}'
        data-hd-confirm="Annuller ordre #1080?">Annuller ordre</button>
AttributPåkrævetBetydning
data-hd-action-urlJaDen adresse Herodesk kalder. Den skal bruge præcis samme skema, vært og port som widgetens Url. Kun sti og query kan være forskellige.
data-hd-payloadNejEkstra information som JSON (maks 8 KB) sendt med forespørgslen, for eksempel ordrenummer. Meget store heltal ankommer som tekst for at bevare nøjagtigheden.
data-hd-confirmNejViser en "Bekræft venligst"-dialog med denne tekst, før handlingen udføres. Anbefales til destruktive handlinger.

Eksempel: med Url https://shop.example/herodesk/widget er handlings-URL https://shop.example/anything tilladt. https://api.shop.example/… (et subdomæne), http://shop.example/… (andet skema) og https://shop.example:8443/… (anden port) er ikke.

Hvad oplever agenten

  1. Agenten klikker på knappen. Hvis en bekræftelsestekst er sat, spørger Herodesk først.
  2. Knappen gråtones, mens handlingen kører.
  3. Resultatet vises under knappen: grønt for succes, rødt for fejl, med beskeden fra dit system.
  4. Hvis dit system beder om det, genindlæses widgeten for at vise den nye tilstand, og beskeden vises i stedet som en notifikation.
  5. Et indlæg tilføjes til samtalens tidslinje, for eksempel "Udførte Annuller ordre i widget Shop: Ordre #1080 blev annulleret. kl. 14:02 af Sofie Lindberg", eller "Forsøgte …, som fejlede: …". Det samme indlæg vises i revisionsloggen som "Brugerdefineret widget-handling".

Agenter, der ikke har tilladelse til at udføre handlinger, ser knapperne gråtonede med tooltip "Du har ikke tilladelse til at udføre handlinger i denne widget."

Hvad modtager dit system

{
  "type": "action",
  "request_id": "3f2b8c1e-9d4a-4f6b-8a2c-1e5d7b9f0a3c",
  "action_url": "https://shop.example/herodesk/orders/1080/cancel",
  "payload": {"order": 1080, "reason": "customer request"},
  "inputs": {"days": "14", "reason": "bug"},
  "widget_id": 6,
  "conversation_id": 17,
  "contact_email": "customer@example.com",
  "agent": {"id": 1, "email": "agent@yourcompany.com"},
  "context": { "…": "kun med udvidet kontekst" }
}
  • Handlingsforespørgsler er underskrevet og autoriseret på samme måde som indholdsforespørgsler (samme headers).
  • request_id er unikt pr. klik og identisk med X-Herodesk-Request-Id-headeren. Hvis dit system modtager samme id to gange, bør det ikke udføre handlingen igen. Dette forhindrer for eksempel dobbelt refundering.
  • inputs indeholder formularværdierne (se Handlingsformularer), eller {} hvis der ikke er nogen formular.

Hvad dit system skal svare

HTTP 200 (enhver 2xx-status) med JSON:

{"status": "success", "message": "Ordre #1080 blev annulleret.", "refresh": true}
  • status: præcis "success" vises som succes (grøn). Alt andet vises som fejl (rød).
  • message: en kort almindelig tekst, der vises for agenten. Maks 500 tegn, HTML-tags fjernes. Hvis du udelader den, ser agenten "Udført."
  • refresh (valgfri): true genindlæser widgeten bagefter.

Alt andet (en anden HTTP-status, intet JSON, en redirect, timeout efter 30 sekunder eller en utilgængelig server) vises som "Handlingen kunne ikke gennemføres."

Handlingsformularer (Pro)

For at spørge agenten om værdier, før en handling udføres, læg knappen og formularfelterne inde i et <fieldset>. Når knappen klikkes, sendes værdierne af de navngivne felter i samme fieldset som inputs:

<fieldset>
  <legend>Forlæng prøveperiode</legend>
  <label>Dage <input type="number" name="days" min="1" max="30" value="14" required></label>
  <label>Årsag
    <select name="reason" required>
      <option value="">Vælg…</option>
      <option value="bug">Fejl i produkt</option>
      <option value="sales">Salgsforespørgsel</option>
    </select>
  </label>
  <label><input type="checkbox" name="notify" checked> Underret kunde</label>
  <button class="btn btn-primary btn-sm"
          data-hd-action-url="https://shop.example/herodesk/trial/extend"
          data-hd-payload='{"account":"acc_9"}'>Forlæng prøveperiode</button>
</fieldset>
  • Felttyper: tekst, tal, dato, e-mail, telefon, url, checkbox, radio, dropdowns (select) og flersporet tekst (textarea).
  • Validering: required, min, max, step og maxlength kontrolleres, før noget sendes. Hvis et felt er ugyldigt, peger browseren på det, og intet sendes.
  • Hvordan værdier modtages:
    • Tekst, tal, datoer og dropdowns: som tekst ("14")
    • En checkbox uden value-attribut: true eller false
    • En checkbox med value-attribut: den værdi, når den er markeret, ellers null
    • Felter med navn, der ender på [] (for eksempel en gruppe checkboxes med navn items[]): en liste over markerede værdier
    • En radiogruppe uden valgt: null
  • Grænser: højst 50 felter, hver højst 2000 tegn.
  • Ikke tilladt: password-, skjulte- og filfelter omdannes til almindelige tekstfelter. Sæt faste værdier i data-hd-payload i stedet.
  • Browserens autofyld er altid slået fra i disse felter, så agenters gemte oplysninger aldrig ender i din formular.
  • Mens handlingen kører, låses felterne.

Hvem kan udføre handlinger (Pro)

Vælg i widget-indstillingerne, hvem der må bruge handlingsknapper:

  • Alle, der kan se samtalen (standard)
  • Kun administratorer
  • Administratorer og udvalgte teams

Administratorer kan altid udføre handlinger. Indstillingen håndhæves på Herodesk-serveren, ikke kun i browseren, så en agent uden tilladelse kan ikke udføre en handling på anden måde. En deaktiveret widget afviser alle handlinger.

For finere regler, som "kun niveau 2 må refundere over 500 DKK", lad dit eget system afgøre det: det modtager agentens id og e-mail, og med udvidet kontekst også agentens rolle og teams.

Verificering af forespørgsler

Signeringshemmelighed

Når du sætter en signeringshemmelighed, bærer hver forespørgsel (indhold og handlinger) to ekstra headers:

  • X-Herodesk-Timestamp: tidspunktet for forespørgslen i Unix-sekunder
  • X-Herodesk-Signature: sha256= efterfulgt af en HMAC-SHA256 af timestamp + "." + den rå forespørgselskrop, med din hemmelighed som nøgle

Dit system bør afvise en forespørgsel, hvis signaturen ikke matcher, eller hvis tidsstemplet er mere end 5 minutter gammelt, og sammenligne signaturer i konstant tid. Brug altid den rå krop præcis som modtaget, ikke en re-enkodet version.

PHP:

$body = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_HERODESK_TIMESTAMP'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $body, $secret);

if (!hash_equals($expected, $_SERVER['HTTP_X_HERODESK_SIGNATURE'] ?? '') || abs(time() - (int)$timestamp) > 300) {
    http_response_code(401);
    exit;
}

Node.js (Express):

const crypto = require('crypto');

app.post('/herodesk/widget', express.raw({ type: 'application/json' }), (req, res) => {
  const timestamp = req.get('X-Herodesk-Timestamp') || '';
  const expected = 'sha256=' + crypto.createHmac('sha256', SECRET).update(timestamp + '.' + req.body).digest('hex');
  const given = req.get('X-Herodesk-Signature') || '';
  const valid = given.length === expected.length
    && crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected))
    && Math.abs(Date.now() / 1000 - Number(timestamp)) <= 300;
  if (!valid) return res.status(401).end();
  const data = JSON.parse(req.body);
  // …
});

Authorization-header

Hvis din endpoint forventer en API-nøgle, for eksempel bag en API-gateway, indtast den i feltet Authorization-header. Den sendes som Authorization-header på hver forespørgsel. Værdien gemmes krypteret og vises aldrig igen i fuld længde (udviklerværktøjerne viser Bearer ********).

Forespørgsels-id'er

Hver forespørgsel bærer en X-Herodesk-Request-Id-header. Den vises i widgetens forespørgselslog og, hvis du logger den, i dine egne logs. Inkluder den, når du kontakter vores support om et problem.

Udviklerværktøjer

Administratorer finder udviklerværktøjerne under Gem-knappen på widgetens indstillingsside. De bruger de gemte indstillinger, så gem dine ændringer først.

  • Send en testforespørgsel: indtast et samtale-id (eller lad det være tomt for at bruge din seneste samtale) og klik "Send testforespørgsel". Du ser:
    • HTTP-status, hvor lang tid det tog, hvilken samtale der blev brugt og forespørgsels-id
    • Den præcise forespørgsel: adresse, alle headers (Authorization-værdien maskeret), kroppen i læsbar form og den præcise krop som sendt (de bytes, signaturen beregnes over, nyttigt ved fejlfinding af signaturkontrol)
    • Det rå svar (første 20 KB)
    • Resultatet præcis som agenter vil se det, i panelbredde (handlingsknapper er deaktiverede i forhåndsvisninger)
  • Forhåndsvis JSON: indsæt et svar og klik "Vis forhåndsvisning" for at se, hvordan det ser ud uden at kalde din endpoint. Godt til at designe HTML.
  • Nylige forespørgsler: de sidste 50 forespørgsler fra de sidste 7 dage (panelindlæsninger, handlinger og tests) med tid, type, resultat (HTTP-status eller fejl), varighed, adresse (uden query-string), bruger og forespørgsels-id. "Ryd" tømmer listen.

Sikkerhedstjekliste

Hvad Herodesk beskytter automatisk

  • Dit HTML kan aldrig køre kode i Herodesk eller nå agenters sessioner. Det renses, vises i en isoleret ramme uden JavaScript og begrænses af en streng sikkerhedspolitik.
  • Falske overlays, loginformularer og skjulte tracking-tricks fjernes.
  • Herodesk kalder kun offentlige adresser, følger aldrig redirects og kalder kun handlings-URL'er på din endpoints egen adresse.
  • Agenters adgang til samtalen kontrolleres ved hver forespørgsel. Handlinger kontrollerer også planen, widgetens status og "Hvem kan udføre handlinger".
  • Hemmeligheder gemmes krypteret og vises aldrig.

Hvad du skal gøre

  • Escape altid HTML-data, som dine egne kunder kan skrive (navne, adresser, ordrenoter, anmeldelser) før du indsætter det i dit HTML. Ellers kan nogen skrive markup, inklusive en falsk handlingsknap, i en ordrenote. Herodesks rensning beskytter Herodesk, men kan ikke skelne mellem din tilsigtede markup og markup skrevet i dine data.
  • Behandl hver handlings-URL som en offentlig API: verificer signaturen, tjek at agenten må gøre det, valider payload og inputs, og ignorer gentagne forespørgsels-id'er.
  • Brug data-hd-confirm til destruktive handlinger.
  • Læg ikke hemmeligheder eller tokens i HTML eller payload. Agenter kan se HTML.

Færdigt eksempel på endpoint (PHP)

Én fil håndterer både widget-indhold og dens handlinger:

<?php
header('Content-Type: application/json');

$body = file_get_contents('php://input');
// (verificer X-Herodesk-Signature her, se "Verificering af forespørgsler")
$data = json_decode($body, true);

if (($data['type'] ?? null) === 'action') {
    // Ignorer gentagne klik/forsøg.
    if (alreadyProcessed($data['request_id'])) {
        echo json_encode(['status' => 'success', 'message' => 'Allerede udført.']);
        exit;
    }
    $order = (int)($data['payload']['order'] ?? 0);
    if (!agentMayCancel($data['agent']['email'], $order)) {
        echo json_encode(['status' => 'error', 'message' => 'Du har ikke tilladelse til at annullere denne ordre.']);
        exit;
    }
    cancelOrder($order, $data['inputs']['reason'] ?? null);
    markProcessed($data['request_id']);
    echo json_encode(['status' => 'success', 'message' => "Ordre #$order blev annulleret.", 'refresh' => true]);
    exit;
}

$order = findLatestOrder($data['contact_email']);
if ($order === null) {
    echo json_encode(['headline' => 'Shop', 'foundItems' => 0, 'elements' => []]);
    exit;
}

$note = htmlspecialchars($order->customerNote, ENT_QUOTES); // ESCAPE ALTID kundeskrevet tekst
echo json_encode([
    'headline' => 'Shop',
    'foundItems' => 1,
    'elements' => [[
        'header' => 'Seneste ordre',
        'type' => 'html',
        'content' => "<p><strong>Ordre #{$order->id}</strong> <span class=\"badge text-bg-success\">{$order->status}</span></p>"
            . "<p class=\"small text-muted\">{$note}</p>"
            . "<fieldset>"
            . "<label>Årsag <select name=\"reason\" required><option value=\"\">Vælg…</option>"
            . "<option value=\"customer\">Kundens anmodning</option><option value=\"stock\">Udsolgt</option></select></label>"
            . "<button class=\"btn btn-danger btn-sm\" data-hd-action-url=\"https://shop.example/herodesk/widget\""
            . " data-hd-payload='{\"order\":{$order->id}}' data-hd-confirm=\"Annuller ordre #{$order->id}?\">Annuller ordre</button>"
            . "</fieldset>",
    ]],
]);

Fejlfinding

Start med Send testforespørgsel i udviklerværktøjerne. Det besvarer de fleste "hvorfor virker min widget ikke"-spørgsmål.

Beskeder i widgeten

BeskedBetydningHvad du skal gøre
Forespørgsel mislykkedes (med detaljer)Herodesk kunne ikke nå din endpoint, eller forespørgslen blev afvist: ikke offentlig, utilgængelig, timeout eller redirect.Tjek at URL'en er offentlig, svarer inden for 30 sekunder og ikke redirecter.
JSON-syntaksfejl: …Din endpoint svarede, men ikke med gyldig JSON.Tjek det rå svar i testværktøjet.
JSON-inputtet stemmer ikke overens med specifikationerneGyldig JSON, men ikke den krævede struktur (mangler headline eller elements, ukendt type, HTML for stor osv.).Sammenlign med responsformatet ovenfor og brug "Forhåndsvis JSON".
JSON-inputtet indeholder HTML-elementer, men "Tillad HTML-indhold" er ikke aktiveret for denne widgetHTML blev sendt, men indstillingen er slået fra.Slå "Tillad HTML-indhold" til.
JSON-inputtet indeholder HTML-elementer, som kun er tilgængelige på Herodesk Plus-planen.HTML blev sendt, men din plan inkluderer det ikke.Opgrader til Plus, eller send kun tekst-, liste-, tabel- og accordeonelementer.
Kontakt ikke fundetSamtalen har ingen kontakt.Intet at gøre. Widgeten har brug for en kontakt at slå op.
Handlingsknapper er kun tilgængelige på Herodesk Pro-planen.En handling blev brugt på en lavere plan.Opgrader til Pro.
Handlinger kræver, at "Tillad HTML-indhold" er aktiveret for denne widget.Knapper ligger i HTML, og HTML er slået fra.Slå "Tillad HTML-indhold" til.
Du har ikke tilladelse til at udføre handlinger i denne widget."Hvem kan udføre handlinger" udelukker denne agent.Bed en administrator om at justere indstillingen eller agentens teams.
Handlings-URL'en skal bruge samme adresse (skema, vært og port) som widget-URL'en.Knappen peger på en anden adresse (anden vært, et subdomæne, http i stedet for https eller en anden port).Peg knappen på din endpoints egen adresse.
Handlings-payload skal være gyldig JSON på maks 8 KB.data-hd-payload er ødelagt eller for stor.Ret JSON i knappen.
Formularfelterne kunne ikke sendes. Tjek at der er maks 50 navngivne felter på maks 2000 tegn hver.For mange eller for lange formularfelter.Reducer formularen.
Handlingen kunne ikke gennemføres.Handlings-URL'en svarede ikke korrekt (ikke-2xx status, intet JSON, timeout, redirect eller utilgængelig).Tjek din handlings-endpoint og forespørgselsloggen.
Udført.Handlingen lykkedes, men din endpoint sendte ingen besked.Send en message i svaret.

Beskeder på indstillingssiden

BeskedHvad du skal gøre
Visningsnavnet må kun indeholde bogstaver, tal, mellemrum og følgende tegn: _ - &Fjern andre tegn, for eksempel parenteser.
Adressen skal pege på en offentlig server.Brug en offentlig adresse, ikke en intern eller lokal.
Signeringshemmelighed bør indeholde mindst 16 tegn.Brug en længere hemmelighed.
Authorization-header skal være en enkelt linje almindelig tekst.Fjern linjeskift og specialtegn.
Vælg mindst ét team.Vælg et team, eller vælg en anden "Hvem kan udføre handlinger"-mulighed.

Ofte stillede spørgsmål

Vil min eksisterende widget gå i stykker?

Nej. Intet ændres, før en administrator aktiverer de nye muligheder. Eksisterende endpoints modtager stadig de samme tre felter plus en ekstra forespørgsels-id-header, som de kan ignorere.

Kan vi køre vores eget JavaScript i widgeten?

Nej, det er designet sådan. Handlingsknapper og formularer dækker interaktive behov uden JavaScript, og Herodesk foretager kaldende.

Hvorfor vises mine billeder ikke?

De skal bruge fulde https://-adresser eller være små indlejrede PNG-, GIF- eller JPEG-billeder. Billeder på Herodesk's egne adresser fjernes.

Altid, så agenten aldrig forlader samtalen.

Hvorfor mistede mit layout sin positionering?

position, z-index, display og viewport-enheder fjernes. Brug normal flow, d-flex-klassen eller tabeller.

Kan handlingsknapper kalde et andet domæne, for eksempel vores API-subdomæne?

Nej. Handlinger skal bruge præcis endpoints adresse. Ruter handlingen gennem din endpoints vært i stedet.

Bruger AI-agenten eller Copilot widgeten?

Nej. Indhold og knapper i den Brugerdefinerede widget bruges ikke af AI-agenten. Til AI, brug AI-agent brugerdefinerede funktioner. For at skrive data tilbage til Herodesk (for eksempel plan eller MRR i brugerdefinerede felter), brug Herodesk API.

Hvad sker der, hvis vi nedgraderer?

Funktionerne, der ikke er inkluderet i den nye plan, stopper med at virke med det samme, med en klar besked. Se Planer og tilgængelighed ovenfor.

Hvordan fjerner jeg en signeringshemmelighed eller API-nøgle?

Tøm feltet og gem.

Hvordan forhindrer vi, at den samme handling udføres to gange?

Brug request_id. Det samme klik har altid samme id, så dit system kan ignorere et id, det allerede har behandlet.

Kan jeg anmode om andre datatyper?

Kontakt os på support@herodesk.io.