Wednesday, 1 December, 2021 UTC


Summary

OpenAI’s GPT-3 is a language model that offers a multifaceted “text in, text out” interface that can be applied to virtually any task. It can produce code, stories, recipes, and more. The engine is capable of doing anything - it can even do your homework for you! OpenAI's GPT-3 engine is also a remarkable tool for chatbots since its output text is indistinguishable from human text. A fitting integration with this is Discord chatbots.
In recent years, Discord has become the central messaging platform for communities especially with the help of Discord bots. Through Discords extensive API, developers are able to build robust bots that are capable of various actions such as automating tasks and chatting with users.
With the gaining traction of both of these technologies, I decided to combine them to build an intelligent but fun chatbot.
In this article you’ll learn how to use Node.js to set up a Discord chat bot powered by OpenAI’s GPT-3 model.
Prerequisites
Before you get started, you’ll need a few things to create your chatbot:
  • A Discord account.
  • Node.js v16+ installed on your machine.
  • Visual Studio Code or your preferred IDE.
  • An OpenAI API key - you’ll need to request beta access.
Set up Discord

Discord server

To get started, set up a Discord server by first downloading and opening the Discord client (or by heading to the web client) and clicking on the green + icon on the left tab.
A menu will pop up asking if you’d like to choose a template - choose Create My Own. The next section will ask you about your new server - choose whichever option you’d like or you can skip this section. The last section will ask you to choose a server name and icon - feel free to add your own or stick with the defaults. Lastly, click the blue Create button and you will be directed to your newly created server.
Now that you have your Discord server ready, let’s set up your Discord bot.

Discord bot

Set up a Discord application for your bot through the Developer Portal. Once you’re signed in, it should redirect you to the applications page.
Click New Application on the top right. A box to create an application should pop up. Enter "discord-gpt3-bot" for your application name and then click Create. You will be redirected to your new application’s portal which should look like this:
In the panel on the left hand side, click Bot to be redirected to the Bot submenu. Click Add Bot and then click Yes, do it! to turn your newly created application into a bot. The Bot menu should populate with new settings and look like this:
Under the Build-A-Bot section, you should see the option to reveal your hidden token. Click Copy to copy your token and store it in a safe place - this token will be used in the next section.
This token should be kept private and should not be shared with anyone. This token gives full access to your bot account and is used to send code to it. If your token ever gets compromised, click Regenerate next to your token in the bot menu to reset your token.
The next step is to send your bot to your server. On the left hand side, click OAuth2 and you should be redirected to the OAuth2 menu as seen below:
Copy your Client ID shown under the Client information section and place it in the URL below in place of YOUR_CLIENT_ID and place it in your browser.
https://discord.com/oauth2/authorize?scope=bot&permissions=8&client_id=YOUR_CLIENT_ID 
This link with your client ID will take you to a dialog that will authorize your bot to a server of your choice. Choose the server you’d like your bot to join and then click Authorize.
You might be presented with a CAPTCHA to complete before your application is authorized. Head over to the Discord server and you should see that the "discord-gpt3-bot" joined.
Now that your chatbot is connected to your server, it’s time to set up your Node.js application.
Create your Node.js Application
In this section, you are going to set up your Node.js application for your chatbot. To keep things organized, create a folder called discord-gpt3-bot to store all of your application files. In your terminal or command prompt, navigate to your preferred directory and enter the following commands:
mkdir discord-gpt3-bot cd discord-gpt3-bot npm init -y 
This command will create your project file and scaffold out your Node project by creating a package.json file that will contain your project's metadata and package dependencies.

Install dependencies

Your next step is to install all the dependencies needed for your project. You will need three packages:
  • The openai-api wrapper - An unofficial API wrapper for OpenAI which seamlessly allows you to interact with the API.
  • Discord.JS - Discord’s official package which also allows you to interact with their API.
  • Dotenv - To store and access environment variables.
The Node.js open-api wrapper was created by Njerschow and is not affiliated with OpenAI. Although the package is maintained, OpenAI does not verify the correctness or security of it.
To install these dependencies, enter the following command in your terminal:
npm install openai-api discord.js dotenv 
Now that the dependencies are installed, you will need to set up your environment variables.

Secure environment variables

The dotenv package is used to access environment variables required to interact with both the Discord and OpenAI APIs.
Create the .env file with the following command:
touch .env 
Open up the .env file using your preferred IDE and place the following lines into the file:
OPENAI_API_KEY=XXXXXXXX BOT_TOKEN=XXXXXXXX 
Replace the OPENAI_API_KEY placeholder with the OpenAI API key from your OpenAI Developer Quickstart profile and replace the BOT_TOKEN placeholder with the hidden token from the Discord Bot Developer Portal from earlier.
Build the GPT-3 Chatbot
Now that you’ve installed the necessary dependencies and configured your environment, it’s time to build out your bot!
Create an index.js file with the following command:
touch index.js 
Open up your index.js file and place the following code into the file:
require('dotenv').config(); const OpenAI = require('openai-api'); const openai = new OpenAI(process.env.OPENAI_API_KEY); const { Client, Intents } = require('discord.js'); const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] }); client.login(process.env.BOT_TOKEN); 
The environment variables you set up will be accessed as properties of the `process.env` object by name. For example, the `BOT_TOKEN` variable can be accessed as `process.env.BOT_TOKEN` in your code.
The first line initializes the dotenv package and imports your environment variables from the .env file. The second and third lines of code initialize the openai-api, and discord.js packages you included in the dependencies section.
The constant variables openai and client represent the instances of the package libraries which are used to interact with the respective API’s.
The client variable represents your Discord bot and can also notify you of any events going on in the server such as new messages. Feel free to check out the Discord.js documentation for more info on the API.
Now let’s execute your index.js file to allow your bot to log in to the client. Save the file and navigate back to your terminal and enter the following command:
node index 
Head over to your Discord server and you should see your bots status changed to online.
The chatbot is currently on the server, but is not listening to any events which is our next step to set up. Press CTRL+C in your terminal to abort the running index.js file.
For our chatbot, we want it to receive and read incoming messages before sending out a response. Copy the highlighted code and paste it into the index.js file:
const OpenAI = require('openai-api'); const Discord = require("discord.js"); const openai = new OpenAI(process.env.OPENAI_API_KEY); const client = new Discord.Client(); client.on("message", function(message) { if (message.author.bot) return; return message.reply(`${message.content}`); }); client.login(process.env.BOT_TOKEN); 
The highlighted lines above use the on method of the Discord client to send you notifications of events on the server and in our case the event is ”message”. This function will run every time the bot sees a message on the server. Line 8 checks to see if the author of a message is a bot and if it is, it’ll stop the function. This is to ensure that the bot doesn't respond to itself.
Line 9 is added for testing purposes to see if the chatbot can read and respond to messages. Save the file and run the bot again using the following command in the terminal:
node index 
Type in a message in your Discord server and you should see your chatbot reply back with the same message:
Press CTRL+C in your terminal to abort the running index.js file. Now that your bot can read and respond to messages, it’s time to integrate it with GPT-3.

