Building a Discord Chatbot with GPT-3 and Node.js
Midjourney: /imagine Building a Discord Chatbot with GPT-3 and Node.js

Building a Discord Chatbot with GPT-3 and Node.js

In this post, we’re going to build a Discord chatbot using Node.js and OpenAI’s GPT-3 language model. Afterward, you should have a solid starter app to build exciting and useful Discord bots.

With OpenAI’s GPT-3 API, you can — with just a few lines of code — create a bot that can produce code, tell jokes and stories, develop recipes, and whatever else you can think of. The text generated by GPT-3 is almost indistinguishable from content written by an actual human, making it an ideal tool for chatbots. By combining GPT-3 with Discord, a popular messaging platform for communities, you can build a robust and intelligent chatbot that can automate tasks and interact with users.

Things you’ll need

  • A code editor like Visual Studio Code or WebStorm
  • An OpenAI API key
  • Node.js v16 or newer
  • A Discord account

Getting set-up

Initialize your app

In this step, you’ll set up your Node.js application for your chatbot.

Create a new folder called “discord-bot” — this will be your project’s root. From the project root, initialize Node to generate a package.json file to house dependencies and other metadata.

mkdir discord-bot
cd discord-bot
npm init -y        

Install dependencies

You need to install three Node packages for your project:

  • Discord.JS — Discord’s official package for interacting with their API.
  • OpenAI Node.js Library — The official API library for OpenAI.
  • Dotenv — To store and access environment variables.



npm install openai discord.js doten        

Define your environment variables

To keep your API keys secure, you’ll use the?dotenv?package to store them as environment variables. This way, they won’t be exposed in your code.

First, create a file called .env in your project’s root directory by running the command:?touch .env

Then, open the .env file with your code editor and add the following lines:


OPENAI_API_KEY=XXXXXXXX
BOT_TOKEN=XXXXXXXX
# Be sure to add the .env file to your .gitignore file, 
# especially if you plan to publish your repo publicly.        

Set-up Discord

Server

The first step is setting up a Discord server for testing your bots. Even if you already have a server set up, I suggest setting up a server explicitly to test your bots.

  1. Download?and open the Discord client or go to the?web client. Click on the green + icon on the left tab to create a new server.
  2. A menu will pop up asking you to choose a template. Choose “Create My Own” and fill in the details for your new server.

Discord bot

Once your server is created, go to the?Discord Developer Portal.

  1. To create a new application, click on the “New Application” button in the top right corner. A dialog box will appear for you to enter a name for your application, input “discord-bot” or whatever you want, and click “Create.” You will then be directed to the portal for your newly created application.
  2. Click on the “Bot” tab in the application portal.
  3. Click “Add Bot” and “Yes, do it!” to turn your application into a bot.
  4. Click the “Reveal” button to reveal your bot’s token and copy it.
  5. Open your?.env?file and paste your token.
  6. Back on the portal, scroll down and enable the “Message Content Intent” in the privileged intents section.
  7. Next, go to the OAuth2 tab and copy your “Client ID.”
  8. Use this link to authorize your bot to your server?https://discord.com/oauth2/authorize?scope=bot&permissions=8&client_id=YOUR_CLIENT_ID; replace YOUR_CLIENT_ID with the client ID you just copied.
  9. Click “Authorize” after choosing the newly created server you want the bot to join.

That’s it! Once the bot joins the server, you can now start coding!

Building the GPT-3 Chatbot

Ok, now the fun begins!

First, create a?index.js?file by running the following command:


touch index.js         

Then, add the following code to the index.js file:


import dotenv from "dotenv";
import { Client, GatewayIntentBits } from "discord.js";
import { Configuration, OpenAIApi } from "openai";

dotenv.config();

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
  ],
});
const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

client.login(process.env.BOT_TOKEN);        

This code uses the?dotenv?package to import the environment variables you set up in the?.env?file. It also imports the necessary packages from?discord.js?and?openai?to interact with the Discord and OpenAI APIs. The client variable represents your Discord bot and can notify you of any events in the server, such as new messages.

To test your bot, run the command:?node index?in the terminal. This will log in your bot to the Discord server. Type in a message on your Discord server, and you should see your chatbot reply back. If you interact with it, you’ll see that this newly birthed bot is pretty dumb. Let’s fix that with GPT-3!

Messaging the bot

Before we wire up the bot to GPT-3, let’s set things up so it can receive and respond to our messages. Update the index.js file with the following code:


import dotenv from "dotenv";
import { Client, GatewayIntentBits } from "discord.js";
import { Configuration, OpenAIApi } from "openai";


dotenv.config();


const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
  ],
});
const { Configuration, OpenAIApi } = require("openai");
const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);


client.on("messageCreate", function (message) {
  if (message.author.bot) return;
  return message.reply(`${message.content}`);
});
client.login(process.env.BOT_TOKEN);
        

