A feature-rich Discord bot powered by OpenAI (ChatGPT), Google (Gemini), or Anthropic (Claude) models, designed to provide intelligent conversational capabilities with image analysis support right within your Discord server.
- Discord Bot Token - Create a new application and bot
- OpenAI, Gemini, or Anthropic API key - Depending on which provider you use
- Doppler - For secure secret management at runtime
- Docker and Docker Compose
-
Set up Doppler:
- Create a Doppler project and config (e.g.
dev,prd) - Add the following secrets to your Doppler config:
- Required:
DISCORD_BOT_TOKEN,DISCORD_CLIENT_ID, and one of:OPENAI_API_KEY,GEMINI_API_KEY, orANTHROPIC_API_KEY - Optional:
AI_PROVIDER,OPENAI_MODEL_NAME,GEMINI_MODEL_NAME,CLAUDE_MODEL_NAME,LOG_LEVEL,MAX_HISTORY_LENGTH,MAX_HISTORY_TOKENS,REASONING_EFFORT,RESPONSES_VERBOSITY,ENABLE_WEB_SEARCH,ENABLE_GOOGLE_MAPS,ENABLE_CONTEXT_CACHE,USER_COOLDOWN_MS,CHANNEL_COOLDOWN_MS,MAX_PENDING_PER_CHANNEL,IMAGE_DOWNLOAD_TIMEOUT_MS,MAX_IMAGE_BYTES, and others listed in Configuration below
- Required:
- Create a service token for the config and copy it (you will pass it as
DOPPLER_TOKEN)
- Create a Doppler project and config (e.g.
-
Create a
docker-compose.ymlfile:
services:
ai:
image: ghcr.io/doubleangels/ai:latest
container_name: ai-discord-bot
restart: unless-stopped
cap_drop:
- ALL
cap_add:
- CHOWN
- SETGID
- SETUID
security_opt:
- no-new-privileges:true
read_only: true
environment:
- DOPPLER_TOKEN=${DOPPLER_TOKEN}
tmpfs:
- /tmp- Set the Doppler token and deploy:
export DOPPLER_TOKEN=your_doppler_service_token_here
docker compose up -dThis bot uses Doppler to inject secrets as environment variables at runtime. The container runs doppler run -- ... so all keys in your Doppler config are available to the app.
Required:
- Create a Doppler project and config (e.g.
prd). - Add your secrets in the Doppler dashboard (or CLI). At minimum:
DISCORD_BOT_TOKEN,DISCORD_CLIENT_ID, and one ofOPENAI_API_KEY,GEMINI_API_KEY, orANTHROPIC_API_KEY. - Generate a service token for that config and pass it when running the container as
DOPPLER_TOKEN(e.g. indocker-compose.ymlor your orchestration).
| Variable | Description | Required | Default | Example |
|---|---|---|---|---|
DOPPLER_TOKEN |
Doppler service token for the project/config | ✅ | - | - |
All other variables below can be stored in Doppler (recommended) or set in environment in your docker-compose.yml. The app reads them after Doppler injects them at startup.
| Variable | Description | Default |
|---|---|---|
AI_PROVIDER |
Backend to use: openai, gemini, or claude. |
openai |
OPENAI_MODEL_NAME |
OpenAI model when AI_PROVIDER=openai. |
gpt-5-nano |
GEMINI_MODEL_NAME |
Gemini model when AI_PROVIDER=gemini. Falls back to OPENAI_MODEL_NAME if unset. |
gemini-2.5-flash |
CLAUDE_MODEL_NAME |
Claude model when AI_PROVIDER=claude. Falls back to OPENAI_MODEL_NAME if unset. |
claude-haiku-4-5-20251001 |
OpenAI (Responses API, text + image, reasoning, verbosity, optional web search):
gpt-5.2, gpt-5.1, gpt-5, gpt-5-mini, gpt-5-nano, gpt-5.2-pro, gpt-5-pro, gpt-4.1, gpt-4.1-mini, gpt-4.1-nano, o3, o4-mini, o3-pro, o3-mini
Gemini (text + image, search grounding, thinking):
gemini-3-pro-preview, gemini-3-flash-preview, gemini-2.5-flash, gemini-2.5-flash-lite, gemini-2.5-pro, gemini-2.0-flash, gemini-2.0-flash-lite
Claude (vision, extended thinking on 4.5):
claude-sonnet-4-5-20250929, claude-sonnet-4-5, claude-haiku-4-5-20251001, claude-haiku-4-5, claude-opus-4-5-20251101, claude-opus-4-5, claude-3-5-sonnet-20241022, claude-3-5-haiku-20241022, claude-3-opus-20240229, claude-3-sonnet-20240229, claude-3-haiku-20240307, claude-sonnet-4-20250514, claude-3-5-sonnet-20240620
Set OPENAI_API_KEY for OpenAI; GEMINI_API_KEY for Gemini (Google AI Studio); ANTHROPIC_API_KEY for Claude (Anthropic Console).
| Variable | Description | Default |
|---|---|---|
REASONING_EFFORT |
OpenAI only. Reasoning effort: none, low, medium, high, xhigh. GPT-5.2 also supports none; GPT-5.2-pro supports medium, high, xhigh. |
none |
RESPONSES_VERBOSITY |
OpenAI GPT-5 only. Response verbosity: low, medium, high. |
low |
ENABLE_WEB_SEARCH |
OpenAI and Gemini. Set to true or 1 to enable web search (OpenAI built-in tool; Gemini Google Search grounding). |
off |
ENABLE_GOOGLE_MAPS |
Gemini only. Set to true or 1 to enable grounding with Google Maps (places, area summaries, location-aware answers). |
off |
| Variable | Description | Default |
|---|---|---|
MAX_OUTPUT_TOKENS |
Max tokens per reply (all providers). Clamped 256–65536. Lower values reduce cost. | 1024 |
MAX_HISTORY_TOKENS |
Rough token-estimated cap for stored per-channel conversation history (in addition to MAX_HISTORY_LENGTH). 0 disables token trimming. |
0 |
USER_COOLDOWN_MS |
Minimum time between requests per user (basic anti-spam/cost control). | 4000 |
CHANNEL_COOLDOWN_MS |
Minimum time between requests per channel (reduces pile-ups). | 1500 |
MAX_PENDING_PER_CHANNEL |
Max queued requests per channel before the bot responds “busy”. | 3 |
IMAGE_DOWNLOAD_TIMEOUT_MS |
Timeout for downloading image attachments. | 8000 |
MAX_IMAGE_BYTES |
Max bytes downloaded per image attachment. | 6000000 |
OPENAI_TIMEOUT_MS |
OpenAI only. Request timeout in milliseconds (5000–300000). | 60000 |
OPENAI_MAX_RETRIES |
OpenAI only. Max retries for transient failures (0–5). | 2 |
Reduces cost and latency by caching static prompt content. Single switch for all providers. Can be stored in Doppler or set in your environment.
| Variable | Description | Default |
|---|---|---|
ENABLE_CONTEXT_CACHE |
Set to true or 1 to enable context/prompt caching for all providers. |
false |
GEMINI_CACHE_TTL_SECONDS |
TTL for Gemini context cache (60–2073600). | 3600 |
| Variable | Description | Default |
|---|---|---|
CLAUDE_THINKING_BUDGET_TOKENS |
Claude only. Token budget for extended thinking on supported 4.5 models (0 = disabled, max 32000). | 0 |
| Variable | Description | Default |
|---|---|---|
GEMINI_SAFETY_SETTINGS |
Gemini only. JSON array of {"category":"...","threshold":"..."} to tune safety filters. Example: [{"category":"HARM_CATEGORY_HARASSMENT","threshold":"BLOCK_MEDIUM_AND_ABOVE"}]. Unset = API defaults. |
- |
The bot supports comprehensive image analysis when using vision-capable models:
- Image Descriptions: Get detailed descriptions of image content
- Visual Q&A: Ask questions about images and receive contextual answers
- Multi-Modal Input: Combine text and images in the same message
- Automatic Detection: Automatically processes image attachments
Usage Examples:
- Send an image with text: "What's in this image?"
- Ask follow-up questions about previously shared images
- Get analysis of charts, diagrams, or screenshots
- Shared conversation history per channel, allowing multiple users to participate
- Context preservation across message exchanges from all users
- Automatic history management and cleanup
- Basic backpressure (per-channel queue limit) and cooldowns to reduce spam/cost
- Mentions:
@AI What's the weather like? - Replies: Reply to any bot message to continue the conversation
- The bot sends messages with mentions disabled (
allowedMentions: { parse: [] }) to avoid accidental@everyone/ role pings. - Logs avoid printing full message contents and full model replies by default (metadata only).
Reset conversation history for a specific channel or all channels. Only users with the Administrator permission can see and use this command.
- No channel specified: Resets conversation history for all channels
- Channel specified: Resets conversation history for the selected channel only
