Skip to content

Webhooks on the sheet

The sheet has no internet access. Its only way out is webhooks: the sheet sends data under a name (“rolls”), and the room’s game master decides where it goes, by pasting the address of a Zapier, Make or IFTTT webhook. That way the sheet never chooses the destination, and the address never shows up for players.

In the manifest:

"webhooks": [
{ "name": "rolls", "description": "Every roll from the sheet", "example": { "total": 17, "roll": "1d20+5" } }
]
  • name: lowercase letters, numbers, - and _. The sheet uses this name to send.
  • description: what the webhook sends, so the game master knows what they are connecting.
  • example (optional): a sample of the data, up to 4 KB.
  • Up to 20 webhooks per plugin.

When installing, RPG Desk shows the webhooks to the game master, who connects the addresses in Room settings → Plugins → Integrations. See Integrations.

const r = await RPGDesk.webhooks.send('rolls', { total: 17, roll: '1d20+5' });
if (!r.ok) RPGDesk.ui.toast(`The webhook did not go through: ${r.error}`, 'error');

The result is { ok, status, body, error }:

error When
null it worked; body is the service’s answer
'not-found' the manifest does not declare a webhook with that name
'not-configured' the game master has not connected an address to that webhook yet
'forbidden' the webhook is GMs only, and whoever triggered it is a player
'bad-request' the data is over 16 KB
'rate-limited' too many sends in a short time in the room
'timeout' the service did not answer within 10 seconds
'failed' the service answered with an error, or could not be reached

RPG Desk sends your data in data, along with the plugin, the webhook, the room, who triggered it and the time. The format is in Integrations.

<button id="attack">Attack</button>
<script>
document.getElementById('attack').addEventListener('click', async () => {
const r = await RPGDesk.dice.roll('1d20+5', { label: 'Attack' });
await RPGDesk.webhooks.send('rolls', { character: RPGDesk.doc.get('name'), total: r.total });
});
</script>

On the other side, a Zap with the Catch Hook trigger and an action that sends a message to a Discord channel, using data.character and data.total.