Building a Discord Bot With AI Memory (Per User, Per Channel)
Free · Open source (MIT) · Works with LangChain, CrewAI, AutoGen · No signup
Your Discord bot's AI forgets everything between restarts. User context vanishes, conversations reset, and your bot feels brain-dead. This happens because Discord.py doesn't persist memory across sessions — your bot's RAM gets wiped clean every time it restarts, crashes, or redeploys.
The Problem: Discord Bots Have Amnesia
Discord bots are stateless by design. When your bot process dies (server restart, code update, crash), all in-memory variables disappear. Your AI might have brilliant conversations, but it can't remember:
- Previous messages from the same user
- User preferences or settings
- Ongoing conversation context
- Channel-specific state
Here's what breaks: A user asks your AI bot "Remember that I prefer Python examples." The bot says "Got it!" But after your next deployment, when the user asks "Show me a code example," your bot has zero memory of their preference.
This creates a frustrating experience where users must re-establish context every single session. Your Discord bot AI memory becomes useless, and persistent user state is impossible without external storage.
The core issue: Discord.py stores nothing. Your bot needs persistent memory that survives restarts and works across processes.
The Fix: Persistent Memory in 3 Lines
Install BotWire Memory for persistent discord bot user state:
pip install botwire
Here's a working Discord bot with AI memory that remembers users across restarts:
import discord
from discord.ext import commands
from botwire import Memory
bot = commands.Bot(command_prefix='!', intents=discord.Intents.default())
memory = Memory("discord-bot") # persistent namespace
@bot.command(name='remember')
async def remember_fact(ctx, *, fact):
user_id = str(ctx.author.id)
# Store user-specific memory
memory.set(f"user:{user_id}:context", fact)
await ctx.send(f"I'll remember: {fact}")
@bot.command(name='recall')
async def recall_fact(ctx):
user_id = str(ctx.author.id)
context = memory.get(f"user:{user_id}:context")
if context:
await ctx.send(f"You told me: {context}")
else:
await ctx.send("I don't remember anything about you yet.")
bot.run('YOUR_BOT_TOKEN')
This works immediately. Your discord bot memory persists across restarts, crashes, and redeployments.
How It Works: Keys, Namespaces, and User Isolation
BotWire Memory is a persistent key-value store. Think Redis, but zero-config and free. Every set() call saves to permanent storage at https://botwire.dev.
The pattern: namespace + key = value. Your namespace ("discord-bot") isolates your bot's data from other apps. Keys like "user:123456:context" separate each user's memory.
Here's a more complete example with conversation history:
from botwire import Memory
import json
from datetime import datetime
class DiscordAIMemory:
def __init__(self, namespace="discord-ai"):
self.memory = Memory(namespace)
def add_message(self, user_id, channel_id, message):
key = f"history:{user_id}:{channel_id}"
history = self.get_history(user_id, channel_id)
history.append({
"message": message,
"timestamp": datetime.now().isoformat()
})
# Keep last 50 messages
if len(history) > 50:
history = history[-50:]
self.memory.set(key, json.dumps(history))
def get_history(self, user_id, channel_id):
key = f"history:{user_id}:{channel_id}"
data = self.memory.get(key)
return json.loads(data) if data else []
def clear_user(self, user_id):
# BotWire doesn't have bulk delete, so track keys
keys_key = f"keys:{user_id}"
user_keys = self.memory.get(keys_key)
if user_keys:
for key in json.loads(user_keys):
self.memory.delete(key)
Cross-process safety: Multiple bot instances can share the same memory namespace. Updates from one process are immediately visible to others.
No expiration by default: Data persists until explicitly deleted. For temporary state, implement your own TTL logic using timestamps.
Integration with Discord Commands
Here's a production-ready Discord bot with per-user AI memory:
import discord
from discord.ext import commands
from botwire import Memory
import openai # or your preferred AI library
class AIBot(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.memory = Memory("discord-ai-bot")
@commands.command(name='chat')
async def ai_chat(self, ctx, *, message):
user_id = str(ctx.author.id)
channel_id = str(ctx.channel.id)
# Get conversation context
context_key = f"context:{user_id}:{channel_id}"
previous_context = self.memory.get(context_key) or ""
# Build AI prompt with memory
full_prompt = f"Previous context: {previous_context}\nUser: {message}\nAssistant:"
# Call your AI (OpenAI, Anthropic, etc.)
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": full_prompt}]
)
ai_response = response.choices[0].message.content
# Update persistent memory
new_context = f"{previous_context}\nUser: {message}\nAssistant: {ai_response}"
# Truncate to last 1000 chars to avoid memory bloat
if len(new_context) > 1000:
new_context = new_context[-1000:]
self.memory.set(context_key, new_context)
await ctx.send(ai_response)
@commands.command(name='forget')
async def clear_memory(self, ctx):
user_id = str(ctx.author.id)
channel_id = str(ctx.channel.id)
context_key = f"context:{user_id}:{channel_id}"
self.memory.delete(context_key)
await ctx.send("I've cleared our conversation history.")
async def setup(bot):
await bot.add_cog(AIBot(bot))
This bot remembers context per user per channel, handles memory cleanup, and works across bot restarts.
When NOT to Use BotWire
BotWire Memory isn't the right tool if you need:
- Vector search or embeddings: BotWire is key-value only, not a vector database
- High-throughput workloads: 1000 writes/day limit on free tier
- Sub-millisecond latency: HTTP API adds network overhead vs in-memory solutions
For semantic search or RAG applications, use Pinecone or Weaviate. For extreme performance, use Redis with your own hosting.
FAQ
Why not just use Redis? Redis requires setup, hosting, and config management. BotWire works immediately with zero infrastructure. For prototypes and small bots, the convenience wins.
Is this actually free? Yes, 1000 writes/day per namespace forever. Unlimited reads. No credit card, no trial expiration. Perfect for personal Discord bots.
What about data privacy? Data goes to https://botwire.dev servers. For sensitive data, self-host the open-source version (it's just FastAPI + SQLite).
Get Started
BotWire Memory solves Discord bot amnesia in minutes, not hours of Redis configuration.
pip install botwire
Full documentation and self-hosting instructions: https://botwire.dev