DEV Community

Cover image for Create Your Own AI Discord Bot with Julep
Ayush Thakur for Julep

Posted on

Create Your Own AI Discord Bot with Julep

Having a Discord bot for your server that interacts with users and resolves their queries on your behalf is incredibly useful. However, building such a bot can be extremely challenging and may take months due to the complexities involved in data preprocessing, model training, hyperparameter training, and deployment. This is where Julep comes in to save the day.

Julep is a platform that helps to build stateful and functional LLM-powered applications. Using Julep, you can create a fully operational AI application with minimal code.

While platforms such as OpenAI's GPT-3, Microsoft's Azure Bot Service, and Google's Dialogflow enable the development of AI applications, Julep distinguishes itself with unique benefits. Julep offers unique features like composio tools integration, adaptive context, multiple AI Agents support, and in-built RAG.

In this blog, we will create an AI Discord Bot using Julep and add it to a live Discord Server to try it. We will walk through each step and understand how you can use Julep in your projects.

Image description

Prerequisites

Make sure you have Node.js installed on your device. Download and install Node.js from their official website.

If you like the posts on the Julep blog so far, please consider please consider giving Julep a star on GitHub, it helps us to reach and help more developers.

GitHub logo julep-ai / julep

Open-source alternative to Assistant's API with a managed backend for memory, RAG, tools and tasks. ~Supabase for building AI agents.

English | 中文翻译

julep

💸🤑 Announcing our Bounty Program: Help the Julep community fix bugs and ship features and get paid. More details here.


Start your project with conversation history, support for any LLM, agentic workflows, integrations & more


Explore the docs »

Report Bug · Request Feature · Join Our Discord · X · LinkedIn

NPM Version   PyPI - Version   Docker Image Version   GitHub License


Why Julep?

We've built a lot of AI apps and understand how difficult it is to evaluate hundreds of tools, techniques, and models, and then make them work well together.

The Problems

  1. The barrier to making LLM apps with memory, knowledge & tools is too high.
  2. Agentic behaviour is hard to control when done through multi-agent frameworks.

Features

  • Statefulness By Design: Manages conversation history by default. Use simple flags; remember & recall to tune whether to save or retrieve conversation history.
  • Support for Users & Agents: Allows creating different user <-> agent…

Building Discord Bot

Create a project directory and open it in VS code. Run this command in the terminal:

npm init -y
Enter fullscreen mode Exit fullscreen mode

This will initialize a Nodejs project and create a package.json file with some default settings.

We will require some libraries to build our AI Discord bot. These libraries are:

  • dotenv - To retrieve the value stored in the .env file
  • julep SDK - To interact with a specific service or API provided by Julep
  • discord.js - To easily interact with the Discord API

To install these libraries, run this command:

npm i dotenv @julep/sdk discord.js
Enter fullscreen mode Exit fullscreen mode

Get Julep API Key

To use Julep in our project, we need an API Key.

Go to platform.julep.ai and Sign in with Google account credentials. Copy the YOUR API TOKEN present on the top-right corner.

Image description

This API Token will serve as your API key.

Create a .env file in your project directory and paste the following code:

JULEP_API_KEY = apiKey
Enter fullscreen mode Exit fullscreen mode

Replace the apikey with the copied API Token.

Get Discord Bot Token

To get the Discord Bot token, go to Discord Developer Portal and login with your credentials.

Click on New Application and give a name to your application.

Navigate to the Bot section on left-hand side and click on Reset Token and it will generate a token, copy it.

Image description

Open the .env file and paste the following code:

BOT_KEY = botToken
Enter fullscreen mode Exit fullscreen mode

Replace the botToken with the token you copied earlier.

Create the Bot

Now that we have the required API key and Bot Key, let’s start creating the bot.

Create a file in your project directory and name it index.js. Then, import the installed libraries into the file:

require("dotenv").config();
const { Client, GatewayIntentBits, Collection } = require("discord.js");
const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
  ],
});
const julep = require("@julep/sdk");
Enter fullscreen mode Exit fullscreen mode

Create a new Julep Client using julep.Client() method. This client interfaces with the Julep API and sets up the managers for agents, users, sessions, documents, memories, and tools.

const apiKey = process.env.JULEP_API_KEY;
const julepClient = new julep.Client({ apiKey });
Enter fullscreen mode Exit fullscreen mode

Add a log to display a message when the Discord client is ready. This will confirm that the Discord client has been successfully created.

client.once("ready", () => {
    console.log(`Logged in as ${client.user.tag}!`);
  });
Enter fullscreen mode Exit fullscreen mode

Now, we want to capture the message content each time the user enters a new message. For that, we will use the messageCreate action.

