Dave is a chat bot. It runs on Discord and Uproar (uproar.chat) at the same time; the Uproar side is optional and stays off until you configure it (see Uproar below).
dave-commands-720p.mp4
The operator-hosted Discord bots' data practices and privacy contact are described in the Dave and Sluglicious privacy policy.
Use $privacy to open buttons for the policy, status, opt-out/opt-in and deletion
requests. $privacy optout stops processing your messages; $privacy optin resumes (substitute the bot's
configured prefix). You can also mention the bot followed by privacy optout
or privacy optin. No holder role is required. The preference persists for that
bot across restarts; set it separately on each bot. $privacy delete opens a
confirmation to request deletion and opt out. $privacy status shows the saved
request reference and status. Submitting a request is not immediate erasure.
The configured operator (config.god) sees a Review deletion requests button
in their privacy panel. The queue and review responses are ephemeral and
operator-only. Review applicable bot records, saved features, worker/media files,
logs, backups and provider-side records before marking a request completed; the
completion button records the outcome and does not delete data itself.
Routine usage logs no longer save command arguments. Startup removes existing argument values from the active bot database while preserving command counts and metadata. Saved quotes, reminders and other intentional feature data retain their existing behavior; this is not a universal 30-day retention policy.
If Discord rejects Message Content access at login, the bot reconnects without that intent so mention-based privacy controls remain available. Ordinary prefix commands and automatic features are limited until access is restored. Restart the bot after restoring the intent to enable full functionality again.
- yarn
- node
-
Go here to make a bot.
-
Give your bot a name, and then click
Create Application. -
Scroll down to
Create a Bot Userand click that. -
Note down the
Client IDfor later. -
Now you can get your bot token by clicking
click to revealin the bot user section. -
Copy the file
src/Config.ts.exampletosrc/Config.ts(cp src/Config.ts.example src/Config.ts) -
Enter your token in
Config.ts. -
Don't reveal this token to anyone!
-
Next you need to get the Channel ID you want the bot to run in.
-
In Discord, follow these steps-
-
Click on
User Settings(small gear icon to right of name in the bottom left) -
Click on
Appearance -
Enable
Developer Mode.
-
-
Edit this link, replacing the string of numbers after
client_id=with the Client ID you noted down earlier.https://discord.com/oauth2/authorize?client_id=446154284514541579&scope=bot&permissions=268437568 -
Open said link and choose the server you wish to add the bot to. You must have
Manage Serverpermissions.
Copy lib/Config.ts.example to lib/Config.ts and fill in the relevant fields.
You can disable functions in lib/CommandDefinitions.ts if you can't be bothered to get the API keys and don't want errors.
- Cat API: https://thecatapi.com/signup
- Exchange rates: https://docs.openexchangerates.org/docs/authentication
- Youtube API: https://developers.google.com/youtube/v3/docs
- Weather API: https://openweathermap.org/price
The optional watcher polls the Codex Resets public API
every 60 seconds. It announces explicit scheduled resets and separately reports executed
resets, including banked credits. Forecasts and elapsed ETAs never count as execution.
Both alert types ping the @codex role (1560349689025532064) and link back to
Codex Resets and the source post. All other mentions are disabled.
Create ~/.config/dave-codex-resets.json (or set CODEX_RESET_WATCH_CONFIG_FILE):
{
"botUserId": "446154284514541579",
"channelId": "746507379310461010"
}Only the selected bot runs the watcher, preventing duplicate alerts across the two
deployment tracks. It needs View Channel, Send Messages, and Embed Links permissions.
The @codex role must be mentionable, or the bot must have Mention Everyone permission.
Restart the bots after configuring it. No API key is required.
The adjacent .state.json file stores seen events and a persistent delivery queue.
Keep it across restarts. First startup silently baselines executed history but announces
any currently scheduled reset. Later polls page through history to catch resets missed
during downtime and retry failed deliveries. Missing configuration disables the watcher;
invalid state fails closed. Use a new config/state path when changing the destination.
The public tracker remains the fallback source. An optional local account monitor can
detect resets before the tracker confirms them, without moving Codex credentials to
the bot server.
scripts/codex-usage-watch.mjs reads the signed-in local CLI's
account/rateLimits/read
once per invocation. It starts no model turns and never redeems reset credits.
Two samples at least 30 seconds apart must confirm either an early usage drop or an
increase in available reset credits. Usage must drop by at least five percentage
points to at most 5%, before its normal reset time. The confirmation may include
new usage as long as it stays below the pre-reset usage.
Normal rollovers, account/plan/window changes, polling gaps over five minutes, unknown credit inventories, and observed personal credit redemptions do not trigger usage-reset alerts. Complete, unchanged credit IDs also allow detection on accounts with banked credits. Grants can be account-specific; all direct alerts explicitly say they were observed on the monitored account, not verified globally. Very small usage drops, resets while the desktop is offline, or resets without comparable account data may be missed; the public tracker still works independently.
The monitor keeps its baseline, pending confirmation, and seven days of observations
in ~/.local/state/dave-codex-usage.json (mode 0600). It forwards only confirmed
observations over SSH to dave:~/.config/dave-codex-resets.json.usage.json, using an
atomic replacement. Credentials, account IDs, credit IDs, and usage percentages are
never forwarded. Delivery failures retry from saved observations on the next run.
The bot reads this feed independently of public tracker availability. Same-kind
events from the two sources within six hours of each other are treated as one reset
to avoid a second ping when the tracker catches up; this correlation is heuristic
because there is no shared event ID.
On the signed-in WSL desktop, build the project, verify batch SSH access to dave,
then install the supplied user timer:
yarn build
mkdir -p ~/.config/systemd/user
cp scripts/systemd/dave-codex-usage.{service,timer} ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now dave-codex-usage.timer
systemctl --user start dave-codex-usage.service
journalctl --user -u dave-codex-usage.service -n 10The timer polls every 60 seconds; confirmation plus the bot's own polling normally
adds about one to three minutes from a detectable account change. It runs only while
the desktop's WSL user services are available. The supplied unit assumes this clone
is at ~/Code/js/dave and Node is at /usr/bin/node. Override CODEX_USAGE_CODEX,
CODEX_USAGE_STATE_FILE, or CODEX_USAGE_REMOTE in a systemd drop-in if needed.
The receiver uses the default bot config path; custom bot config paths need a
matching receiver-path adjustment. Stop monitoring with
systemctl --user disable --now dave-codex-usage.timer. Preserve the local state
and bot state files across restarts to avoid losing baselines and deduplication.
Dave can run on Uproar alongside Discord. It stays Discord-only until you set both
uproarBotId and uproarBotToken in lib/Config.ts; leave them blank to disable it.
Dave connects to Uproar by dialing out over a WebSocket, the same way it connects to Discord's gateway, so there is nothing to host: no public URL, webhook, or open port.
To wire it up:
- Create a bot on Uproar: either an account-level agent (Settings > Bots > My Agents),
which you then admit into any server, or a server-owned bot (a server's
Settings > Bots). The bot's token is shown once, at creation, inside the returned URL
(
https://uproar.chat/api/bots/<id>/<token>). Copy it immediately; it is stored hashed and never shown again. If you lose it, regenerate a new one. - Add the bot to the server(s) and channel(s) you want it in. For an account-level agent,
share its handle (
bot.xxxxxxxx) and have a server admin admit it (Server Settings > Bots). Give the bot View Channel and Send Messages in those channels, plus Attach Files (for the image commands) and Add Reactions (for polls and paginated replies). - Fill in the Uproar fields in
lib/Config.ts:uproarBotId— the bot's id (the<id>in the URL above)uproarBotToken— the execute token (the<token>shown once)uproarBaseUrl— defaults tohttps://uproar.chat; only change it if you self-host Uproar
- Build and start as usual (below). Commands work exactly as on Discord, with the same
prefix.
yarn install
yarn build
yarn start