# Create a discord bot with Model API

## Introduction

This tutorial guides you through the process of creating a Discord bot powered by the FLockRAG model. The bot can respond intelligently to user queries and automate tasks within the server.&#x20;

### What You Will Learn

* Learn how to create a chatbot on FLock’s AI Co-Creation platform
* How to create a simple chat bot on discord
* Link up the chat bot with AI endpoint to create a AI-driven Chatbot.

### Technology Stack

* JavaScript

## How it Works

Before we get into the actual development, lets first run down through the function requirement

* We want to interact with the bot using slash comments.
  * The command should include a `prompt` parameter for the bot.
* The new chat should take place in a private thread.
* All chats should only be visible to the caller user.

There will be three sections we will cover in this tutorial

* Setup Discord bot from discord developer portal
* Setup your RAG bot from AI Co-Creation platform
* Create a Discord bot with Discord.js
* Test and run the Discord bot from local environment.

### **Creating Your Bot on Discord**

* Go to Discord's [Developer Portal](https://discord.com/developers/applications) and log in with your Discord account.
* Click on the "New Application" button and give it a name, which will also be the name of your bot.
  * On this page, you will find the **APPLICATION ID** and **PUBLIC KEY**.
* In the left-hand side menu, click on the "Bot" tab. Here, you will find your **bot token**.
  * Remember, the bot token is sensitive and should never be shared. You will use this token to log your bot in.

### AI Co-Creation Setup

To create a bot from AI Co-Creation platform

* First visit <https://beta.flock.io>
* Click on the **Create my Model**
* Follow the requirement, and fill in all the details.

### Bot Creation

#### **Step 1: Setting Up Your Project**

```bash
mkdir flock-io
cd flock-io
npm init -y
```

These lines helps us to create directory, change to the created directory and setup `package.json`

#### Step 2. Install package

```bash
npm install discordjs dotenv axios
```

This help us to install all the required package

* `discordjs`
* `dotenv`
* `axios`

#### Step 3. Build the bot

