API: Chat

This page outlines details pertaining to the Roll20 API in regards to chat functions.


Chat Events

chat:message

Triggered whenever a new chat message is received. Note that if the message is of type "rollresult" or "gmrollresult", you will need to call JSON.parse() on the content of the message to get an object which contains information on the roll results.

Note: If a player enters a chat message beginning with an exclamation mark (!), that message will have the type of "api" and not be shown to anyone. It's intended that this functionality can be used to provide commands that Mod (API) scripts respond to. So, if the message is of type "api", then it hasn't been shown to anyone, and the player who sent the chat message is probably expecting an Mod (API) script to do something as a result of the message.

Callback parameter:

Property Default Value Notes
who "" The display name of the player or character that sent the message.
playerid   The ID of the player that sent the message.
type "general" One of "general", "rollresult", "gmrollresult", "emote", "whisper", "desc", or "api".
content "" The contents of the chat message. If type is "rollresult", this will be a JSON string of data about the roll.
origRoll   (type "rollresult" or "gmrollresult" only) The original text of the roll, eg: "2d10+5 fire damage" when the player types "/r 2d10+5 fire damage". This is equivalent to the use of content on messages with types other than "rollresult" or "gmrollresult".
inlinerolls   (content contains one or more inline rolls only) An array of objects containing information about all inline rolls in the message.
rolltemplate   (content contains one or more roll templates only) The name of the template specified.
target   (type "whisper" only) The player ID of the person the whisper is sent to. If the whisper was sent to the GM without using his or her display name (ie, "/w gm text" instead of "/w Riley text" when Riley is the GM), or if the whisper was sent to a character without any controlling players, the value will be "gm".
target_name   (type "whisper" only) The display name of the player or character the whisper was sent to.
selected   (type "api" only) An array of objects the user had selected when the command was entered.

Note: You probably don't need all of this information. In most cases you'll only be interested in the overall result of the roll (see the bottom of the first example). However all of it is provided if you want to really dig deeper into the results of a roll.

 


Roll Result Structure Ex. 1

After you call JSON.parse on the content property of a "rollresult" or "gmrollresult" message, you'll get an object with the following format (this is the result from the command /roll {2d6}+5+1t[weather] Attack!)

{
  "type":"V", //"V" = "Validated Roll" (this will always be "V" right now)
  "rolls": [
    {
      "type":"G", //"G" indicates a grouped roll. A group is like a series of "sub-rolls" within a roll.
      "rolls": [
        [
          {
            "type":"R", //"R" = "Roll"
            "dice":2, // Number of dice rolled (2dX means 2 dice)
            "sides":6, //Number of sides for the dice (Xd6 means 6 sides)
            "mods":{},
            "results": [ //An array of the results of each roll.
             {
               "v":1 // We rolled a 1 for our first 2d6
             },
             {
               "v":5 //We rolled a 5 for our second 2d6
             }
            ]
          }
        ]
      ],
      "mods":{},
      "resultType":"sum", //The result is a sum (as opposed to a success check)
      "results": [
        {
          "v":6 // In this case, the overall result (total) of the group.
        }
      ]
    },
    {
      "type":"M", //"M" = Math Expression
      "expr":"+5+"
    },
    {
      "type":"R", //"R" = Roll
      "dice":1,
      "table":"weather", //The table property is set to the name of the table used if this roll was made against a table
      "mods":{},
      "sides":2, //You can probably just ignore this for table rolls.
      "results": [
        {
          "v":0, //The "value" of the table item rolled. For text tables this is always 0.
          "tableidx":1, //The index of the item in the table that was rolled.
          "tableItem": { //A copy of the table item object as it existed when the table was rolled.
            "name":"rainy", 
            "avatar":"", //This will be a URL to an image if the rollable table uses image icons
            "weight":1,
            "id":"-IpzPx2j_9piP09ceyOv"
          }
        }
      ]
    },
    {
      "type":"C", // "C" = Comment
      "text":" Attack!"
    }
  ],
  "resultType":"sum", //The overall result type of the entire roll
  "total":11 // The overall total of the entire roll (including all sub-groups)
}

Roll Result Structure Ex. 2

An annotated structure for the result of /roll {1d6!!>5}>6 (showing exploding modifications and target successes):

{
  "type":"V",
  "rolls": [
    {
      "type":"G",
      "rolls": [
        [
          {
            "type":"R",
            "dice":1,
            "sides":6,
            "mods": { //Modifications to the roll
              "compounding": { //"compounding" = "Compounding exploding (!!)"
                "comp":">=", //Comparison type
                "point":5 //Comparison point
              }
            },
            "results": [
              {
                "v":13 //Overall dice result. Note that since this is compounding exploding there is only one dice result.
              }
            ]
          }
        ]
      ],
      "mods": {
        "success": {
          "comp":">=",
          "point":6
        }
      },
      "resultType":"sum",
      "results": [
        {
          "v":13
        }
      ]
    }
  ],
  "resultType":"success", // In this case, the result is a count of successes
  "total":1 //Total number of successes
}

Chat Event Example (Implementing Custom Roll Type)

on("chat:message", function(msg) {
  //This allows players to enter !sr <number> to roll a number of d6 dice with a target of 4.
  if(msg.type == "api" && msg.content.indexOf("!sr ") !== -1) {
    var numdice = msg.content.replace("!sr ", "");
    sendChat(msg.who, "/roll " + numdice + "d6>4");
  }
});

