Greeting and private notes
Add !hello, or save one note per authenticated DM caller. Keep the bundled bot commands.
Add useful commands and monitoring to your node without reflashing. Download a module, retain your existing commands and settings, then make it your own.
Download commands from the library
Follow a tutorial: write, install and message a command
Install your Lua file over LoRa · Management admin commands over RF
Add !hello, or save one note per authenticated DM caller. Keep the bundled bot commands.
Read SNR average/P95 and RSSI from nearby repeater hops with !snr and !rssi.
Poll configured repeater identities from Aspen and collect their status and battery voltage.
Get the monitorEach ZIP includes requirements and named-source installation commands. Export a module before replacing it; an existing packet sampler has its own slot and settings. Browse the command library
Send commands to the bot in a private message. !help lists the commands you may use; !help remember shows arguments and an example. Your permissions and the node's settings decide which commands are available.
| Try | What it does | Needs |
|---|---|---|
!ping, !about, !help, !test | Check the connection, meet the bot and list commands. | Advertise your companion first, then send a private message. |
!calc, !convert, !roll, !choose | Calculate, convert units and make random choices. | Also works in channels the operator enables. |
!status, !signal, !air, !path, !trace | Show node status, signal, shared airtime and route. | Local reflections are labelled apart from RF receptions. |
!remember, !recall, !forget, !notes | Keep personal notes across restarts. | A private message keeps notes in your own space. |
!remind, !reminders, !cancel | Schedule and manage private reminders. | Owner grant and trusted time; delivery needs a fresh direct route. |
!board | Share notes in a channel. | A shared-storage grant and the channel's command/thread policy. Address the bot for channel operations. |
!weather, !service | Call an approved web service. | HTTPS configuration and a network grant on Aspen or a host. |
Aspen, Willow, the Go host worker and Pine run Lua 5.5.1. Use the command, scoped-storage and mesh APIs available on your node. A command is a function plus a declaration:
function hello(name)
return "Hello " .. name
end
command("hello", "name:string:32", "Greet a name",
"hello", "public", "!hello mesh")
The declaration gives the command name, typed arguments, help text, handler, permission and an example. The bot checks the arguments and builds the !help entry for you. A returned string becomes the reply.
Install the program as a named source on Aspen or Willow, then send !hello mesh and expect Hello mesh. The combined Lua source set holds up to 4,096 bytes. Named installation retains the other files and rejects conflicting exports.
Wrap a built-in: override_command(name, export) lets your handler replace a built-in command, and call_original(name[, argument_text]) runs the original with the same caller and permissions. Restoring the previous program leaves stored data in place. See replacing or wrapping a built-in.
The local runner keeps the test on your computer, using the real bot runtime, an in-memory radio and a test web service. From the source repository:
printf '!hello mesh\n' | make -s -C firmware/esp32 bot-local \
SOURCE=firmware/runtime/plugins/template.lua
Expected: the last JSON line contains "text":"Hello mesh". The first run builds the runner and fetches its pinned dependencies.
To check replies automatically, run a scenario; the runner exits nonzero when an assertion fails:
make -s -C firmware/esp32 bot-local \
SOURCE=firmware/runtime/plugins/template.lua \
SCENARIO=firmware/runtime/plugins/examples/hello.scenario.json
| Build with | API | Use it for |
|---|---|---|
| Commands and modules | command, program-local modules | Named handlers, typed arguments, help, aliases and cooperating functions. |
| Replies and messages | reply, mesh.compose/send/wait | Replies to the caller, messages to permitted destinations and waiting for results. The node handles keys and packet encoding. |
| Routes and forwarding | mesh.trace/multitrace/forward | Route diagnostics and permitted message forwarding, with attribution, expiry and loop checks. |
| State and events | kv, events.on, timer, reminder | Private or shared stored data, event handlers, timers and reminders. Jobs pause while waiting so other work can run. |
| Utilities and services | utility, json, node.report | Calculations, conversions, JSON and diagnostics. ESP32 HTTPS builds and the Go host add approved web requests. |
Programs run within instruction, time, memory and job limits. Pine has smaller limits; see operating Pine. The Lua API reference lists every function and the grants it needs. Willow uses the native Lua/Wasm worker or a smaller all-Hew bot; check its service guide for program management and available host controls.
An ESP32-S3 with PSRAM and the Linux x86-64 host worker can run one Wasm package alongside the Lua program, using the WAMR 2.4.1 interpreter. Both share the bot identity, permissions, stored data and radio queue.
meshcore_v1 interface covers commands, events, replies and waiting for node operations.--runtime wasm for status, readback, rollback or removal; lifecycle commands default to Lua.Run source api runtimes on the node to check that it includes Wasm before uploading a package.
ESP32 HTTPS builds and the Go host worker provide http.get, http.post and rpc.call to endpoints the operator approves. Credentials stay in the node's protected storage, out of reach of Lua and Wasm programs.
Start with the reference service, which provides health, echo and weather endpoints, or configure your own.