Rawtoh Rawtoh / Docs

Create Your Own Module

Build a custom module to connect any tool or service to Rawtoh.

A module is any program that connects to Rawtoh via WebSocket. It can emit events (things that happen) and receive action calls (things to do). If you can write a script that opens a WebSocket, you can build a module.

How a module works

Your module connects to Rawtoh's WebSocket server and communicates using JSON-RPC 2.0. The flow is simple:

  1. Connect — open a WebSocket to the Rawtoh RPC server
  2. Register — send your API key to authenticate
  3. Subscribe — the server tells your module which events it should emit
  4. Emit events — send data to Rawtoh when something happens
  5. Receive calls — Rawtoh calls your module when an action needs something done

Step 1: Get an API key

Before your module can connect, you need to register it in Rawtoh:

  1. Go to Settings → Module Definitions and create a new definition (or use an existing one)
  2. Go to Settings → Modules and create a new instance
  3. Copy the API key — it's shown only once

Step 2: Connect and register

Open a WebSocket connection to the Rawtoh RPC server. Within 5 seconds, send a registration request:

// → Send to server
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "session.register",
  "params": { "token": "rth_your_api_key_here" }
}

// ← Server responds
{ "jsonrpc": "2.0", "id": 1, "result": true }

If the key is invalid, the server returns an error and closes the connection. If you don't register within 5 seconds, the connection is also closed.

Step 3: Handle subscribe calls

Right after registration, the server tells your module which events it needs. For each event, it sends a request like this:

// ← Server asks your module to subscribe to an event
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "event.subscribe",
  "params": ["chat.message"]
}

// → Your module responds with a subscription ID (any unique string)
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": "sub_abc123"
}

Rules:

Step 4: Emit events

When something happens (a chat message, a button click, a sensor reading — anything), send a notification to the server. Notifications have no id field — they're fire-and-forget.

// → Send to server (notification — no "id" field)
{
  "jsonrpc": "2.0",
  "method": "event.subscription",
  "params": {
    "subscription": "sub_abc123",
    "result": {
      "user": "alice",
      "message": "hello world"
    }
  }
}

Events are rate limited to 10 per second per connection. If you exceed this, the event is dropped.

Step 5: Expose methods (optional)

If you want actions to be able to call your module (e.g. module("my-tool").request("do.something", params)), your module needs to handle incoming JSON-RPC requests:

// ← Server sends a request to your module
{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "lights.set_color",
  "params": { "color": "#ff0000" }
}

// → Your module responds
{
  "jsonrpc": "2.0",
  "id": 42,
  "result": { "status": "ok" }
}

You define the method names and params — it's your API. Users will be able to call them from action scripts.

Required methods

Your module must handle these 3 methods from the server:

Method What you return Purpose
ping"pong"Heartbeat check
event.subscribesubscription ID or nullStart emitting an event
event.unsubscribetrueStop emitting an event

The manifest

To make your module's events and methods appear in Rawtoh's script editor (autocomplete, documentation), you can provide a manifest — a JSON document that describes what your module can do. Set it on the module definition in Settings → Module Definitions.

{
  "events": [
    {
      "name": "sensor.temperature",
      "summary": "Temperature reading from sensor"
    }
  ],
  "methods": [
    {
      "name": "lights.set_color",
      "summary": "Set the light color",
      "params": [
        { "name": "color", "schema": { "type": "string" } }
      ]
    }
  ]
}

The manifest is optional — your module will work without it. But it makes the experience much better for anyone writing automations.

Reconnection

Your module should reconnect automatically when the connection drops. But check the close code first:

Close code What to do
4000Don't reconnect. The user disconnected the module on purpose.
4001Don't reconnect. The API key was refreshed — the current one is invalid.
Anything elseReconnect with exponential backoff: 1s → 2s → 4s → 8s → … up to 64s. Reset on successful registration.

After reconnecting, the server starts a fresh subscribe phase. Discard any old subscription IDs.

Naming convention

All event and method names use dot notation:

Summary

To build a module, your program needs to:

  1. Open a WebSocket to the Rawtoh RPC server
  2. Call session.register within 5 seconds
  3. Handle ping, event.subscribe, and event.unsubscribe
  4. Emit events via event.subscription notifications
  5. Optionally handle custom method calls from actions
  6. Reconnect on disconnect (respecting close codes)

That's it. Your module can be written in any language — JavaScript, Python, Rust, Go — anything that supports WebSocket and JSON.