client.on("messageCreate", async (message) => {
Enter fullscreen mode Exit fullscreen mode

When a user sends a message in the channel, a message object is created. This message object contains every detail about the sent message. We will use this message object to capture some of those details.

Next step is to make sure that the user is not a bot and a human. For that we will check if bot property is present in message object or not:

if (message.author.bot) {
    return;
  }
Enter fullscreen mode Exit fullscreen mode

We want to show the Bot is typing…. animation to let the users know that the bot is replying to their query. For this we will use the sendTyping() function.

await message.channel.sendTyping();
Enter fullscreen mode Exit fullscreen mode

Now, let’s create users, agents, and sessions to perform the interaction with Julep API.

Creating User

A User object represents an entity, either a person or a system, that interacts with the application. Every AI application built with Julep supports multiple users, each able to interact with the Agent. Each user is unique, with their own identity and role.

It is not a necessary thing to define a User. Applications can function properly even in the absence of a User. However, it's a good idea to create a user profile for each person or system interacting with the Agent for better organization and tracking. Adding basic details about the user helps the application understand their behavior, allowing it to provide personalized results that match the user's preferences and needs.

Julep comes with a users.create() method which we can be used on the client to create a user. Creating a user demands 4 attributes:

  • Name - Name of the user
  • About - Small description of the user
  • Documents - Essential documents formatted as text tailored to the user's needs (Optional)
  • Metadata - Additional data beyond the ID that pertains to the user within the application (Optional)

Here’s an example:

const user = await client.users.create({
    name: "Sam",
    about: "Machine Learning Developer and AI Enthusiast",
    docs:[{"title": "AI Efficiency Report", "content": "...", "metadata": {"page": 1}}],  // Optional
    metadata:{"db_uuid": "1234"}, // Optional
  });
Enter fullscreen mode Exit fullscreen mode

Now, let’s create a user for our Discord bot. We will keep the name of the user dynamic to capture the name of each user interacting with the Discord bot.

const user = await julepClient.users.create({
    name: message.author.globalName,
    about: "A test user",
  });
Enter fullscreen mode Exit fullscreen mode

Here, we have created a user with the name assigned to globalName property and A test user as description.

Creating Agent

An Agent is a smart interface that connects the user and the application, managing interactions to improve the user experience. Agents are designed to handle user queries and provide customized results or suggestions.

Agents store all the settings and configurations for the LLM models you want to use in your AI application. This allows the application to perform specific tasks and meet individual user preferences.

Agents can be simple, like a chatbot, or more complex, like advanced AI assistants that understand natural language and perform complex tasks.

In Julep, you can create an agent using the agents.create() method. Creating an agent requires a set of attributes:

  • Name - Name of the agent
  • About - Small description of the agent (Optional)
  • Instructions - List of instructions for the agent to follow (Optional)
  • Tools - List of functions for agent to execute tasks (Optional)
  • Model Name - LLM Model that agent will use (Optional)
  • Settings - Configurations on LLM model (Optional)
  • Documents - Important documents in text format to be used by agent to improve the persona (Optional)
  • Metadata - Additional information apart from ID to identify the user or agent (Optional)

Here’s an example:

const agent = client.agents.create(
    (name = "Cody"),
    (about =
      "Cody is an AI powered code reviewer. It can review code, provide feedback, suggest improvements, and answer questions about code."),
    (instructions = [
      "On every new issue, Review the issue made in the code. Summarize the issue made in the code and add a comment",
      "Scrutinize the changes very deeply for potential bugs, errors, security vulnerabilities. Assume the worst case scenario and explain your reasoning for the same.",
    ]),
    (tools = [
      {
        type: "function",
        function: {
          name: "github_comment",
          description:
            "Posts a comment made on a GitHub Pull Request after every new commit. The tool will return a boolean value to indicate if the comment was successfully posted or not.",
          parameters: {
            type: "object",
            properties: {
              comment: {
                type: "string",
                description:
                  "The comment to be posted on the issue. It should be a summary of the changes made in the PR and the feedback on the same.",
              },
              pr_number: {
                type: "number",
                description:
                  "The issue number on which the comment is to be posted.",
              },
            },
            required: ["comment", "pr_number"],
          },
        },
      },
    ]),
    (model = "gpt-4"),
    (default_settings = {
      temperature: 0.7,
      top_p: 1,
      min_p: 0.01,
      presence_penalty: 0,
      frequency_penalty: 0,
      length_penalty: 1.0,
    }),
    (docs = [{ title: "API Reference", content: "...", metadata: { page: 1 } }]),
    (metadata = { db_uuid: "1234" })
  );
Enter fullscreen mode Exit fullscreen mode

Now, let’s create the agent for our Discord bot:

const agent = await julepClient.agents.create({
  name: "Jarvis an AI Assistant",
  model: "gpt-4-turbo",
});
Enter fullscreen mode Exit fullscreen mode

Here, we've used the gpt-4-turbo LLM model in this agent, but Julep supports various LLM models for creating AI applications. Check out the documentation for more information.

Creating Session

A Session is a period where users interact with the agent. It includes all the back-and-forth messaging and relevant details.

Sessions store all messages exchanged between the user and agent. This helps the AI understand the conversation better and provide more personalized answers.

To create a session, use the sessions.create() method. Here are the attributes it requires:

  • Agent ID - ID of the created agent
  • User ID - ID of the created user (Optional)
  • Situation - A prompt to describe the background of the interaction
  • Metadata - Additional information apart from IDs to identify the session (Optional)

Situation attribute is important in the session because it provides context for the interaction. This helps the agent understand the user's query better and give more personalized responses.

Here’s an example:

// Assuming 'client' is an object with a 'sessions' property containing a 'create' method
let session = client.sessions.create({
    agent_id: agent.id,
    user_id: user.id,
    situation: `
          You are James a Software Developer, public speaker & renowned educator.
          You are an educator who is qualified to train students, developers & entrepreneurs.
          About you:
          ...
          Important guidelines:
          ...
      `,
    metadata: { db_uuid: "1234" },
  });
Enter fullscreen mode Exit fullscreen mode

Let’s create a session for our Discord bot:

const situationPrompt =
"Your name is Jarvis and you are a Senior Software Engineer that has decades of experience in coding. You have worked with almost every programming language present there like C, C++, C#, JavaScript, TypeScript, Python, Swift, Ruby, Go, Rust, Blockchain, Solidity, etc. People comes to you and ask their questions related to coding. Users ask their doubts, queries, project ideas, questions, solutions and everything about related to coding. You help users with their coding related problems. But you are savage and sarcastic in nature. Therefore, you answer each question in a very sarcastic and savage manner. Sometimes you also roast users based upon the query they have asked. But no matter how sarcastic and savage you are, you do provide the answer user is looking for.";


const session = await julepClient.sessions.create({
agentId: agent.id,
userId: user.id,
situation: situationPrompt,
});
Enter fullscreen mode Exit fullscreen mode

Here, we have created the situationPrompt that has the whole situation/context for our Discord bot to perform the interaction. Then used this situationPrompt for situation attribute and specified other mandatory attributes to create a session.

Getting Message Response

Image description

After creating the user, agent, and session, we need to manage the interaction. We'll use the sessions.chat() method to handle the chat and get the response message.

This method requires two attributes to work: session.id and an object containing a messages array.

const chatParams = {
    messages: [
      {
        role: "user",
        name: message.author.globalName,
        content: message.content,
      },
    ],
    max_tokens: 1000,
  };
  const chatResponse = await julepClient.sessions.chat(session.id, chatParams);
  const responseMessage = chatResponse.response[0][0].content;
  const chunks = responseMessage.match(/[\s\S]{1,2000}/g);

  // Send each chunk as a separate message
  for (const chunk of chunks) {
    await message.channel.send(chunk);
  }
Enter fullscreen mode Exit fullscreen mode

Here, we have created the chatParams object that has a messages array. This array includes:

  • role - role of the message sender, “user”
  • name - name of the message sender, message.author.globalName
  • content - content of the message, message.content

Along with this, the chatParams also holds a max_tokens property with the value 1000, which represents the maximum number of tokens to generate in the chat completion.

Following that, the sessions.chat() method is called on the client with session.id and chatParams as arguments. The resultant object is stored in chatResponse.

The value of the content property is extracted from chatResponse and stored in responseMessage.

Then, the message stored in responseMessage is split into smaller groups of 2000 characters and stored in the chunks variable.

After this, a for-of loop is used on the chunks array to send each chunk as a message to the user using the channel.send() method.

Lastly, the client.login(token) is used to authenticate and connect a client (like a Discord bot) to a server using a specified token.

Here’s the full index.js code:

require("dotenv").config();
const { Client, GatewayIntentBits, Collection } = require("discord.js");
const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
  ],
});
const julep = require("@julep/sdk");

