RawtohRawtoh/Docs
Documentation

Discord Module

A Rawtoh bot in your Discord server — messages, reactions, roles, DMs and slash commands.

The Discord module adds the Rawtoh bot to your server. Everything that happens there — messages, reactions, members joining, slash commands — comes in as events, and your actions can post, react, hand out roles or answer a command.

Getting started

  1. Open the Discord module site and sign in with your Rawtoh account — same session as the dashboard
  2. Pick your organization and click Add to a Discord server. Discord asks which server to add the bot to; you need Manage Server there
  3. Back on the module site, click Install with Rawtoh. The server becomes a module instance in your organization. You need the owner role

Each server is its own instance, so a community server and a mod-team server can run side by side and be targeted with module("discord", "<instance>"). A server belongs to one organization at a time.

Channel, role, user and message IDs are Discord snowflakes. To copy one, enable Developer Mode in Discord (Settings → Advanced), then right-click a channel, role or user and choose Copy ID. channel.list and role.list return them too.

Events

EventDescription
message.createA message is posted in the server (the bot's own messages excluded). Payload: id, channel_id, author, content, timestamp, reply_to
message.deleteA message is deleted
reaction.addSomeone reacts to a message. emoji is the character, or name:id for a custom emoji
member.joinA member joins the server
member.leaveA member leaves or is removed
command.invokeA member uses one of the server's slash commands. Payload: name, options, user, channel_id, token

Events carry the whole server. To react in one channel only, filter on channel_id in the trigger:

import { event } from "rawtoh"

export default event.payload.channel_id === "123456789012345678"
  && event.payload.content.startsWith("!clip")

What you can do

Messages

Members and roles

Slash commands

Slash commands, step by step

Commands are declared once per server, on the module site under Commands, or from an action:

import { module } from "rawtoh"

await module("discord").request("command.create", {
  name: "stats",
  description: "Today's stream stats",
  options: [{ type: 3, name: "period", description: "day or week", required: false }],
})

When a member types /stats, Discord shows "Rawtoh is thinking…" and the module emits command.invoke. A trigger picks the command by name:

import { event } from "rawtoh"

export default event.payload.name === "stats"

and the action answers with command.reply, which replaces the "thinking…" placeholder. You have 15 minutes; after that Discord shows "did not respond". message.send would post a separate message and leave the placeholder hanging.

import { event, module, storage } from "rawtoh"

const subs = (await storage.get("subs-today")) ?? 0
await module("discord").request("command.reply", {
  token: event.payload.token,
  content: `${subs} new subs today, asked by ${event.payload.user.username}`,
})

Example: welcome new members

A trigger on member.join and this action:

import { event, module } from "rawtoh"

await module("discord").request("message.send", {
  channel_id: "123456789012345678",
  content: `Welcome <@${event.payload.user.id}>! Grab a role in #roles.`,
})
await module("discord").request("member.add_role", {
  user_id: event.payload.user.id,
  role_id: "987654321098765432",
})

Example automations