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:

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:

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

Install in one command:

pip install botwire

Start free at botwire.dev