const apiKey = process.env.JULEP_API_KEY;
const julepClient = new julep.Client({ apiKey });

client.commands = new Collection();

const token = process.env.BOT_KEY;

client.once("ready", () => {
  console.log(`Logged in as ${client.user.tag}!`);
});

client.on("messageCreate", async (message) => {
  if (message.author.bot) {
    return;
  }
  await message.channel.sendTyping();
  const user = await julepClient.users.create({
    name: message.author.globalName,
    about: "A test user",
  });

  const agent = await julepClient.agents.create({
    name: "July an AI Assistant",
    model: "gpt-4-turbo",
  });

  const situationPrompt =
    "Your name is Jarvis and you are a Senior Software Engineer that has decades of experience in coding. You have worked with almost every programming language present there like C, C++, C#, JavaScript, TypeScript, Python, Swift, Ruby, Go, Rust, Blockchain, Solidity, etc. People comes to you and ask their questions related to coding. Users ask their doubts, queries, project ideas, questions, solutions and everything about related to coding. You help users with their coding related problems. But you are savage and sarcastic in nature. Therefore, you answer each question in a very sarcastic and savage manner. Sometimes you also roast users based upon the query they have asked. But no matter how sarcastic and savage you are, you do provide the answer user is looking for.";
  const session = await julepClient.sessions.create({
    agentId: agent.id,
    userId: user.id,
    situation: situationPrompt,
  });

  const chatParams = {
    messages: [
      {
        role: "user",
        name: message.author.globalName,
        content: message.content,
      },
    ],
    max_tokens: 1000,
  };
  const chatResponse = await julepClient.sessions.chat(session.id, chatParams);
  const responseMessage = chatResponse.response[0][0].content;
  const chunks = responseMessage.match(/[\s\S]{1,2000}/g);

  // Send each chunk as a separate message
  for (const chunk of chunks) {
    await message.channel.send(chunk);
  }
});

