Skip to main content
Developers Slash commands

Add slash commands

Give your community its own /commands. When a member types one, mssgs sends the message to your web service and posts what it answers: a card, buttons, a reply only they can see.

What you can do

  • Answer with a cardReply with JSON and it appears in the channel as a card.
  • Know who askedYou get the member and their roles, so you can check who may do what.
  • Reply privatelyShow the answer only to the member who asked.
  • Take your timeAnswer with a loader in 5 seconds, then finish through the callback URL.

In the app

Type / and the community's commands appear

Your service answers, mssgs posts the card

The picker and the card are the app's own. The footer says who used which command.

Quick start

  1. Create the trigger

    In the desktop app, open your community's Manage Server → Triggers and add one: the command it reacts to, such as /weather, and the URL of your web service.

  2. Receive the message

    When a member sends a message that starts with /weather, mssgs POSTs it to your URL:

    json
    {
      "server_guid": "abc12345-...",
      "channel_guid": "def67890-...",
      "trigger_match": "/weather",
      "message": {
        "id": "d01ZZdef6-...",
        "content": "/weather Amsterdam",
        "member_guid": "member-guid",
        "user_guid": "user-guid",
        "group_guids": ["group-guid-1", "group-guid-2"],
        "cms": 1790000000000
      },
      "callback_url": "https://mss.gs/api/v1/trigger-callback/...",
      "stream_url": "https://mss.gs/api/v1/instant/...?token=..."
    }
  3. Answer with JSON

    Answer within 5 seconds with a 2xx status and JSON. It becomes a card in the channel.

    json
    {
      "message_container": {
        "color": "blue",
        "title": "Amsterdam",
        "description": "14 °C, light rain until 16:00",
        "fields": [
          { "field": "Wind", "value": "SW 18 km/h" },
          { "field": "Humidity", "value": "82%" }
        ]
      }
    }
    general
    maya18:45
    /weather Amsterdam
    System
    Message from Weekend Crew

    Amsterdam

    14 °C, light rain until 16:00
    Wind
    SW 18 km/h
    Humidity
    82%

Settings

Each trigger has these settings in Manage Server → Triggers.

SettingWhat it does
Trigger NameWhat the trigger is called, shown next to the command in the picker.
Word to MatchThe text a message has to start with, such as /weather. A slash is usual, not required.
URL EndpointWhere mssgs sends the message.
Webhook SecretOptional. mssgs signs every request with it, see below.
ActiveSwitch the trigger off without deleting it.
Post Matching MessageWhether the member's own /weather Amsterdam stays in the channel above your answer.
Show Loading ReplyShow a loading card while your service works.
Allowed User GroupsOnly members of these roles fire it. For anyone else it is an ordinary message.
Matching is on the start of the message. Avoid commands that begin with each other, like /deploy and /deploy-prod: which one fires is not fixed. Messages from bots and forwarded messages never fire a trigger.

What you receive

A POST with a JSON body. The headers include User-Agent: mssgs-webhook/1.0.

FieldTypeWhat it is
server_guidstringThe community.
channel_guidstringThe channel the message was sent in.
trigger_matchstringThe command that matched, such as /weather.
message.contentstringThe whole message, command included.
message.member_guidstringThe member who sent it, in this community.
message.user_guidstringThe same person's account, the same in every community.
message.group_guidsarrayThe roles the member has.
message.cmsnumberWhen it was sent, in milliseconds.
message.is_action_buttonbooleantrue when a button fired the trigger, not a typed command.
message.action_payloadobjectThe button's payload, for button presses.
callback_urlstringUpdate or delete your answer later, for 30 minutes.
stream_urlstringA live stream of replies, reactions and button presses on your answer, for 10 minutes.
With a secret set, the request carries X-Mssgs-Signature: sha256=<hex>: an HMAC-SHA256 of the raw body with your secret. Compute it yourself and compare before you trust the request.

Checking who may do what

Compare message.group_guids with the roles you trust, for example to let only moderators run /ban. To keep a command away from everyone else entirely, set its roles in the trigger's settings.

What you answer

Any 2xx status with a JSON body, up to 4 MB. Send at least one of message_container or actions.

FieldTypeWhat it is
message_containerobjectThe card. Every field on message cards works here, including the status pill, badge, diff stats and folded reasoning.
title, description, color, ...stringShorthand: card fields at the top level are wrapped into a card for you.
actionsarrayButtons under the card. See buttons.
visible_to_member_guidsarrayOnly these members see the answer. See private replies.
The card's header shows your community's name, and its footer says who used the command: "maya triggered /weather command". The avatar is the member's.
Always answer with a card: the content line is not shown on a command reply's card, so put what matters in the card itself.

Five seconds

mssgs waits 5 seconds for your answer. If you need longer, answer straight away with a loader card and finish through callback_url, which stays valid for 30 minutes.

javascript
// Answer within 5 seconds with a loader...
res.json({ message_container: { loader: true, loader_text: 'Looking it up…' } });

// ...then finish in your own time with the callback URL.
await fetch(req.body.callback_url, {
  method: 'PUT',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ message_container: { color: 'blue', title: 'Done', description: result } })
});
If your service does not answer in time, or answers with an error, the member who used the command sees a red "Failed" card. Nobody else does.

Private replies

Put member ids in visible_to_member_guids and only they see your answer. Use the member_guid from the request to answer only the person who asked.

json
{
  "message_container": {
    "color": "green",
    "title": "You're on the list",
    "description": "Only you can see this reply."
  },
  "visible_to_member_guids": ["<message.member_guid from the request>"]
}

A full example

A /weather command in Node.js with Express, answering with a card.

javascript
import express from 'express';

const app = express();
app.use(express.json());

app.post('/mssgs/weather', async (req, res) => {
  const city = req.body.message.content.replace('/weather', '').trim() || 'Amsterdam';
  const w = await getWeather(city); // your own lookup

  res.json({
    message_container: {
      color: 'blue',
      title: city,
      description: `${w.temp} °C, ${w.summary}`,
      fields: [
        { field: 'Wind', value: w.wind },
        { field: 'Humidity', value: `${w.humidity}%` }
      ]
    }
  });
});

app.listen(3000);

Limits

LimitValue
Time to answer5 seconds
Answer size4 MB
Commands per member5 every 5 seconds
Updating the answer afterwards30 minutes, through callback_url
Live stream of the answer10 minutes, through stream_url

Keep building