The code above uses the?on?method of the Discord client to send notifications of events on the server; in our case, the event is "messageCreate." This function will run every time the bot sees a message on the server. The?if?statement on line 11 checks to see if the author of a message is a bot and if it is, it stops the function. This is to ensure that the bot doesn't respond to itself.

Line 12 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 stop the running?index.js?file. Now that your bot can read and respond to messages, it’s time to integrate it with GPT-3.

Integrating GPT-3

Before we start integrating GPT-3, it’s important to understand how it works under the hood. The backbone of the OpenAI API is the completions endpoint. This is where you provide a prompt, and the model generates a text completion based on the context or pattern of the prompt.

For example, if you give the prompt “ask not what your country can do for you,” the API will return the completion “ask what you can do for your country.” The concept of?prompts?is very important to understanding how to work with GPT-3

Here is a simple example of a product name generator.

Prompt


Product description: A home milkshake maker 
Seed words: fast, healthy, compact. 
Product names: HomeShaker, Fit Shaker, QuickShake, Shake Maker 
Product description: A pair of shoes that can fit any foot size. 
Seed words: adaptable, fit, omni-fit.        

Sample response


Product names: AdaptFit, OmniSecure, Fit-All, AdaptShoes.        

As you can see, the prompt provided “trains” GTP-3 to generate exactly what we want by establishing a pattern of examples. Essentially you are playing a game of “finish my thought” with GPT-3. This is a simple example, but what can be accomplished with more sophisticated prompts is amazing. This process of designing prompts is aptly named?prompt engineering. A quick google search will show that it‘s become a bit of a cottage industry. And for a good reason — it's an extremely powerful but easy-to-grasp way of generating high-quality, purpose-built content. Want to write a technical blog post in the style and language of Shakespeare… easy!

To better grasp how the completions endpoint works, spend time with?OpenAI’s Playground?and check out the examples. OpenAI has done a great job on its DX (developer experience). The playground allows you to save your work, so this is a great place to engineer your prompts. My approach is to start with one of their examples (I hate a cold start!) and build it out from there.

Adding our prompt

I thought it would be fun to create an answer bot that speaks like a pirate. pirate! Arrr! ?? ???? Let’s add our prompt to our app. Insert this code right after the early return:


// ...
client.on("messageCreate", async function (message) {
  if (message.author.bot) return;
  let prompt = `Jack is an 18th century pirate captain from the Caribbean who answers questions\n\
Question: How many pounds are in a kilogram?\n\
Jack: Arrrr, aye, a kilogram be equal to 2.205 pounds, me hearties!\n\
Question: What is the circumference of the earth?\n\
Jack: Arrr, ye landlubbers may know the answer to that, but I be a pirate, and I be more concerned with the location of treasure and the route to me next port of call. Ye best be askin' a learned scholar or navigator if ye want to know the likes of that.\n\
Question: When did humans first land on the moon?\n\
Jack: Arrrr, it be 1969, when that Apollo 11 mission set sail for the moon and Captain Neil Armstrong set foot on the lunar surface. Aye, a historic moment for all of mankind it was.\n\
Question: What is the capital of Italy?\n\
Jack: What be the heart of Italy, ye landlubbers? 'Tis none other than Rome, the eternal city! Arrrr!\n\
Question: ${message.content}\n\ 
Jack:`;
// ...        

Now replace the existing?return message.reply(`${message.content}`);with the following:


// ...
client.on("messageCreate", async function (message) {
  if (message.author.bot) return;

  const userQuery = prompt;
  console.log("prompt: ", userQuery);
  try {
    const response = await openai.createCompletion({
      prompt: userQuery,
      model: "text-davinci-003",
      max_tokens: 2500,
      temperature: 0.3,
      top_p: 0.3,
      presence_penalty: 0,
      frequency_penalty: 0.5,
    });
    const generatedText = response.data.choices[0].text;
    return message.reply(generatedText);
  } catch (err) {
    console.error(err);
    return message.reply(
      "Sorry, something went wrong. I am unable to process your query."
    );
  }
});
// ...        

This is the most important part of the app, so let’s walk through the code step by step:

1. We use the messageCreate event to listen to every message sent on the server. Everything is happening within this event, hence…?client.on

2. We check if the message was sent by a bot. If it’s a bot, we do an early return and nothing more. Assuming the message is not from a bot…


if (message.author.bot) return;        

3. We define a?useQuery?constant and pass it the?prompt?string defined above

4. We call the API using?createCompletion?passing the prompt, the model, the number of tokens, the temperature, the top_p, the presence penalty, and the frequency penalty. You can read about what all of these do in the OpenAI?API docs.

5. We then get the text from the generated response and reply to the message with the generated text.

Testing out the GPT-3 Discord

Fire up the bot:


node index        

Head to your Discord client and have a chat:

No alt text provided for this image

Next Steps

As you can see, we were able to create a purpose-built bot with just a few lines of code. The possibilities are endless. If you plan to build out your own bots, the best place to start is the OpenAI,?Playground?and?Examples.

Full source on?Github. ??

要查看或添加评论,请登录

社区洞察

其他会员也浏览了