NapNodes

← Discord bot guides

Discord bots · updated 24 October 2026

How to Make an AI Discord Bot (ChatGPT, Gemini…) in Python

An AI Discord bot doesn't carry the AI inside it: it sends the question over the internet to a service like ChatGPT (OpenAI) or Gemini (Google) and posts what it answers. That's why the bot is small and the code short: this one has an /ask command and works with almost any AI by changing two lines of the .env.

1. What you need

A Discord bot created in the Developer Portal, with its token. If it's your first bot, do the step-by-step Python bot first: here we assume you know how to create it and invite it (with “bot” and “applications.commands”).

And an API key for the AI you want to use. OpenAI's comes from platform.openai.com and Gemini's from Google AI Studio (aistudio.google.com). It isn't the ChatGPT Plus subscription: the API is paid separately, by usage (by tokens, chunks of text), and Gemini has a free tier with usage limits. Check today's prices and limits on the provider's page before you start.

Rather not set it up yourself? Discord bot hosting from €1.50 a month, no contract and a full refund within 72 hours. Or create a free Discord bot, no card needed.

2. One library for almost every AI

OpenAI's official Python library (openai) talks to OpenAI and also to any service that copies its API shape, and there are many: Gemini supports it at https://generativelanguage.googleapis.com/v1beta/openai/, and others like OpenRouter or Groq have their own compatible address. So the same bot works for all of them: in the .env you change the address (AI_URL), the key (AI_KEY) and the model (AI_MODEL).

For OpenAI, leave AI_URL empty. Copy the model name exactly from your provider's documentation: they change often, and one that no longer exists gives an error.

3. The code

Three files in one folder. The /ask command first tells Discord it's going to take a while (Discord only waits 3 seconds for an answer, and the AI usually takes longer), then asks the AI and replies with what it says, cut to 2000 characters, the maximum for a Discord message.

The INSTRUCTIONS are what the AI reads before every question: change them to give it a personality or focus it on your community (the rules, your Minecraft server…).

requirements.txt
discord.py
openai
python-dotenv
.env
DISCORD_TOKEN=paste-the-bot-token-here
AI_KEY=paste-the-api-key-here
AI_MODEL=model-name
# Empty for OpenAI; for Gemini:
# AI_URL=https://generativelanguage.googleapis.com/v1beta/openai/
AI_URL=
app.py
import os

import discord
from discord import app_commands
from dotenv import load_dotenv
from openai import AsyncOpenAI

load_dotenv()  # reads the token and the key from the .env file

ai = AsyncOpenAI(
    api_key=os.environ["AI_KEY"],
    base_url=os.getenv("AI_URL") or None,  # empty = OpenAI
)
MODEL = os.environ["AI_MODEL"]
INSTRUCTIONS = (
    "You are the assistant of a Discord server. "
    "Answer in English, briefly and in a friendly tone."
)

intents = discord.Intents.default()
client = discord.Client(intents=intents)
tree = app_commands.CommandTree(client)


@tree.command(name="ask", description="Ask the AI something")
@app_commands.describe(text="What you want to ask")
@app_commands.checks.cooldown(1, 30)  # one question every 30 s per person
async def ask(interaction: discord.Interaction, text: str):
    await interaction.response.defer(thinking=True)  # “The bot is thinking…”
    try:
        r = await ai.chat.completions.create(
            model=MODEL,
            messages=[
                {"role": "system", "content": INSTRUCTIONS},
                {"role": "user", "content": text},
            ],
        )
        answer = r.choices[0].message.content or "(no answer)"
    except Exception as e:
        print("AI error:", e)  # shows up in the console
        answer = "The AI didn't answer. Try again in a while."
    await interaction.followup.send(answer[:2000])


@ask.error
async def ask_error(interaction: discord.Interaction, error):
    if isinstance(error, app_commands.CommandOnCooldown):
        await interaction.response.send_message(
            f"Wait {error.retry_after:.0f} s before another question.", ephemeral=True
        )
    else:
        print("Error:", error)


@client.event
async def on_ready():
    await tree.sync()  # publishes the /ask command
    print(f"Logged in as {client.user}")


client.run(os.environ["DISCORD_TOKEN"])

4. Try it on your computer

With Python 3.10 or newer: open a terminal in the folder, install the libraries with “pip install -r requirements.txt” and start it with “python app.py”. When it says “Logged in as…”, type /ask on your Discord server. The first time, the command can take a few minutes to show up.

If it replies “The AI didn't answer”, look at the terminal: the error says what's wrong. The most common causes are a badly copied key, a model name that doesn't exist, a badly copied AI_URL, or the provider account with no credit or without the free tier turned on.

5. Don't let them burn your credit

Every question costs tokens, and on a busy server someone can start asking non-stop. Three brakes:

The wait between questions: in the code, @app_commands.checks.cooldown(1, 30) allows one question every 30 seconds per person. Raise it if your community is big.

A spending limit in your provider's dashboard: almost all of them let you set a monthly cap or get an alert when you reach an amount. Set it before opening the bot to everyone.

Who can use it: on your Discord server, “Server Settings” → “Integrations” → your bot lets you choose which roles and channels can use /ask, without touching the code.

6. Keep the key safe

The AI key is money: whoever has it spends on your account. Just like the bot token, it goes in the .env and never in a public GitHub repository (if you push the code, add .env to your .gitignore). If it leaks, delete it in the provider's dashboard and create another one.

7. Keep it online all the time

The heavy lifting is done by the AI on the provider's servers; your bot only passes messages along, so it uses little memory and fits easily in the NapNodes free bot, with 256 MB.

On NapNodes: create the bot, switch it to Python in “Settings” → “Language”, upload the three files in “Files” and click “Start”. The libraries in requirements.txt install themselves at startup and app.py is the startup file that comes set; whatever the bot prints (AI errors included) shows up in “Console”. The whole process is in the Discord bot hosting guide.

The free bot is renewed with one click every week. If you'd rather not have to remember, the Mini plan (512 MB) stays online with nothing to renew (Discord bot pricing).

Frequently asked questions

Can I add ChatGPT to my Discord server?

Yes, with your own bot that uses the OpenAI API: it passes the question along and posts the answer. The API is paid by usage, separately from the ChatGPT subscription.

Is there a free AI for a Discord bot?

Google's Gemini has a free tier with usage limits, and it works with the same code by changing the address, the key and the model in the .env. Check today's limits on Google's page.

Why does my bot say “The application did not respond”?

Discord only waits 3 seconds for the first reply to a slash command, and the AI takes longer. You have to say beforehand that it'll take a while (interaction.response.defer) and reply afterwards with interaction.followup.send, as in this guide's code.

Can it answer when it's mentioned, without a command?

Yes, by reading messages with on_message, but then the bot needs the “Message Content Intent”, which you turn on in the “Bot” tab of the Developer Portal (and in the code, intents.message_content = True). With the /ask command you don't need it.

How much RAM does an AI Discord bot need?

Very little: the AI runs on the provider's servers, not yours. A bot like the one in this guide runs comfortably in 256 MB.

Shall we set it up for you?

Discord bot hosting from €1.50 a month, never oversold: your RAM is yours alone. And if you'd rather start without paying, there's a free Discord bot, no card needed.

Keep reading

All Discord bot guides, sorted →