Create Your Own AI Discord Bot with Julep

ayush2390

Ayush Thakur

Posted on August 4, 2024

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

A new DSL and server for AI agents and multi-step tasks

English | 中文翻译 | 日本語翻訳 | French

julep


Explore Docs · Discord · 𝕏 · LinkedIn

NPM Version   PyPI - Version   Docker Image Version   GitHub License


Note

👨‍💻 Here for the devfest.ai event ? Join our Discord and check out the details below.

Get your API key here.

🌟 Contributors and DevFest.AI Participants (Click to expand)

🌟 Call for Contributors!

We're excited to welcome new contributors to the Julep project! We've created several "good first issues" to help you get started. Here's how you can contribute:

  1. Check out our CONTRIBUTING.md file for guidelines on how to contribute.
  2. Browse our good first issues to find a task that interests you.
  3. If you have any questions or need help, don't hesitate to reach out on our Discord channel.

Your contributions, big or small, are valuable to us. Let's build something amazing together! 🚀

🎉 DevFest.AI October 2024

Exciting news! We're participating in DevFest.AI throughout October 2024! 🗓️

  • Contribute to Julep during this…

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

A new DSL and server for AI agents and multi-step tasks

English | 中文翻译 | 日本語翻訳 | French

julep


Explore Docs · Discord · 𝕏 · LinkedIn

NPM Version   PyPI - Version   Docker Image Version   GitHub License


Note

👨‍💻 Here for the devfest.ai event ? Join our Discord and check out the details below.

Get your API key here.

🌟 Contributors and DevFest.AI Participants (Click to expand)

🌟 Call for Contributors!

We're excited to welcome new contributors to the Julep project! We've created several "good first issues" to help you get started. Here's how you can contribute:

  1. Check out our CONTRIBUTING.md file for guidelines on how to contribute.
  2. Browse our good first issues to find a task that interests you.
  3. If you have any questions or need help, don't hesitate to reach out on our Discord channel.

Your contributions, big or small, are valuable to us. Let's build something amazing together! 🚀

🎉 DevFest.AI October 2024

Exciting news! We're participating in DevFest.AI throughout October 2024! 🗓️

  • Contribute to Julep during this…




Check out the tutorial for a deeper understanding of Julep.

Have any questions or feedback? Join the Julep Discord Community

💖 💪 🙅 🚩
ayush2390
Ayush Thakur

Posted on August 4, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related