A Working Bot in One File
From an empty folder to a bot that answers, in one file that already reconnects and stops cleanly

Create the Bot, Keep Its Token Private
A Fluxer bot is an application with its own bot account. Create one from your account settings in the Fluxer app, then copy the bot token it shows, the secret the bot signs in with. Fluxer shows it only right after you create the application or regenerate the token
Anyone holding the token can act as the bot. It goes in a file named .env that version control ignores, never in the code
- User settings
- Developer
- Applications
- Create application
FLUXER_BOT_TOKEN=paste-the-token-here .envOne File That Answers
This is the whole bot. It reads its token from the environment, and runBot connects and calls the handler for each new message from a person. Install the SDK and invite the bot to a community where it can view the channel and send messages. Start it with the command under the code and send !ping. It answers Pong!
The same call runs large bots. It reconnects on its own, stops cleanly on Ctrl+C and explains a failed start with a suggested fix. Returning the reply hands its outcome to the SDK, so a failed send shows up in the log
import { runBot } from "@neontechspace/fluxerly"// A failure that stops the bot, such as a rejected token, is logged and sets a failing exit codeawait runBot({ token: process.env.FLUXER_BOT_TOKEN, events: { messageCreate: ({ message, reply }) => { if (message.content !== "!ping") return // Returning the reply reports a failed send to the log return reply("Pong!") }, },})node --env-file=.env bot.jsOr Generate It, Test Included
In a new folder, fluxerly init asks for JavaScript, TypeScript or the optional Effect API and writes the same bot, shaped so a test can import it, with its .env and .gitignore, and a first test. Then it installs the dependencies and prints the steps that remain
The test runs the bot against an in-memory Fluxer, so it needs no token and no network
npx @neontechspace/fluxerly init import assert from "node:assert/strict" import { test } from "node:test"import { createTestBot } from "@neontechspace/fluxerly/testing" import { bot } from "./bot.js" // createTestBot runs the bot against an in-memory Fluxer, so no token or network is neededtest("the bot answers !ping with Pong! and ignores other messages", async () => { await using testBot = createTestBot(bot) await testBot.ready() // The say method sends a message as a user and returns the messages the bot sent in response assert.deepEqual((await testBot.say("!ping")).map((message) => message.content), ["Pong!"]) assert.deepEqual(await testBot.say("hello"), []) })
Start and Stop, Already Handled
runBot checks every option before anything connects, registers the handlers, then connects. While it runs, it reconnects after a lost connection, and a handler that fails is logged while the bot keeps going
On Ctrl+C it stops taking new events, gives running handlers time to finish, closes the connection and waits for cleanup. Startup work and its timers can stop with the bot

import { runBot } from "@neontechspace/fluxerly"await runBot({ token: process.env.FLUXER_BOT_TOKEN, // On Ctrl+C or SIGTERM, running handlers get up to 10 seconds to finish drainMs: 10_000, // Runs before the bot connects. Its signal aborts once the bot begins stopping setup: (client, { signal }) => { const timer = setInterval(() => console.info("Still running"), 60_000) signal.addEventListener("abort", () => clearInterval(timer)) }, events: { messageCreate: ({ message, reply }) => { if (message.content !== "!ping") return return reply("Pong!") }, },})// The bot has stopped and the SDK has cleaned up. Close what the application opened here