sendChat(speakingAs, input [,callback [, options]] )

You can use this function to send a chat message.

speakingAs can be one of:

  • Any string, in which case that will be used as the name of the person who sent the message. E.g. "Riley"
  • A player's ID, formatted as "player|-Abc123" where "-Abc123" is the ID of the player. If you do this it will automatically use the avatar and name of the player.
  • A character's ID, formatted as "character|-Abc123". If you do this it will automatically use the avatar and name of the Character.


input should be any valid expression just like the ones used in the Roll20 App. You enter text to send a basic message, or use slash-commands such as "/roll", "/em", "/w", etc. In addition:

  • You can use Character Attributes with the format @{CharacterName|AttributeName}.
  • You can use Character Abilities with the format: %{CharacterName|AbilityName}.
  • You cannot use macros.
  • You can use the "/direct <msg>" command to send a message without any processing (e.g. autolinking of URLs), and you can use the following HTML tags in the message:

 

<code><span><div><label><a><br><br /><p><b><i><del><strike><u><img>
<blockquote><mark><cite><small><ul><ol><li><hr><dl><dt><dd><sup>
<sub><big><pre><figure><figcaption><strong><em><table><tr><td><th>
<tbody><thead><tfoot><h1><h2><h3><h4><h5><h6>

callback is an optional third parameter consisting of a callback function which will be passed the results of the sendChat() call instead of sending the commands to the game. Using sendChat() in this way is asynchronous. The results of the sendChat() command will be an ARRAY of operations, and each individual object will be just like an object you receive during a chat:message event (see above).

You can use this, for example, to perform a roll using the Roll20 roll engine, then get the results of the roll immediately. You could then perform additional modifications to the roll before sending it to the players in the game.

sendChat("Riley", "/roll 1d20+4", function(ops) {
    // ops will be an ARRAY of command results.
    var rollresult = ops[0];
    //Now do something with rollresult, just like you would during a chat:message event...
});

options is an optional fourth parameter to set options for how the message is handled. Options are specified as a javascript object with who's properties are the names of the options to set and whose values are the settings for them, generally true as they default to false.

Available options:

  • noarchive -- set this to true to prevent the message from being stored in the chat log. This is particularly useful for output that is not part of the story, such as Mod (API) Button menus and state information.
  • use3d -- You can now generate 3D Dice rolls using the sendChat() function. The syntax is simply: sendChat("Name", "Rolling [[3d6]]", null, {use3d: true}); If you pass a player ID to the name parameter, such as sendChat("player|-ABC123",...) the player's color will be used for the dice. Otherwise a default white color will be used. 

    Note: Clients can only show the result of one 3D roll at a time, so making a bunch of separate 3D rolls in a row is not useful. Also note that using 3D rolls does place a bit more strain on the QuantumRoll server, so use your judgement and don't perform 100 3D rolls in the space of a second. Use 3D rolls when the roll will "matter" to the player and make an impact on the game.

    If you want to adjust these options but do not want to use a callback parameter (third parameter--see above), you can simply pass null in it's place:

 

sendChat("Status", "All players are logged in.", null, {noarchive:true} );

Mod (API) Command Buttons

Now available with the Update of Holding you can take advantage of the new text chat formatting (in both your API-generated messages and those generated by macros and abilities) to create "Mod (API) command buttons" in the chat.

To do so using Markdown formatting:

[Attack Roll](!attackroll)

The text in between the brackets will show up in the button, and part in the parentheses is the command to be executed. You can include anything in a normal roll (macros, abilities, queries, etc.), but keep in mind that the command itself will be executed by the player who clicks on it. For example, don't include @{Character|AC} if everyone who can see the message can't access that character. Instead, include the actual value as it existed when you sent the command by filling it in yourself before you send the chat message. These buttons will work in all message types, general messages, whispers, gmwhispers, etc.

Note that if you use /direct to send a message, we won't do any Markdown parsing on it, so you need to include your own <a> tags. Here's an example of that:

<a href="!attackroll">Attack Roll</a>

Entering Mod (API) Buttons In Chat

You can also type Markdown syntax Mod (API) buttons into chat for others to use. Because they will be interpreted by the chat parser, if you want attributes, queries and rolls to be expanded when the button is clicked, you must enter parts of the command with a special syntax (HTML Entities):

Character Replacement
 % &#37;
) &#41;
 ? &#63;
@ &#64;
[ &#91; or &lbrack;
] &#93; or &rbrack;

This sample button uses some of them:

[Attack Roll](!attackroll &#64;{target|token_id} &#91;[1d6+&#63;{Bonus|0}]&#93;)

You can actually use the Mod (API) Buttons to call Macros or Abilities.

Character Replacement
<carriage return> &#13;

To do so, you simply begin the command portion with the special code !&#13; then add the macro call with # or the ability call with &#37; (%):

[Macro](!&#13;#MacroName)

[Ability](!&#13;&#37;{CharName|AbilityName})

Note: At this time, reopening a Macro saved under the Collections tab of the Sidebar causes HTML entities within to be reverted; if the Macro is then saved, so are those reversions. This behavior is not present within Abilities or Ability Command Buttons.

For Ability Command Buttons, if the Ability that creates the button and the Ability it references are both on the same sheet, the syntax is very simple:

[Ability](~AbilityName)

Was this article helpful?
14 out of 21 found this helpful