Handle responses with GPT-3

Before we dive into integrating GPT-3, let’s understand how GPT-3 and the OpenAI API work. The core of the OpenAI API is the completions endpoint: You input some text as a prompt, and the model will generate a text completion based on the context or the pattern of the prompt.
For example, if you give the API the prompt, “As Descartes said, I think, therefore”, it will return the completion “I am”. To have a better understanding of the completion's endpoint, feel free to play around with OpenAI’s Playground or take a look at their examples.
To better tune the chatbot for our needs let’s use an example provided by OpenAI, Marv the sarcastic chatbot. This preset will give us a chatbot with the nature of being factual but also sarcastic.
This example above provides us with a prompt along the necessary parameters in the settings for the intended output. The settings fine tune GPT-3 even further, however we won’t be covering the details of that in this tutorial. For a deeper dive into GPT-3, check out The Ultimate Guide to OpenAI's GPT-3 Language Model.
Head back to your index.js file and insert the following variable below where you initialized the packages and above the client.on("message", function(message) {...}) listener:
let prompt =`Marv is a chatbot that reluctantly answers questions.\n\ You: How many pounds are in a kilogram?\n\ Marv: This again? There are 2.2 pounds in a kilogram. Please make a note of this.\n\ You: What does HTML stand for?\n\ Marv: Was Google too busy? Hypertext Markup Language. The T is for try to ask better questions in the future.\n\ You: When did the first airplane fly?\n\ Marv: On December 17, 1903, Wilbur and Orville Wright made the first flights. I wish they'd come and take me away.\n\ You: What is the meaning of life?\n\ Marv: I'm not sure. I'll ask my friend Google.\n\ You: hey whats up?\n\ Marv: Nothing much. You?\n`; 
This prompt variable is from the example image above but converted to a string and will be used as our input to the OpenAI API.
Replace the contents inside of the client.on("message", function(message) {...}) listener with the following highlighted code:
client.on("message", function (message) { if (message.author.bot) return; prompt += `You: ${message.content}\n`; (async () => { const gptResponse = await openai.complete({ engine: 'davinci', prompt: prompt, maxTokens: 60, temperature: 0.3, topP: 0.3, presencePenalty: 0, frequencyPenalty: 0.5, bestOf: 1, n: 1, stream: false, stop: ['\n', '\n\n'] }); message.reply(`${gptResponse.data.choices[0].text.substring(5)}`); prompt += `${gptResponse.data.choices[0].text}\n`; })(); }); 
The listener will grab your message and place it within the prompt variable. Then the OpenAI API calls the prompt with the given parameters from the example image. The completion response from the GPT-3 engine will then be sent out as a response to your message. The completion response is then appended to the prompt variable so the chatbot can keep the conversation in memory.
OpenAI's API usage is based on the number of your input and output tokens - A token is approximately 4 characters. The input prompt also has a limit of 2048 tokens so it's best to limit your input lengths.
The code above allows input lengths of an unbounded amount of tokens since it appends the input and output to `prompt` every time the API is called which is not recommended.

Test out the GPT-3 Discord bot

Now that GPT-3 is integrated into your chatbot it’s finally time to test it out!
To ensure your code is correct, here is the full code for the index.js file.
Save the code and run your Node.js application in your terminal with the following command:
node index 
Head over to your Discord server and start talking to your chatbot! Here is my conversation I had with the bot:
How fun, right? Responses with the API will be different so you’ll likely get a different response if you ask it the same question.
What's next for OpenAI GPT-3 chatbots?
In this tutorial we walked through how to use the OpenAI API with Discord’s API to create an intelligent chatbot that keeps up a conversation and answers questions for you. I hope you had some fun with this tutorial and learned a few things along the way!
Going forward, you can adjust the API settings and even test it out with different engines and presets to cater your chatbot for specific needs. If you’re needing some inspiration or looking to explore more with OpenAI, here are a few other projects using the API:
  • Start a Ghost Writing Career for Halloween with OpenAI's GPT-3 Engine and Java
  • Build a Cooking Advice Chatbot with Python, GPT-3 and Twilio Autopilot
  • Building a Chatbot with OpenAI's GPT-3 engine, Twilio SMS and Python
Happy Building!
Dhruv Patel is a Developer on Twilio’s Developer Voices team. You can find Dhruv working in a coffee shop with a glass of cold brew or he can either be reached at dhrpatel [at] twilio.com or LinkedIn.