client.login(token);
Enter fullscreen mode Exit fullscreen mode

Congratulations your Discord Bot is successfully created.

Deploy the bot

The bot is completed, we will run it and try it.

To deploy the bot, run the command in the terminal:

node index.js
Enter fullscreen mode Exit fullscreen mode

If your bot starts running successfully, you should see this message in log window:

Logged in as botName#botTag
Enter fullscreen mode Exit fullscreen mode

with your Bot name and Bot tag in-place of botName and botTag.

Now, to try out the Discord bot, we need to add it in a Discord server.

Image description

Adding Bot to a Server

Go to the Discord Developer Portal and open your created Discord bot.

Navigate to the OAuth2 section on the left-hand side. Scroll down to the OAuth2 URL Generator and check the bot box.

Further down, under Bot Permissions, select the necessary permissions for your Discord bot, such as Send Messages, Read Message History, and Manage Messages.

A URL will be generated in the Generated URL section. Copy this URL and paste it into your web browser.

Select the desired server from the dropdown menu and click Authorize.

Your bot will now be added to the server.

Now you can try out your Discord bot, message him, and get his responses.

Here’s a live demo of the Discord bot:

Image description

Your Discord Bot is running successfully.

Project link - https://github.com/ayush2390/Jarvis-bot

Try out Jess, an AI Discord bot made using Julep, Click Here

Excited to see what more Julep offers? The journey starts with a single click. Visit the repository and give it a star:

GitHub logo julep-ai / julep

Open-source alternative to Assistant's API with a managed backend for memory, RAG, tools and tasks. ~Supabase for building AI agents.

English | 中文翻译

julep

💸🤑 Announcing our Bounty Program: Help the Julep community fix bugs and ship features and get paid. More details here.


Start your project with conversation history, support for any LLM, agentic workflows, integrations & more




Explore the docs »




Report Bug
·
Request Feature
·
Join Our Discord
·
X
·
LinkedIn

NPM Version   PyPI - Version   Docker Image Version   GitHub License


Why Julep?

We've built a lot of AI apps and understand how difficult it is to evaluate hundreds of tools, techniques, and models, and then make them work well together.

The Problems

  1. The barrier to making LLM apps with memory, knowledge & tools is too high.
  2. Agentic behaviour is hard to control when done through multi-agent frameworks.

Features

  • Statefulness By Design: Manages conversation history by default. Use simple flags; remember & recall to tune whether to save or retrieve conversation history.
  • Support for Users & Agents: Allows creating different user <-> agent…




Check out the tutorial for a deeper understanding of Julep.

Have any questions or feedback? Join the Julep Discord Community

Julep AI Community

Check out the Julep AI Community community on Discord - hang out with 220 other members and enjoy free voice and text chat.

favicon discord.com

Top comments (7)

Collapse
 
fabrikapp profile image
Fabrikapp

That's a very nice tool ! Thanks for your work, i'll try it !

Collapse
 
ayush2390 profile image
Ayush Thakur

Glad you like it. Do check out - git.new/julep

Collapse
 
devshefali profile image
Shefali

Very well detailed guide, Ayush!

Julep looks really nice. Thanks for sharing.

Collapse
 
ayush2390 profile image
Ayush Thakur

Glad you like it Shefali

Collapse
 
ritikaagrawal08 profile image
Ritika Agrawal

Interesting and a well-detailed article Ayush!

Julep looks quite nice and easy to use with your explanation!

Collapse
 
ayush2390 profile image
Ayush Thakur

Glad you like it Ritika

Collapse
 
ijindal1 profile image
ijindal1

Love Jarvis!!