chatgpt discord bot

How To Make A ChatGPT Discord Bot With LangChain

In this post, we’ll be making a Discord bot, which we’re going to connect to OpenAIs ChatGPT model (gpt-3.5-turbo). Additionally, we’ll also give it access to the internet, so it’ll be aware of up to date state of things.

Furthermore, Discord API offers us a lot of options and tools to create bots for all kinds of purposes. For example, it’s been quite popular for playing music in voice channels and giving users access to certain channels.

Prerequisites

Like any other python project, first thing we need to do is import all the necessary libraries and tools. Following tools will enable us to fetch API keys from a separate file, create a basic structure for a working Discord bot, and build a chatbot structure using LangChain.

import os
import json
import asyncio
import discord
from discord.ext import commands

from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferWindowMemory
from langchain.utilities import SerpAPIWrapper
from langchain.agents import initialize_agent, AgentType, Tool

Next, we’ll need to define the function that will fetch an API key from a separate .json file. This way you can keep track of all API keys in your project. Additionally, it allows you to hide them with .gitignore file in case you’re uploading your work into public repository on GitHub.

ROOT = os.path.dirname(__file__)
def get_token(token_name):
    
    auth_file = open(os.path.join(ROOT, 'auth.json'))
    auth_data = json.load(auth_file)
    token = auth_data[token_name]
    return token

os.environ['OPENAI_API_KEY'] = get_token('openai-token')
os.environ['SERPAPI_API_KEY'] = get_token('serpapi-token')

As we mentioned before, we’ll also give the bot access to the internet, so we’ll need to use SerpAPI to do that. Furthermore, using API keys with LangChain is fairly simple, since you can define them with environment variables.

Defining ChatGPT components for our Discord bot

There are a couple of things we’ll need to add into the mix to make our bot behave intelligently. In order to connect our bot to the internet, we’ll need to define a tool, which our chatbot will use to browse the web.

Then, we’ll need to define all the core components, such as memory, large language model (LLM), and an Agent, which pools it all together.

search = SerpAPIWrapper()
tools = [
    Tool(
        name='Current Search',
        func=search.run,
        description='useful for when you need to answer questions about current events or the current state of the world. the input to this should be a single search term.'
    )
]
memory = ConversationBufferWindowMemory(memory_key='chat_history', return_messages=True)
llm = ChatOpenAI(temperature=0.9)

agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION,
    memory=memory
)

Setting up Discord Cog

In this section, we’ll make a class in which we’ll define our Discord bot command. The purpose of this command is to take an argument and pass it as a prompt for our chatbot. Furthermore, we’ll make a hybrid command, which means we can use it in a few different ways.

We can use the command by:

  • mentioning the bot in chat, followed by the name of the command and prompt (@botusername command_name prompt)
  • writing an exclamation mark (!) before the command name and prompt (!command_name prompt)
  • slash command (/command_name prompt)
class Chat(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
    
    @commands.hybrid_command(name='chat')
    async def chat(self, ctx, *, prompt):
        async with ctx.typing():
            response = agent.run(input=prompt)
        
        await ctx.send(f'<@{ctx.message.author.id}> says: {prompt}\n\n{response}')

Okay, now we have our functionality for our command, but there is still more to take care of for our bot to work. Next, we need to define intents and create a bot instance.

intents = discord.Intents.default()
intents.message_content = True

bot = commands.Bot(
    command_prefix=commands.when_mentioned_or('!'),
    description='A chatbot with access to the internet',
    intents=intents
)

In case you’re having any troubles with intents, you need to check if you have them turned on/approved in the Discord application settings under Bot tab.

chatGPT discord bot intents

Next, we need to register our hybrid command within our bot tree, so we’ll be able to use the slash commands for it.

The following function fires everytime you run the bot script.

@bot.event
async def on_ready():
    print(f'Logged in as {bot.user} (ID: {bot.user.id})')
    print('--------------------')
    await bot.tree.sync()

Bring the ChatGPT Discord bot to life

Finally, we’re at the stage to run this thing and test it out. In the following function, we add the Cog functionality with the command to the bot instance and start it.

async def main():
    async with bot:
        await bot.add_cog(Chat(bot))
        await bot.start(get_token('discord-token'))

asyncio.run(main())

And here is the final result.

As we can see, it browsed the internet to retrieve this information, since it wasn’t trained to know this answer. Looks like this thing works!

Conclusion

To conclude, we made a simple, but powerful Discord bot powered by the same model that ChatGPT uses. I learn a lot while working on this project and I hope this tutorial proves to be helpful to you as well.

Share this article:

Related posts

Discussion(0)