Skip to main content
The bot reads all configuration from environment variables using Effect’s Config module and ConfigProvider. Feature-specific variables are scoped under a prefix (e.g. AUTOTHREADS_, NOEMBED_) and resolved with ConfigProvider.nested.

Core credentials

DISCORD_BOT_TOKEN
string
required
The bot token from the Discord Developer Portal. Read as a redacted value via Config.redacted("DISCORD_BOT_TOKEN") so it never appears in logs or traces.
OPENAI_API_KEY
string
required
Your OpenAI API key. Used to power AI title generation, documentation article creation, and conversation summarization via gpt-5.2. Read as a redacted value via Config.redacted("OPENAI_API_KEY").
GITHUB_TOKEN
string
required
A GitHub personal access token. Required by the Issueifier feature to create GitHub issues from Discord conversations.

Discord gateway

The bot connects to the Discord gateway with the following intents, configured in DiscordConfig.ts:
packages/discord/src/DiscordConfig.ts
export const DiscordConfigLayer = DiscordConfig.layerConfig({
  token: Config.redacted("DISCORD_BOT_TOKEN"),
  gateway: {
    intents: Config.succeed(
      Intents.fromList(["GuildMessages", "MessageContent", "Guilds"]),
    ),
  },
})
IntentPurpose
GuildMessagesReceive message create and update events in guild channels
MessageContentAccess the content of messages (privileged intent)
GuildsReceive guild and channel lifecycle events
MessageContent is a privileged intent. You must enable it explicitly in the Discord Developer Portal under your bot’s settings, otherwise the bot will not receive message content.

Logging

DEBUG
boolean
default:"false"
When set to true, switches the minimum log level from Info to All, enabling verbose output for all Effect log spans and traces. Useful during local development.
main.ts
const LogLevelLive = Layer.effect(
  References.MinimumLogLevel,
  Config.withDefault(Config.boolean("DEBUG"), false)
    .pipe(Config.map((debug) => (debug ? "All" : "Info")))
    .asEffect(),
)

AutoThreads

The AutoThreads feature automatically creates a Discord thread for every new message posted in an eligible channel. A channel is eligible when its topic contains the keyword configured below. Variables are read under the AUTOTHREADS_ prefix via ConfigProvider.nested("autothreads").
AUTOTHREADS_KEYWORD
string
default:"[threads]"
The string that must appear in a channel’s topic for AutoThreads to activate in that channel. When a new (non-bot) message is posted in a matching channel, the bot creates a thread and uses OpenAI to generate a title.Example: Set AUTOTHREADS_KEYWORD=[threads] and add [threads] anywhere in a channel’s topic.
Thread titles are AI-generated from the message content. If the OpenAI call fails, the title falls back to "<username>'s thread". Users can edit or archive their thread using the buttons the bot posts.

NoEmbed

The NoEmbed feature automatically suppresses Discord’s link preview embeds for messages containing whitelisted URLs. It activates in channels (and their public threads) whose topic contains the configured keyword. Variables are read under the NOEMBED_ prefix via ConfigProvider.nested("noembed").
NOEMBED_KEYWORD
string
default:"[noembed]"
The string that must appear in a channel’s topic for NoEmbed to activate. Add this keyword to any channel topic to start suppressing embeds there.
NOEMBED_URL_WHITELIST
string
default:"effect.website"
A comma-separated list of URL substrings. Only embeds whose URL contains one of these substrings are suppressed. Other embeds are left untouched.Example: NOEMBED_URL_WHITELIST=effect.website,example.com
NOEMBED_URL_EXCLUDE
string
default:"effect.website/play"
A comma-separated list of URL substrings. Even if a URL matches the whitelist, it is excluded (embed kept) when it also matches one of these substrings.Example: NOEMBED_URL_EXCLUDE=effect.website/play keeps playground link previews visible even though effect.website is whitelisted.

Reminders

The Reminders feature does not use environment variables. Instead, it reads configuration directly from channel topics at runtime. To schedule a reminder for a channel, add one or more [reminder:CRON:MESSAGE] entries to its topic:
[reminder:0 9 * * 1:Weekly standup time!]
PartDescription
CRONA standard cron expression (e.g. 0 9 * * 1 for every Monday at 09:00 UTC)
MESSAGEThe message content to post when the cron fires
When the cron fires, the bot posts the message to the channel and immediately creates a thread from it, named <date> - <message>.
You can add multiple reminders to the same channel by including multiple [reminder:...] entries in the topic. Each is scheduled independently.
Reminders are parsed when the bot starts (GUILD_CREATE) and re-evaluated whenever a channel is created or updated (CHANNEL_CREATE, CHANNEL_UPDATE). Updating a channel’s topic immediately reschedules its reminders.

Build docs developers (and LLMs) love