Bot Updates
Release rolling / release (push) Failing after 4m5s

This commit is contained in:
Raven Scott
2026-08-13 10:47:55 -04:00
parent 0fcca9021d
commit 9e4fcc4331
20 changed files with 559 additions and 22 deletions
@@ -5,7 +5,7 @@
"synopsis": [
"discord-bot [--env PATH] [--token TOKEN] [--guild ID] [--check] [--debug] [--message-content] [--login-timeout MS]"
],
"description": "Foreground Discord ping-pong bot using ctx.bare.discordJS (vendored bare-discord-js / official discord.js). Replies pong to the /ping slash command. Channel message ping/pong is opt-in: pass --message-content (or DISCORD_MESSAGE_CONTENT=1) and enable MESSAGE CONTENT INTENT in the Discord Developer Portal. Requesting that privileged intent without enabling it closes the gateway (4014) and used to hang after 'logging in'. Token comes from --token, guest DISCORD_TOKEN, a VFS .env file (--env, DISCORD_ENV_FILE, ~/.discord.env), or a host DISCORD_ENV_FILE / DISCORD_TOKEN copied into the session by the booter. Custom bots should use ctx.bare.discordJS.Client the same way (see examples/discord-ping-pong).",
"description": "Foreground Discord ping-pong bot using ctx.bare.discordJS (vendored bare-discord-js / official discord.js). Ctrl+C (or host SIGINT) stops the process. Replies pong to the /ping slash command. Channel message ping/pong is opt-in: pass --message-content (or DISCORD_MESSAGE_CONTENT=1) and enable MESSAGE CONTENT INTENT in the Discord Developer Portal. Token comes from --token, guest DISCORD_TOKEN, or a VFS .env file (--env, DISCORD_ENV_FILE, ~/.discord/.env, ~/.discord.env). The initd unit bare-os-discord is registered and listed by systemctl only when ~/.discord/.env exists with DISCORD_TOKEN=. Disable the unit with BARE_OS_DISCORD_INITD=0. Custom bots should use ctx.bare.discordJS.Client the same way (see examples/discord-ping-pong).",
"options": [
{
"flag": "--env PATH",
@@ -39,7 +39,8 @@
"keywords": ["discord", "bot", "ping", "pong", "ctx.bare"],
"environment": [
"DISCORD_TOKEN — bot token in the guest session (also copied from the host when set).",
"DISCORD_ENV_FILE / BARE_OS_DISCORD_ENV_FILE — path to a .env file. On the host this may be a host filesystem path (booter reads it). In the guest it is a VFS path.",
"DISCORD_ENV_FILE / BARE_OS_DISCORD_ENV_FILE — path to a .env file. On the host this may be a host filesystem path (booter reads it). In the guest it is a VFS path. Preferred guest path: ~/.discord/.env.",
"BARE_OS_DISCORD_INITD — set 0 / false to never register the bare-os-discord systemctl unit, even when ~/.discord/.env exists.",
"DISCORD_GUILD_ID — optional guild for slash-command registration.",
"DISCORD_MESSAGE_CONTENT / BARE_OS_DISCORD_MESSAGE_CONTENT — set 1 to request Message Content Intent (same as --message-content).",
"DISCORD_DEBUG / BARE_OS_DISCORD_DEBUG — set 1 to print discord.js debug lines.",
@@ -57,11 +58,11 @@
"examples": [
{
"caption": "check token resolution without connecting",
"code": "discord-bot --check --env ~/.discord.env"
"code": "discord-bot --check --env ~/.discord/.env"
},
{
"caption": "run the ping-pong bot",
"code": "discord-bot --env ~/.discord.env --guild 123456789012345678"
"code": "discord-bot --env ~/.discord/.env --guild 123456789012345678"
}
]
}
+71 -2
View File
@@ -110,6 +110,49 @@ function discordErrText(err) {
return (err && err.message) || String(err)
}
function discordAttachInterrupt(ctx, onStop) {
const proc = typeof globalThis.process !== 'undefined' ? globalThis.process : null
if (!proc || typeof proc.on !== 'function') {
return function () {}
}
let fired = false
function fire() {
if (fired) return
fired = true
ctx.exitCode = 130
try {
ctx.console.log('discord-bot: stopped (^C)')
} catch {
/* ignore */
}
try {
onStop()
} catch {
/* ignore */
}
}
proc.on('SIGINT', fire)
proc.on('SIGTERM', fire)
proc.on('bare-os:host-sigint', fire)
return function detach() {
try {
proc.off('SIGINT', fire)
} catch {
/* ignore */
}
try {
proc.off('SIGTERM', fire)
} catch {
/* ignore */
}
try {
proc.off('bare-os:host-sigint', fire)
} catch {
/* ignore */
}
}
}
function discordUsage(argv0) {
return (
'usage: ' +
@@ -118,7 +161,9 @@ function discordUsage(argv0) {
' [--debug] [--message-content] [--login-timeout MS]\n' +
'Ping-pong bot via ctx.bare.discordJS.\n' +
'Token from --token, DISCORD_TOKEN, or a .env file (--env, DISCORD_ENV_FILE,\n' +
'host DISCORD_ENV_FILE, ~/.discord.env).\n' +
'host DISCORD_ENV_FILE, ~/.discord/.env, ~/.discord.env).\n' +
'Ctrl+C stops the foreground bot. Initd unit bare-os-discord appears in\n' +
'systemctl only when ~/.discord/.env exists with DISCORD_TOKEN=.\n' +
'Replies pong to /ping. Message "ping" needs --message-content and the\n' +
'Message Content Intent in the Developer Portal (privileged).'
)
@@ -151,7 +196,13 @@ async function discordLoadToken(ctx, argv) {
if (ctx.env && ctx.env.BARE_OS_DISCORD_ENV_FILE) {
envPaths.push(ctx.env.BARE_OS_DISCORD_ENV_FILE)
}
envPaths.push('~/.discord.env', '~/discord.env', './.env', '~/.env')
envPaths.push(
'~/.discord/.env',
'~/.discord.env',
'~/discord.env',
'./.env',
'~/.env'
)
const seen = {}
for (let i = 0; i < envPaths.length; i++) {
@@ -401,6 +452,11 @@ async function run(ctx, argv) {
let loggingIn = true
let loginTimer = null
let loginTick = null
let interruptStop = null
const detachInterrupt = discordAttachInterrupt(ctx, function () {
if (typeof interruptStop === 'function') interruptStop()
Promise.resolve(client.destroy()).catch(function () {})
})
if (Events.Warn) {
client.on(Events.Warn, function (message) {
@@ -484,6 +540,11 @@ async function run(ctx, argv) {
resolve('ready')
})
}),
new Promise(function (resolve, reject) {
interruptStop = function () {
resolve('interrupt')
}
}),
new Promise(function (_, reject) {
let waited = 0
loginTick = setInterval(function () {
@@ -539,19 +600,27 @@ async function run(ctx, argv) {
loggingIn = false
if (loginTimer) clearTimeout(loginTimer)
if (loginTick) clearInterval(loginTick)
detachInterrupt()
await Promise.resolve(client.destroy()).catch(function () {})
return
}
loggingIn = false
if (loginTimer) clearTimeout(loginTimer)
if (loginTick) clearInterval(loginTick)
if (ctx.exitCode === 130) {
detachInterrupt()
await Promise.resolve(client.destroy()).catch(function () {})
return
}
await new Promise(function (resolve) {
function shutdown() {
detachInterrupt()
Promise.resolve(client.destroy())
.catch(function () {})
.then(resolve)
}
interruptStop = shutdown
if (typeof ctx.registerKernelShutdownHook === 'function') {
ctx.registerKernelShutdownHook(shutdown)
}