---
title: "Botberichten - mssgs | Embeds, knoppen & live-bijgewerkte kaarten"
description: "mssgs botberichten-documentatie. Rijke embed-kaarten met statusbadges en diff-stats, loader- en thinking-status, interactieve knoppen met triggerketens."
canonical: https://mss.gs/nl/docs/bots
language: nl
---

# Botberichten

Rijke embed-kaarten, interactieve knoppen en live-bijgewerkte berichten voor bots

## Overzicht

Bots plaatsen rijke berichten door een action_message te sturen. Het veld message_container.type bepaalt hoe de client het rendert:

- ** embed_message **: een rijke kaart met gekleurd accent, bot-header, klikbare titel, markdown-body, statusbadge, diff-stats, loader en inklapbare redenering. Gemaakt voor GitHub-notificaties, CI-resultaten, deploys en AI-assistenten.

- ** system_message **: een geverifieerde systeemkaart met interactieve knoppen die triggerketens uitvoeren.

#### Waar past dit?

Je verstuurt deze payloads via dezelfde webhook- en trigger-integraties uit de [API-documentatie](https://mss.gs/nl/docs). Deze gids beschrijft de volledige message containers: wat er in een kaart kan en hoe knoppen zich gedragen.

## Embed-berichten

Een embed rendert met een gekleurd linkeraccent, een header "Message from {bot} {badge}", een klikbare titel, een subtitel en een markdown-beschrijving.

```json
{
  "type": "action_message",
  "channel_guid": "...",
  "server_guid": "...",
  "message_container": {
    "type": "embed_message",
    "bot_name": "Github Notifications",
    "avatar_url": "https://avatars.githubusercontent.com/u/310687?v=4",
    "badge": "acme/acme-core",
    "color": "purple",
    "title": "alex opened pull request #144",
    "title_url": "https://github.com/acme/acme-core/pull/144",
    "sub_title": "Resolve outlying hamlet to dominant nearby city",
    "description": "A hamlet is the smallest OSM settlement class ...",

    "status": { "label": "Open", "color": "green", "icon": "pull_request" },
    "additions": 86,
    "deletions": 38,
    "files_changed": 2
  }
}
```

#### alex opened pull request #144

Resolve outlying hamlet to dominant nearby city

### Containervelden

| Veld | Type | Beschrijving |
| --- | --- | --- |
| type | string | Moet "embed_message" zijn |
| bot_name | string | Getoond in de header: "Message from {bot_name}" |
| badge | string | Tweede header-chip na de botnaam (bijv. acme/acme-core ) |
| avatar_url | string | Bot-/bron-avatar, over het systeemicoon. Volledige URL, of een pad dat de statische host als prefix krijgt |
| color | string | Linkeraccentkleur: blue (standaard), green , purple , red , orange , yellow |
| title | string | Vetgedrukte titelregel |
| title_url | string | Indien gezet wordt de titel een link die deze URL opent |
| sub_title | string | Tweede vetgedrukte regel onder de titel |
| description | string | Bodytekst. Ondersteunt markdown: vet, inline code, fenced codeblokken, quotes en checkboxes |
| fields | array | [{ "field": "...", "value": "..." }] : label/waarde-rijen met kopieerknop |
| image_url / image_base64 | string | Optionele afbeelding, rechts uitgelijnd |

#### Lange beschrijvingen

De server kan een lange description afkappen. In dat geval bevat het bericht message_big_embed_guid en toont de client een **Show more**-knop die de volledige body ophaalt.

### Statusbadge & diff-stats

Allemaal optioneel. De status -badge rendert naast de titel; de diff-stats staan in de footer, rechts van de tijd. Elke combinatie kan; laat je alles weg, dan ziet de embed er precies uit als voorheen. Zonder title valt de statusbadge terug in de footergroep.

| Veld | Type | Beschrijving |
| --- | --- | --- |
| status | object \| string | Gekleurde statuspil. Een kale string wordt behandeld als { "label": <string> } |
| status.label | string | Piltekst, bijv. "Open" , "Merged" , "Passing" . Vereist om de pil te renderen |
| status.color | string | green , purple , red , orange , yellow , blue , gray (standaard gray , of valt terug op de containerkleur) |
| status.icon | string | Optioneel icoon uit de vaste set hieronder. Onbekend/afwezig → geen icoon |
| additions | number | Toegevoegde regels → groen +86 |
| deletions | number | Verwijderde regels → rood -38 |
| files_changed | number | Gewijzigde bestanden → chip 2 files ( 1 file bij 1) |

#### status.icon -waarden

| Waarde | Icoon | Typisch gebruik |
| --- | --- | --- |
| pull_request | git-pull-request | PR geopend / open |
| pull_request_closed | git-pull-request-closed | PR gesloten zonder merge |
| merge / merged | git-merge | PR gemerged |
| commit | git-commit | Gepushte commit |
| issue | circle-dot | Issue geopend / open |
| issue_closed | circle-check | Issue gesloten |
| check | circle-check | CI geslaagd / succes |

#### Aanbevolen kleurmapping (GitHub)

| Event | status.label | status.color | status.icon |
| --- | --- | --- | --- |
| PR geopend | Open | green | pull_request |
| PR draft | Draft | gray | pull_request |
| PR gemerged | Merged | purple | merged |
| PR gesloten zonder merge | Closed | red | pull_request_closed |
| Issue geopend | Open | green | issue |
| Issue gesloten | Closed | purple | issue_closed |
| Commit gepusht | Commit | gray | commit |
| CI geslaagd | Passing | green | check |
| CI gefaald | Failing | red | geen |

### Loader-status

Wanneer loader op true staat, toont de kaart een spinner met optionele teksten: een placeholder in "AI denkt na…"-stijl terwijl de bot nog werkt. title en description mogen in deze staat volledig weggelaten worden (ze renderen nog wel als ze aanwezig zijn).

| Veld | Type | Beschrijving |
| --- | --- | --- |
| loader | boolean | true rendert het spinnerblok in plaats van de beschrijving |
| loader_text | string | Primaire regel naast de spinner, bijv. "Thinking…" |
| loader_sub_text | string | Kleinere, gedimde tweede regel, bijv. "Searching your documents" |

```json
{
  "message_container": {
    "type": "embed_message",
    "bot_name": "Assistant",
    "color": "blue",
    "loader": true,
    "loader_text": "Thinking…",
    "loader_sub_text": "Searching your documents"
  }
}
```

De bot wist de loader door een UPDATE_MESSAGE te sturen met een vervangen message_container zonder loader en mt de definitieve inhoud; de client rendert de kaart op zijn plek opnieuw.

### Thinking (inklapbare redenering)

Wanneer thinking een niet-lege string is, verschijnt onder de beschrijving een ingeklapte **Show thinking**-rij. Klikken klapt hem client-side uit. Zelfde markdown-ondersteuning als description . Typisch gebruik: de bot plaatst een loader-kaart en bewerkt die daarna tot het definitieve antwoord, met de redenering van het model achter de toggle.

```json
{
  "message_container": {
    "type": "embed_message",
    "bot_name": "Assistant",
    "color": "blue",
    "sub_title": "marius: how late is the standup?",
    "description": "Standup is at **09:30**.",
    "thinking": "Checked the channel history for the recurring invite…"
  }
}
```

marius: how late is the standup?

### Voorbeelden

```json
{
  "message_container": {
    "type": "embed_message",
    "bot_name": "Github Notifications",
    "badge": "acme/acme-core",
    "color": "gray",
    "title": "alex pushed to master",
    "title_url": "https://github.com/acme/acme-core/commit/1a2b3c4",
    "sub_title": "Fix reverse-geocode city resolution for outlying hamlets",
    "status": { "label": "Commit", "color": "gray", "icon": "commit" },
    "additions": 86,
    "deletions": 38,
    "files_changed": 2
  }
}
```

#### alex pushed to master

Fix reverse-geocode city resolution for outlying hamlets

```json
{
  "message_container": {
    "type": "embed_message",
    "bot_name": "CI",
    "badge": "acme/acme-core",
    "color": "green",
    "title": "Build passed on master",
    "status": { "label": "Passing", "color": "green", "icon": "check" }
  }
}
```

#### Build passed on master

## Interactieve action messages

Action messages bevatten klikbare knoppen die meerdere acties na elkaar uitvoeren. Ze verschijnen met een systeemverificatiebadge en ondersteunen conditionele uitvoering op basis van eerdere actieresultaten.

```json
{
  "type": "action_message",
  "message_container": {
    "type": "system_message",
    "color": "orange",
    "title": "Message Title",
    "description": "Message description"
  },
  "actions": [
    {
      "type": "button",
      "color": "green",
      "text": "Button Text",
      "triggers": [
        {
          "action": "ws:send",
          "payload": {
            "method": "SOME_METHOD",
            "data": "value"
          }
        }
      ]
    }
  ],
  "expire_in_seconds": 300,
  "id": "unique-message-id"
}
```

#### Message Title

### Verplichte velden

| Veld | Beschrijving |
| --- | --- |
| type | Moet "action_message" zijn |
| message_container | Berichtinhoud en stijl. Gebruik "system_message" voor de geverifieerde systeembadge |
| actions | Array met knopacties |
| channel_guid | Doelkanaal-identifier |
| server_guid | Doelserver-identifier |
| id | Unieke bericht-identifier |

### Optionele velden

| Veld | Beschrijving |
| --- | --- |
| expire_in_seconds | Afteltimer in seconden |
| cms | Aanmaaktijdstip (standaard de huidige tijd) |

## Bouw je embed

Bewerk de velden of de JSON payload. Beide blijven in sync. Zie het bericht renderen precies zoals in een kanaal. Dit is de echte webhook body; kopieer hem als het goed staat.

### Visuele stijl

#### Containerkleuren

- orange : amber waarschuwingsstijl

- green : succes / positieve actie

- red : fout / destructieve actie

- blue : informatie / neutraal

- purple : speciaal / premium

- yellow : opgelet / aandacht

#### Knopkleuren

- **Primair** ( green , blue , purple ): prominente actieknoppen

- **Secundair** ( red , orange , yellow ): secundaire of destructieve acties

## Triggersysteem

Knoppen voeren meerdere acties na elkaar uit via de triggers -array. Elke trigger draait op volgorde, met conditionele uitvoering op basis van het succes of falen van de vorige trigger.

### WebSocket-acties

```json
{
  "action": "ws:send",
  "payload": {
    "method": "YOUR_METHOD_NAME",
    "param1": "value1",
    "param2": "value2"
  }
}
```

### Berichtupdates

```json
{
  "action": "local:update_message",
  "message_container": {
    "color": "green",
    "title": "Updated Title",
    "description": "Updated description"
  },
  "actions": []
}
```

#### Beveiliging

Het bericht- type kan niet gewijzigd worden door een update. Dat voorkomt imitatie: een botkaart kan zichzelf nooit veranderen in een ander soort bericht.

Knoppen beheren bij een update:

- Stuur "actions": [] mee om alle knoppen te verwijderen na afronding

- Stuur "actions": [...] mee om knoppen te vervangen door nieuwe

- Laat het actions -veld weg om bestaande knoppen te behouden

### Bericht verwijderen

```json
{
  "action": "local:remove_message"
}
```

### Conditionele uitvoering

Triggers kunnen conditioneel draaien op basis van het resultaat van de vorige trigger:

| Conditie | Gedrag |
| --- | --- |
| *geen* | Draait altijd |
| "previous:success" | Alleen als de vorige trigger slaagde |
| "previous:failed" | Alleen als de vorige trigger faalde |
| "failed" | Alleen als de vorige trigger faalde |

```json
{
  "type": "button",
  "text": "Process Request",
  "color": "green",
  "triggers": [
    {
      "action": "ws:send",
      "payload": {
        "method": "PROCESS_DATA",
        "request_id": "12345"
      }
    },
    {
      "condition": "previous:success",
      "action": "local:update_message",
      "message_container": {
        "color": "green",
        "title": "Processing Complete",
        "description": "Your request was processed successfully"
      }
    },
    {
      "condition": "previous:failed",
      "action": "local:update_message",
      "message_container": {
        "color": "red",
        "title": "Processing Failed",
        "description": "There was an error processing your request"
      }
    }
  ]
}
```

### Verlooptimers

Berichten kunnen een afteltimer bevatten via expire_in_seconds . De client formatteert de resterende tijd automatisch:

- Onder 60 seconden: "45 seconds"

- Onder 60 minuten: "5 minutes 30 seconds"

- Boven 60 minuten: "1 hour 15 minutes"

- Verlopen: "This message has expired"; met verlopen berichten kan niet meer worden geklikt

## Live updates

Beide berichttypes worden op hun plek bijgewerkt. Het gebruikelijke patroon voor AI-achtige bots:

#### Plaats een loader-kaart

Stuur een embed_message met loader: true en een korte loader_text .

#### Doe het werk

Je bot verwerkt het verzoek terwijl de spinner zichtbaar is.

#### Vervang de container

Stuur UPDATE_MESSAGE met de definitieve message_container : laat loader weg, voeg het antwoord toe en stop de redenering desgewenst achter thinking .

### Zie het gebeuren

De hele loop op n plek: een commando vuurt je webhook af, je reply wordt een kaart, een knop-tik komt bij jou terug en je callback-update landt op zijn plek.

##### Een commando vuurt je webhook af

Iemand typt /deploy. mssgs POST het bericht naar je endpoint, inclusief een callback_url voor dit bericht.

##### Je reply wordt een kaart

Antwoord met JSON en de kaart verschijnt in het kanaal: titel, beschrijving, status en knoppen.

##### Een knop-tik komt bij jou terug

De tik vuurt de trigger opnieuw naar je server, met een verse callback_url.

##### Je werkt de kaart op zijn plek bij

Eerst een loader terwijl jij het werk doet, daarna de eindstatus. Iedereen in het kanaal ziet de update live.

#### Deploy v2.1.0 to production?

#### Deploy complete

## Best practices

#### Duidelijke knoptekst

Geef knoppen een beschrijvende text om verwarring te voorkomen.

#### Vang fouten af

Neem faalcondities op in triggerketens voor betere UX.

#### Redelijke timeouts

Gebruik passende expire_in_seconds -waarden voor tijdgevoelige acties.

#### Visuele hirarchie

Gebruik kleuren consistent: groen voor positief, rood voor negatief.

#### Knoppenbeheer

Verwijder knoppen met "actions": [] na afronding, of vervang ze zodat ze passen bij elke workflowstaat.

## Fouten & limieten

### Foutafhandeling

- Gefaalde triggers stoppen de keten, tenzij een faalconditie matcht

- WebSocket-fouten worden gelogd en behandeld als falen

- Mislukte berichtupdates worden gelogd en behandeld als falen

- Triggers met faalcondities ( previous:failed , failed ) draaien juist bij fouten

### Limieten

- Aanbevolen maximum aantal triggers per knop: 10

- Berichtupdates kunnen het veld message_container.type niet wijzigen

- WebSocket-payloadlimieten gelden ook voor trigger-payloads

- Met verlopen berichten kan niet meer worden geklikt

## Vragen?

We helpen je graag met je bot.
