![](/style/images/good.png)
![](/style/images/bad.png)
Create A ChatGPT Discord Bot With Slash Commands
source link: https://jyroneparker.com/2023/03/03/create-a-chatgpt-discord-bot-with-slash-commands/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
![profile.png](https://jyroneparker.com/wp-content/uploads/2023/03/profile.png)
Adding ChatGPT and OpenAI To Your Discord Server
I love writing Discord bots, my favorite one was the Discord Twitter Bot. Now that ChatGPT API is available to developers I decided to create an OpenAI ChatGPT discord bot in Node.js and share the source code with you. This bot adds a slash command to your server called /generate-prompt that takes in a prompt string and the bot returns a result using the Text Completion API.
MastaGPT Bot in action
The Source Code
This is a dockerized node.js application that uses GitHub actions to deploy the Docker container to Docker Hub and GitHub Container Registry. The index.js file loads an instance of OpenAI and Discord.js, loads the slash commands from a commands
directory and registers them with Discord. It then listens for interactions i.e. a user using the slash command and then calls the generate
method to use the gpt-3.5-turbo
OpenAI language model to generate a response and reply to that message in Discord.
Listen To Some Hacker Music While You Code
Follow me on Spotify I make Tech Trap music
Package.json
Below is an example of how you might want your package.json file to look like.
{
"name": "discord-gpt-bot",
"version": "1.1.0",
"description": "Add ChatGPT to your Discord server. Responds with a ChatGPT generated text when @.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/mastashake08/discord-gpt-bot.git"
},
"keywords": [
"OpenAI",
"ChatGPT",
"gpt",
"discord",
"bots",
"discord"
],
"author": "Mastashake08",
"license": "GPL3",
"bugs": {
"url": "https://github.com/mastashake08/discord-gpt-bot/issues"
},
"homepage": "https://github.com/mastashake08/discord-gpt-bot#readme",
"dependencies": {
"discord.js": "^14.7.1",
"dotenv": "^16.0.3",
"openai": "^3.2.1"
}
}
Index File
This is where most of the magic happens, the index.js file loads our slash commands starts OpenAI, and starts the Discord.js instance. All secret keys and tokens are loaded using the dotenv package from a .env file. The generate
function makes a call to the OpenAI.createCompletion()
function which returns our text completion.
require('dotenv').config()
const { Client, Events, Collection, REST, Routes } = require('discord.js');
const fs = require('node:fs');
const path = require('node:path');
const { Configuration, OpenAIApi } = require("openai")
const client = new Client({ intents: 2048 })
client.commands = new Collection()
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
async function generate(prompt, model="gpt-3.5-turbo") {
const completion = await openai.createCompletion({
model: model,
prompt: prompt
});
const text = completion.data.choices[0].text
return text;
}
// start the discord client and listen for messages
const commandsPath = path.join(__dirname, 'commands');
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
const commands = []
// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
commands.push(command.data.toJSON());
}
// Construct and prepare an instance of the REST module
const rest = new REST({ version: '10' }).setToken(process.env.DISCORD_TOKEN);
// and deploy your commands!
(async () => {
try {
console.log(`Started refreshing ${commands.length} application (/) commands.`);
// The put method is used to fully refresh all commands in the guild with the current set
const data = await rest.put(
Routes.applicationGuildCommands(process.env.DISCORD_CLIENT_ID, process.env.DISCORD_GUILD_ID),
{ body: commands },
);
console.log(`Successfully reloaded ${data.length} application (/) commands.`);
} catch (error) {
// And of course, make sure you catch and log any errors!
console.error(error);
}
})();
client.login(process.env.DISCORD_TOKEN)
client.on(Events.InteractionCreate, async interaction => {
if (interaction.commandName === 'generate-prompt') {
const res = await generate(interaction.options.getString('prompt'))
await interaction.reply({ content: res });
}
});
Commands
I created a commands
directory and inside created a prompt.js
file. This file is responsible for using the SlashCommandBuilder
class from DIscord.js to create our command and options.
require('dotenv').config()
const { Configuration, OpenAIApi } = require("openai")
const { SlashCommandBuilder } = require('discord.js');
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
async function generate(prompt, model="gpt-3.5-turbo") {
const completion = await openai.createCompletion({
model: model,
prompt: prompt
});
const text = completion.data.choices[0].text
return text;
}
module.exports = {
data: new SlashCommandBuilder()
.setName('generate-prompt')
.setDescription('Generate a ChatGPT reponse!')
.addStringOption(option =>
option
.setName('prompt')
.setDescription('The prompt to generate')
.setRequired(true)
),
async execute(interaction) {
const res = await generate(interaction.options.getString('prompt'))
await interaction.reply(res);
},
};
Dockerfile
I created a Dockerfile so that anyone can run this application without having to build from source. It creates a node 16 image, copies the code files over, runs npm install
, then runs the command. By passing in an --env-file
flag to the docker run
command will pass in a .env file to the script.
# syntax=docker/dockerfile:1
FROM node:16.15.0
ENV NODE_ENV=production
WORKDIR /
COPY ["package.json", "package-lock.json*", "./"]
RUN npm install --production
COPY . .
CMD [ "node", "index.js" ]
GitHub Actions
Automating the build process is the final part of the project. Whenever I release a new tagged version of the code, the GitHub action packages the Docker Image and publishes it to Docker Hub as well as Github Container Registry. From there I either run the docker image locally on my Raspberry Pi or I will run it in the cloud.
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# GitHub recommends pinning actions to a commit SHA.
# To get a newer version, you will need to update the SHA.
# You can also reference a tag or branch, but the action may change without warning.
name: Publish Docker image to Docker Hub
on:
release:
types: [published]
jobs:
push_to_registry:
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v3
- name: Log in to Docker Hub
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ github.repository }}
- name: Build and push Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# GitHub recommends pinning actions to a commit SHA.
# To get a newer version, you will need to update the SHA.
# You can also reference a tag or branch, but the action may change without warning.
name: Create and publish a Docker image to Github Packages
on:
release:
types: [published]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Usage
Via Node
cp .env.example .env
# Set variables
DISCORD_TOKEN=
DISCORD_CHANNEL_ID=
DISCORD_CLIENT_ID=
DISCORD_GUILD_ID=
OPENAI_API_KEY=
# Call program
node index.js
Via Docker
docker run --env-file=<PATH TO .ENV> -d --name=<NAME> mastashake08/discord-gpt-bot:latest
Follow Me On Social Media
Hackin’ on yo mainframe
mastashake08
Jyrone Parker is an American software engineer and entrepreneur from Louisville, KY. He is the owner and CEO of J Computer Solutions LLC, a full-scale IT agency that deals with hardware, networking, and software development. He is also a tech rapper and producer that goes by the name Mastashake.
Follow Me On Youtube!
Follow my YouTube account
Join The Newsletter
By joining the newsletter, you get first access to all of my blogs, events, and other brand-related content delivered directly to your inbox. It’s 100% free and you can opt out at any time!
Name(required)
Email(required)
By submitting your information, you're giving us permission to email you. You may unsubscribe at any time.
Like this:
Recommend
-
88
Introduction In this tutorial, we will walk through the process of creating a bot in JavaScript. We will start by creating a Discord server, creating a bot account, and inviting it to the server. Then we will d...
-
72
discord-py-slash-command Simple Discord Slash Command extension for discord.py. Example Normal usage: import discord from discord.ext import commands fr...
-
16
Hello all, Today, I will demonstrate how to create a discord bot using typescript and manage it easily with discordx. I will show you the fastest way to setup your bot in this post,...
-
1
Create a basic Discord bot in F# 30 Oct 2021 I have been using Discord a lot lately, mainly because I needed a space to meet for role-playing games remotely during the Black Plague. One nice perk of Discord is its support for bot...
-
5
TechPro424 Posted on Dec 22...
-
2
Slow slash commands - display text entered by user? advertisements I'm working with the slack
-
29
discord.py 2.0a slash command info and examples Slash Commands and you...
-
1
Mastering GitHub (5 Part Series) Wait, what? Slash commands are available...
-
11
Building your first Discord ChatGPT Bot@0xinhua 发布于 2023年05月18日What we'll be building In this tutorial, we will guide you through building your initial Discord app using JavaScri...
-
4
Streamlining Your Workflow as a Student ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK