---
title: "How to add artificial intelligence to a Discord bot | StreetHosting"
description: "Make your Discord bot answer with AI using fetch and a provider's API: per channel context, per user limit, a 2000 character cut and a key kept out of the code."
url: "https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence"
type: "page"
language: "en-US"
---

Discord Bots · 8 min · Intermediate

Published on Nov 13, 2026 · Updated on Nov 13, 2026

# Discord bot with artificial intelligence: how to integrate it and control the cost

A bot that answers when mentioned, remembers the channel's recent conversation and doesn't blow the budget. The code uses plain fetch against an API compatible with OpenAI's chat API, with URL, key and model in environment variables.

By [Equipe StreetHosting](https://streethosting.com.br/en/autores#equipe-streethosting) · StreetHosting infrastructure and support team

[Automation and webhooks](https://streethosting.com.br/en/guides/topics/automation)

Summarize with:

[](https://chat.openai.com/?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-artificial-intelligence.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "ChatGPT") [](https://claude.ai/new?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-artificial-intelligence.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Claude") [](https://www.google.com/search?udm=50&aep=11&q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-artificial-intelligence.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Google AI Mode") [](https://x.com/i/grok?text=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-artificial-intelligence.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Grok") [](https://www.perplexity.ai/search/new?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-artificial-intelligence.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Perplexity")

Share:

[](https://x.com/intent/tweet?text=How%20to%20add%20artificial%20intelligence%20to%20a%20Discord%20bot&url=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-artificial-intelligence "Share on X") [](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-artificial-intelligence "Share on Facebook") [](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-artificial-intelligence "Share on LinkedIn") [](https://wa.me/?text=How%20to%20add%20artificial%20intelligence%20to%20a%20Discord%20bot%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-artificial-intelligence "Share on WhatsApp")

For agents: Copy as Markdown [.md](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence.md)

In this guide 7 sections

* [How it works and where the model runs](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#como-funciona)
* [URL, key and model in environment variables](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#variaveis)
* [Call the chat API with fetch](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#chamada-api)
* [The complete bot](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#codigo-bot)
* [Control the cost](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#custo)
* [Care with what the AI writes](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#cuidados)
* [Where to host the bot](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#onde-rodar)

Quick answer

The bot listens for messages that mention it, builds a list with the channel's short history and makes a `POST` with `fetch`to the provider's chat API, using the URL, key and model from environment variables. The answer is cut at 2000 characters and sent with `message.reply`. The model runs at the provider, not on the bot's hosting, and the cost is controlled by a per user limit, a short history and a token ceiling.

## How it works and where the model runs[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#como-funciona)

Before the code, it is worth understanding the design, because this is where cost and hosting questions come from. A bot with AI has three separate pieces:

1. Discord, which delivers the user's message to your bot.
2. Your bot, a Node.js process that receives the message and builds the request.
3. The AI provider, which runs the model on its own servers and returns the text.

The language model **does not run inside the bot plan**. The provider you signed up with does the heavy work, and it is the one that charges, usually by the amount of text processed. Your hosting only runs a small program that talks to Discord on one side and to the provider's API on the other. That explains two things: the bot plan doesn't need much RAM, and the AI bill arrives separately, from the provider.

Since OpenAI's chat format became a de facto standard, many providers and programs accept the same request: a POST to a chat completions address, with the list of messages and the model name. That is why the code in this guide uses no SDK and doesn't hardcode a model name. What changes from one provider to another goes into environment variables.

## URL, key and model in environment variables[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#variaveis)

Create a `.env`file in the bot's folder with four values. The three for the AI come from the provider's documentation and dashboard:

| Variable       | What it holds                                  | Example                                          |
| -------------- | ---------------------------------------------- | ------------------------------------------------ |
| DISCORD\_TOKEN | The bot token, from Discord's developer portal | (your token)                                     |
| AI\_API\_URL   | Full address of the provider's chat endpoint   | https://api.yourprovider.com/v1/chat/completions |
| AI\_API\_KEY   | API key generated in the provider's dashboard  | (your key)                                       |
| AI\_MODEL      | Model name, exactly as the provider lists it   | (model name)                                     |

The model name stays out of the code on purpose: providers rename and retire models often, and changing a variable is much easier than editing the program. On Node 20.6 or newer, you can load the file without an extra library, by starting the bot with `node --env-file=.env index.js`.

**Never put the key in the code.** Whoever gets the key spends your money. Keep the `.env` in the `.gitignore`, don't print the key in logs and, if it leaks in a public repository or a screenshot, revoke it in the provider's dashboard and generate another right away. The guide on [safe tokens and environment variables](https://streethosting.com.br/en/guides/discord-bots/discord-bot-token-environment-variables) covers this care in detail.

## Call the chat API with fetch[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#chamada-api)

The request always has the same format: an authorization header with the key and a JSON body with the model and the list of messages. Each message has a role (`system`, `user` or `assistant`) and a text. The response carries the generated text in `choices[0].message.content`.

`const { AI_API_URL, AI_API_KEY, AI_MODEL } = process.env; const SYSTEM = 'You are the assistant for this Discord server. ' + 'Reply in the same language as the user, briefly and directly.'; async function askAI(messages) { const response = await fetch(AI_API_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + AI_API_KEY, }, body: JSON.stringify({ model: AI_MODEL, messages: [{ role: 'system', content: SYSTEM }, ...messages], max_tokens: 500, }), signal: AbortSignal.timeout(30000), }); if (!response.ok) { throw new Error('The provider answered with status ' + response.status); } const data = await response.json(); return data.choices?.[0]?.message?.content?.trim() ?? ''; }`

Three details matter. The `AbortSignal.timeout` drops the call after 30 seconds, so the bot doesn't wait forever on a slow provider. The `max_tokens` limits the size of the answer, which is the main cost control per question. Some newer models ask for the `max_completion_tokens` field instead, so check your provider's documentation. On reasoning models that ceiling includes the internal reasoning, and a low value can return an empty answer. And the `system` message defines the behavior: that is where you ask for short answers in the right language.

## The complete bot[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#codigo-bot)

Now the Discord part. The bot only answers when mentioned, keeps the last messages of each channel in a `Map`, shows "typing..." while it waits for the AI, applies the per user limit and cuts the answer at 2000 characters. Paste this snippet in the same file, right below the `askAI` function from the previous section, because it uses the variables declared there.

`const { Client, GatewayIntentBits, Events } = require('discord.js'); const { DISCORD_TOKEN } = process.env; if (!DISCORD_TOKEN || !AI_API_URL || !AI_API_KEY || !AI_MODEL) { console.error('Missing environment variables (check the .env file).'); process.exit(1); } const MAX_HISTORY = 8; // messages kept per channel const LIMIT_PER_HOUR = 10; // questions per user every hour const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages], }); const histories = new Map(); // channelId -> [{ role, content }] const usage = new Map(); // userId -> [timestamps] function canUse(userId) { const now = Date.now(); const recent = (usage.get(userId) ?? []).filter((t) => now - t < 3600000); if (recent.length >= LIMIT_PER_HOUR) { usage.set(userId, recent); return false; } recent.push(now); usage.set(userId, recent); return true; } function truncate(text) { return text.length <= 2000 ? text : text.slice(0, 1997) + '...'; } client.on(Events.MessageCreate, async (message) => { if (message.author.bot || !message.guild) return; if (!message.mentions.has(client.user, { ignoreEveryone: true, ignoreRoles: true })) return; const question = message.content .replace(new RegExp('<@!?' + client.user.id + '>', 'g'), '') .trim(); if (!question) { await message.reply('Send me a question along with the mention.'); return; } if (!canUse(message.author.id)) { await message.reply('You reached the limit of questions per hour. Try again later.'); return; } const name = message.member?.displayName ?? message.author.username; const history = histories.get(message.channelId) ?? []; history.push({ role: 'user', content: name + ': ' + question }); const typing = setInterval(() => message.channel.sendTyping().catch(() => {}), 8000); message.channel.sendTyping().catch(() => {}); try { const text = await askAI(history); if (!text) throw new Error('Empty answer from the provider'); history.push({ role: 'assistant', content: text }); while (history.length > MAX_HISTORY) history.shift(); histories.set(message.channelId, history); await message.reply({ content: truncate(text), allowedMentions: { parse: [], repliedUser: false }, }); } catch (error) { console.error('Error calling the AI:', error.message); history.pop(); // drop the question that failed await message.reply('I could not answer right now. Try again in a moment.'); } finally { clearInterval(typing); } }); client.login(DISCORD_TOKEN);`

As for intents, this bot uses only `Guilds` and `GuildMessages`. Discord delivers the text of messages that mention the bot even without the privileged message content intent, and since the bot only reacts to mentions, it needs nothing more. If you ever want it to read messages without a mention, you will need to turn that intent on in the developer portal. If you run into trouble with it, see the guide on [slash commands](https://streethosting.com.br/en/guides/discord-bots/create-discord-bot-slash-commands), which is an alternative path: instead of a mention, the user types `/ask`.

## Control the cost[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#custo)

AI billing is usually by volume of text, adding what you send (the system prompt, the history and the question) and what the model returns. Each call resends the whole history, so a long conversation gets more expensive with every message. These are the locks the code above already applies, plus one that lives outside it:

* **Per user limit:** the `canUse` function allows 10 questions per hour per person. Adjust it to your server, and consider a lower limit for new members.
* **Short history:** with `MAX_HISTORY = 8` the bot only remembers the latest messages of the conversation. Less text sent means a lower cost and faster answers.
* **Token ceiling:** the `max_tokens` setting stops a single answer from eating a fortune. With 500, the answer fits within Discord's 2000 characters in most cases.
* **Spending limit at the provider:** most dashboards let you set a monthly budget or alerts. Set one, because it is the only lock that still holds if the bot has a bug.

The hourly limit lives in memory and resets when the bot restarts. For a small server that is enough. If the bill worries you, store the counters in a database and add a daily ceiling for the whole server as well.

## Care with what the AI writes[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#cuidados)

The text comes from a model, so treat it as untrusted input. Two precautions are already in the code. The `allowedMentions: { parse: [] }` setting stops the reply from tagging `@everyone`, roles or people, even if someone manages to trick the model into writing that. And the 2000 character cut keeps Discord from rejecting the message with an error.

* **Don't give the model powers:**use the AI only to generate text. Don't run commands, bans or database queries based on what it writes.
* **A clear system prompt:** state the tone, the language and what the bot must not do. No prompt is manipulation proof, which is why the cost and permission locks matter more.
* **Say it is an AI:**make it explicit in the bot's description and in the help command that answers may contain mistakes.
* **Member data:**the text of the questions goes to the provider. Don't send private information, and read its data policy before opening the feature to the community.

For nicer answers, you can send the AI's text inside an embed. See how in [embeds and formatted messages](https://streethosting.com.br/en/guides/discord-bots/discordjs-embed-formatted-messages), remembering that an embed description takes up to 4096 characters.

## Where to host the bot[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#onde-rodar)

Since the model runs at the provider, your bot is light: a Node.js process waiting for messages and making an HTTP call now and then. On [StreetHosting bot hosting](https://streethosting.com.br/en/bots) the Discord Essential plan, at R$ 9.99 per month, with 1 GB of RAM, 0.5 vCPU, 2 GB of NVMe and up to 2 bots, already handles running this code. The plan hosts the bot, not the artificial intelligence: the cost of the model stays with the AI provider you choose.

If you want to run your own model instead of paying per use, that is a different kind of project and calls for a much bigger machine. Since the chat format is the same, the code in this guide works by pointing `AI_API_URL` at your own server, and the guide on [running Ollama on a VPS without a GPU](https://streethosting.com.br/en/guides/vps/run-ollama-llm-vps-cpu) shows what to expect in speed on that path.

In this guide

* [How it works and where the model runs](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#como-funciona)
* [URL, key and model in environment variables](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#variaveis)
* [Call the chat API with fetch](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#chamada-api)
* [The complete bot](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#codigo-bot)
* [Control the cost](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#custo)
* [Care with what the AI writes](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#cuidados)
* [Where to host the bot](https://streethosting.com.br/en/guides/discord-bots/discord-bot-artificial-intelligence#onde-rodar)

## Frequently asked questions

Does the AI model run on the bot's hosting plan?

No. The model runs on the servers of the AI provider you signed up with. The bot only receives the message on Discord, sends the text to the provider's API over the internet and returns the answer. That is why the bot plan can be small: it only runs Node.js.

Do I need a provider SDK for this?

No. Most providers offer a chat API compatible with OpenAI's, and a POST with fetch is enough, which already ships with Node 18 or newer. Switching providers comes down to changing the URL, the key and the model name in the environment variables.

Why does the bot need to be mentioned to answer?

Because that way it only spends calls when someone asks. On top of that, Discord delivers the content of messages that mention the bot even without the privileged message content intent, which simplifies the setup.

How do I avoid a high bill from the AI provider?

Combine four locks: a per user usage limit in the bot itself, a short history, a token ceiling on the answer and a spending limit set in the provider's dashboard. With all four, even a server where everyone abuses it has a known maximum spend.

The AI answer went over 2000 characters. Now what?

Discord refuses messages longer than 2000 characters. Cut the text before sending or split it into parts. Asking for short answers in the system prompt and limiting output tokens lowers the chance of that happening, and the cost too.

Next step

See bot plans

24/7 Discord bots with fast activation and support in Portuguese.

[See bot plans](https://streethosting.com.br/en/bots)

## Related guides

[Discord bots Beginner Keep your Discord bot token safe: .env, .gitignore and what to do if it leaks The bot token is its password. Whoever has the token controls the bot. Learn how to move the token out of your code with a .env file, keep it off GitHub and what to do when it leaks. 8 min Read guide](https://streethosting.com.br/en/guides/discord-bots/discord-bot-token-environment-variables) [Discord bots Beginner How to create a Discord bot with slash commands Slash commands improve the user experience and make your bot easier to use. Here is a clear path to get started. 2 min Read guide](https://streethosting.com.br/en/guides/discord-bots/create-discord-bot-slash-commands) [Discord bots Beginner Discord embeds with discord.js: how to build formatted messages The embed is the colored card that gives your bot's messages a professional look. Learn to build one from scratch, the official limits, what markdown works inside it and how to edit an embed that was already sent. 7 min Read guide](https://streethosting.com.br/en/guides/discord-bots/discordjs-embed-formatted-messages)

[← Back to the Guide Center](https://streethosting.com.br/en/guides)