> Our tutorial is based on [DiscordJS guide](https://discordjs.guide/#before-you-begin)

Refer to our previous requirements, we want this bot to achieve:

* Allow a `chatbot` slash command
* React to slash command with prompt

Create an `index.js` file, where we will write our bots’s code. Then, set up your Client as follow:

```jsx
import { Client } from "discord.js";

const client = new Client({
  intents: ["Guilds", "GuildMessages", "GuildMembers", "MessageContent"],
});

client.on("ready", () => {
  console.log(`${client.user.tag} has logged in.`);
});

client.login(process.env.DISCORD_TOKEN);
```

Then we add the slash command

#### Step 4. Adding a Slash Command

To interact with the Discord API and create slash commands, you'll need to use Discord's application commands API. Here, I'll show you how to register a **`chatbot`** command and respond to it.

1. **Register the Command**: Commands can be registered globally or to a specific guild for testing. For simplicity, we'll register a global command, which might take up to an hour to propagate.
2. **Responding to Commands**: Modify your bot to listen for interactions and respond to the **`chatbot`** command.

Further explanation to command variable

* `setName` - set the name for this command
* `setDescription` - set the description for this command
* `addStringOption` - add an option that accepts string input, in our case we want to gather the prompt text from user.

```jsx
const commands = [
  new SlashCommandBuilder()
    .setName("chatbot")
    .setDescription("Chat with the bot")
    .addStringOption((option) =>
      option
        .setName("prompt")
        .setDescription("Prompt for the chatbot")
        .setRequired(true)
    )
    .toJSON(),
];

const rest = new REST().setToken(process.env.DISCORD_TOKEN);

(async () => {
  try {
    console.log(
      `Started refreshing ${commands.length} application (/) commands.`
    );

    const data = await rest.put(
      Routes.applicationGuildCommands(process.env.APP_ID, process.env.GUILD_ID),
      { body: commands }
    );

    console.log(
      `Successfully reloaded ${data.length} application (/) commands.`
    );
  } catch (error) {
    console.error(error);
  }
})();
```

#### Step 5. Handle the command

Within `Discordjs` , they provided a status called `interactionCreate` where we sets up an event listener that waits for an interaction to occur.

```jsx
client.on("interactionCreate", async (interaction) => {
  // Code to handle the interaction goes here
});
```

Next we check few conditions

* Has user inputed command
* If user inputed command, is the command name equal to chatbot.

```jsx
if (!interaction.isChatInputCommand()) return;

if (interaction.commandName === "chatbot") {
  // Proceed to handle the `chatbot` command
}
```

Recapping on the requirement

* Create a thread upon user’s command.

But in Discord there is an issue if we set the reply as ephemeral(private) the API will not be able to pick it up.

Therefore our execution flow should be: User interact → Discord sends out a helper text(Public) → use this helper text as the thread starting node → Create a private thread

#### **Step 6. Sending a Preliminary Reply**

* Inside the command check, it first sends a reply to the interaction with a message indicating that a personal thread is being prepared: **`const message = await interaction.reply({ ... });`**.
  * **`fetchReply: true`** tells Discord to return the sent message as a **`Message`** object.
  * **`ephemeral: false`** specifies that the message should be visible to everyone, not just the user who invoked the command. This is necessary because the bot intends to start a thread based on this message.

```jsx
const message = await interaction.reply({
  content: "Preparing your personal thread...",
  fetchReply: true,
  ephemeral: false
});
```

#### **Step 7. Starting a Thread**

* Then we start a thread from the reply message: **`const thread = await message.startThread({ ... });`**. Adding `PrivateThread` to ensure thread is only visible to command caller.

```jsx
// Starting a thread from the bot's message
const thread = await message.startThread({
	name: prompt,
	autoArchiveDuration: 60,
	type: ChannelType.PrivateThread,
	reason: "Needed a separate thread for User Prompt",
});
```

#### **Step 8. Sending a Message to the Thread**

* After creating the thread, the bot gets ready to send a message to it. There are discussions about sending a basic greeting message directly or using a function called **`main(prompt)`** you can check the [Model API guide](https://docs.flock.io/flock-products/ai-marketplace/quickstart/model-api-guide), to generate a response based on the user's prompt and then send that response to the thread.

```jsx
// Send a message to the thread using the flock-api.js file
const response = await main(prompt);
thread.send(response.answer);

// Option
await interaction.followUp({
  content: `Your personal thread ${prompt} is ready!`,
  ephemeral: true,
});
```

```jsx
client.on("interactionCreate", async (interaction) => {
  if (!interaction.isChatInputCommand()) return;

  if (interaction.commandName === "chatbot") {
    // Reply with a non-ephemeral message
    const message = await interaction.reply({
      content: "Preparing your personal thread...",
      fetchReply: true,
      ephemeral: false, // This message needs to be non-ephemeral to start a thread
    });

    // Get the prompt from the user
    const prompt = interaction.options.getString("prompt");
    const user = interaction.user;
    console.log(user);

    // Starting a thread from the bot's message
    const thread = await message.startThread({
      name: prompt,
      autoArchiveDuration: 60,
      type: ChannelType.PrivateThread,
      reason: "Needed a separate thread for User Prompt",
    });
 
    // Send a message to the thread using the flock-api.js file
    const response = await main(prompt);
    thread.send(response.answer);

		// Option
    await interaction.followUp({
      content: `Your personal thread ${prompt} is ready!`,
      ephemeral: true,
    });
  }
});
```

#### Step 9: Deployment and Testing in a Local Environment

To deploy the application locally:

1. **Update the `package.json` File**: Insert the following code snippet into your `package.json` file under the `scripts` section:

   ```json
   "scripts": {
       "start": "node index.js"
   }

   ```
2. **Launch the Application**: Execute the command below in your terminal:

   ```bash
   npm run start

   ```
3. **Verify the Output**: Upon successful execution, you should observe an output similar to the following:

   ```
   > discord-flock@1.0.0 start
   > node index.js

   Started refreshing 1 application (/) commands.
   Successfully reloaded 1 application (/) commands.
   FLockbot_tim_test#6051 has logged in.

   ```

   These log messages indicate that your bot is now operational and running in your local environment.

Next we need to add the bot to a server.

* You can add the bot using this URL

```
<https://discord.com/api/oauth2/authorize?client_id=><**APPLICATION ID**>&permissions=0&scope=bot%20applications.commands
```

* In your server you can type in following command
