Building a Discord Bot Using Open AI and python

Building a Discord Bot Using Open AI and python

Discord

Discord is a versatile communication platform initially designed for gamers but has since expanded its appeal to a broader range of online communities and groups. It offers a rich set of features aimed at fostering interaction and building communities through text, voice, and video communication.

Key Features of Discord:

  1. Servers and Channels:
    • Servers: Discord servers are like individual community centers where groups of people can gather to communicate and share content. Each server can be subdivided into multiple channels.
    • Channels: These are specific areas within a server designated for particular topics or types of interaction. Channels can be text-based or voice-based, and server administrators can create multiple channels to organize discussions effectively.
  2. Voice and Video Communication:
    • Users can join voice channels where they can speak with others using their microphone, share their screen, or even video chat. This feature is particularly popular among gamers for coordinating in-game activities but is also used for virtual meetings, live classes, and casual voice chats.
  3. Text Messaging:
    • Text channels allow users to communicate via typed messages. These channels support rich text formatting, direct messages, mentions, and embedded media (images, videos, and links).
  4. Integration and Bots:
    • Discord supports integration with other services like Spotify, Twitch, and many gaming services, enhancing the user experience by allowing activities like streaming music, sharing game stats, or broadcasting live gameplay.
    • Bots are another powerful feature of Discord, which can automate tasks, manage server activities, or even add fun interactive elements for users.
  5. Roles and Permissions:
    • Discord allows extensive customization of user roles and permissions within a server. Administrators can assign roles with specific permissions that control who can access certain channels, modify server settings, or manage other users.
  6. Security and Privacy:
    • Discord provides robust privacy controls and security features, including two-factor authentication, moderation tools, and the ability to control who can send direct messages or add you as a friend.
  7. Cross-platform Use:
    • Discord is accessible via desktop apps for Windows, macOS, and Linux, mobile apps for Android and iOS, and can also be run directly in web browsers, making it widely accessible.

OpenAI

OpenAI is an artificial intelligence research organization that aims to promote and develop friendly AI in such a way as to benefit humanity as a whole. Founded in December 2015 by Elon Musk, Sam Altman, and others, OpenAI initially started as a non-profit entity but later formed a capped-profit arm to attract outside investment.

Key aspects of OpenAI include:

  • Research and Development: OpenAI conducts cutting-edge research in AI and machine learning, with a focus on developing advanced AI technologies and capabilities.
  • Safety and Ethics: A core part of OpenAI’s mission is to ensure AI technologies are developed safely and ethically, with the potential risks managed responsibly.
  • GPT Models: OpenAI is well-known for its Generative Pre-trained Transformer (GPT) models, which are capable of a wide range of natural language processing tasks.
  • Collaboration and Licensing: OpenAI collaborates with various organizations and companies and offers commercial versions of its AI models, such as GPT-3, through API services.

Replit

Replit (formerly Repl.it) is an online integrated development environment (IDE) that allows users to write, run, and share code online. It's a powerful tool for developers, educators, and students alike, designed to make coding more accessible and collaborative. Replit supports a wide range of programming languages, including Python, JavaScript, Ruby, C++, and many others.

Key Features of Replit:

  1. Instant IDE Setup:
    • Zero Installation: Replit runs entirely in the browser, eliminating the need to install software or manage dependencies on your local machine.
    • Support for Many Languages: Replit supports over 50 programming languages, allowing you to switch between projects and languages without any additional setup.
  2. Collaborative Coding:
    • Real-time Collaboration: Similar to Google Docs, Replit allows multiple users to code simultaneously in the same environment. This feature is particularly useful for pair programming, teaching, or collaborative problem-solving.
    • Multiplayer Mode: This mode enables real-time collaboration with other users, including a chat feature to discuss the code directly within the IDE.
  3. Hosting and Deployment:
    • Instant Deployment: Replit provides hosting services, which means you can develop and deploy web applications directly from the platform. It generates a live, public URL for each project.
    • Always-on Repls: For paid users, Replit offers the ability to keep applications always running, even when you close the browser, which is great for bots, web apps, and other continuous services.
  4. Version Control:
    • Built-in Git Support: Replit integrates Git, allowing users to push and pull from any external Git repository. This integration facilitates version control and code sharing via platforms like GitHub.
  5. Educational Tools:
    • Classroom Management: Educators can manage coding assignments, provide feedback, and monitor student progress directly within Replit. It's widely used in educational settings due to its ease of use and minimal setup.
    • Templates and Examples: Replit offers a range of templates and example projects that can help users get started with new languages or frameworks quickly.
  6. Nix Environment:
    • Customizable Environments: Advanced users can customize their coding environment using Nix, a powerful package management tool. This feature allows developers to define precise project environments that include specific system dependencies.
  7. Integrated Database Support:
    • Built-in Database: Replit includes a built-in database feature for simple key-value storage, which is useful for applications that need to persist data without setting up an external database.

Best Uses of Replit:

  • Rapid Prototyping: Quickly prototype apps without worrying about environment setup.
  • Learning and Education: Ideal for classrooms and self-learning, thanks to its accessibility and ease of use.
  • Technical Interviews: Conduct coding interviews and assessments easily with shared sessions.
  • *Hackathons**: Start projects quickly during hackathons without losing time on setup.

Demo

Side Note:

Async & await

In Python, `async` and `await` are keywords used to define and handle asynchronous code, which is code that allows you to perform long-running operations without blocking the execution of your program. This is particularly useful for I/O-bound and network-bound tasks, like making network requests, reading or writing to files, etc., where the program spends most of its time waiting for external events.

Here’s a detailed explanation of both keywords and how they work in Python:

  • The `async` Keyword
  1. Defining Asynchronous Functions: The `async` keyword is used to declare a function as an "asynchronous function." This means the function is non-blocking and returns an `awaitable` object, specifically an `asyncio.Future` object. An async function is defined using the syntax `async def`:
async def fetch_data():
    # function body

By declaring a function with `async def`, you're telling Python that this function can perform asynchronous operations and can be paused and resumed.

  • The `await` Keyword
  1. Pausing and Resuming Execution: The `await` keyword is used within an asynchronous function to pause the execution of the function until the `awaitable` object (like those returned by other async functions) is resolved. This lets the function wait for a result to become available while letting other tasks run in the meantime.
async def fetch_data():
    data = await some_async_function()
    return data

In this example, `some_async_function()` is another asynchronous function, and `await` pauses `fetch_data()` until `some_async_function()` finishes its task and returns some data.

  • How `async` and `await` Work Together
  • Concurrency: Together, `async` and `await` provide a way to write concurrent code in Python. By using these keywords, you can keep your application responsive by allowing Python to handle other tasks while waiting for I/O operations to complete. This is not parallel execution but concurrent execution (via cooperative multitasking).
  • Event Loop: The core concept behind `async` and `await` is the event loop, which is provided by the `asyncio` library in Python. The event loop manages and distributes the execution of different tasks. It keeps track of all the running tasks and resumes the functions paused by `await` as soon as their awaited operations are complete.

Example Usage

Here’s a simple example using `asyncio` to perform a task asynchronously:

import asyncio

async def main():
    print("Hello")
    await asyncio.sleep(1)  # Asynchronous sleep, doesn't block the event loop
    print("world")

# Running the asynchronous main function
asyncio.run(main())

Practical Applications

  • Web Development: In web servers and web applications, `async` and `await` allow handling multiple web requests concurrently. This makes handling high load and performing multiple network requests efficient.
  • Data Gathering: They are useful in scenarios where data needs to be gathered from multiple sources over the internet, such as APIs or databases, without waiting for each task to complete sequentially.

Step0 Hello Bot!

  • Step 1: Install discord.py First, you need to install the discord.py library. You can use Rye as package manager
  • Step 2: Set Up Your Discord Bot Go to the Discord Developer Portal (https://discord.com/developers/applications). Create a new application and give it a name. Go to the Bot tab and click "Add Bot". Copy the token that is generated. You will need this token to run your bot.
  • Step 3: Write the Python Script Create a Python script that uses the bot token to log in and respond to messages. Below is a basic example of a bot that responds to simple commands:

Environment variables

import discord
import os
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

intents = discord.Intents.default()
intents.messages = True

client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print(f'Logged in as {client.user}')

@c*lient.event
async def on_message(message):
    # do not let the bot respond to itself
    if message.author == client.user:
        return

    elif message.content.startswith('!hello'):
        await message.channel.send('Hello!')

    elif message.content.startswith('hi'):
        await message.channel.send('welcome!')

    elif message.content.startswith('what is the best meetup up there?'):
        await message.channel.send('The Ubuntu Tech Hive :)')

    elif message.content.startswith('!bye'):
        await message.channel.send('Goodbye!')

    else:
        await message.channel.send("I did not understand your request!!")


client.run(os.environ["DISCORD_TOKEN"])import math  # importing the math library

What was used:

  • dotenv api
  • Disord token
  • Discord api bot
  • Python3

Limitations

  • Bot cannot engage.
  • Only respond to specific prompt based on condition
  • Not very useful

Step1 Let's make the bot more useful

Tools Needed: OpenAi api dotenv api Disord token Python3

import discord
import my_openai
import os
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

intents = discord.Intents.default()
intents.messages = True

client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print(f'Logged in as {client.user}')

@client.event
async def on_message(message):
    # do not let the bot respond to itself
    if message.author == client.user:
        return

    if message.content.startswith('$hello'):
        await message.channel.send('Hello, how can I help?')

# Check if the message starts with a question keyword
    if message.content.startswith('!ask'):
        # Remove the command part and strip leading/trailing whitespace
        user_question = message.content[len('!ask'):].strip()

        if user_question:

            try:
                response = my_openai.generate_answer(message.content)
                await message.channel.send("Hang Tight! Looking for the response...")
                await message.channel.send(response)

            except Exception as e:
                await message.channel.send(f"Error processing your request: {str(e)}")
        else:
            await message.channel.send("Please provide a question after !ask")


    if message.content.startswith('$question'):
        response = my_openai.generate_answer(message.content)
        await message.channel.send("looking for response")
        await message.channel.send(response)

# Replace 'your_token_here' with your bot's actual token
client.run(os.environ["DISCORD_TOKEN"])
from openai import OpenAI
import os

# Set up your OpenAI API credentials
client = OpenAI(
    # This is the default and can be omitted
    api_key=os.environ["OPENAI_TOKEN"],
)


MODEL = "gpt-3.5-turbo"
# Define the function to generate answers
def generate_answer(question):
    response = client.chat.completions.create(
        model=MODEL,
        messages=[
            {"role": "system", "content": "You are a helpful assistant in a discord server answering question and being helpful."},
            {"role": "user", "content": question},
        ],
        temperature=0,
    )

    return response.choices[0].message.content

Limitations

  • Bot is still local
  • Not useful for our ubuntu or anyone else
  • Not state to save

What was used:

  • dotenv api
  • Disord token
  • Discord api bot
  • Python3
  • openai api key

Step2 Let's deploy, Introducing Replit

import discord
import my_openai
import os
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

intents = discord.Intents.default()
intents.messages = True

client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print(f'Logged in as {client.user}')

@client.event
async def on_message(message):
    # do not let the bot respond to itself
    if message.author == client.user:
        return

    if message.content.startswith('$hello'):
        await message.channel.send('Hello, how can I help?')

# Check if the message starts with a question keyword
    if message.content.startswith('!ask'):
        # Remove the command part and strip leading/trailing whitespace
        user_question = message.content[len('!ask'):].strip()

        if user_question:

            try:
                response = my_openai.generate_answer(message.content)
                await message.channel.send("Hang Tight! Looking for the response...")
                await message.channel.send(response)

            except Exception as e:
                await message.channel.send(f"Error processing your request: {str(e)}")
        else:
            await message.channel.send("Please provide a question after !ask")


    if message.content.startswith('$question'):
        response = my_openai.generate_answer(message.content)
        await message.channel.send("looking for response")
        await message.channel.send(response)

# Replace 'your_token_here' with your bot's actual token
client.run(os.environ["DISCORD_TOKEN"])
from replit import db

# URLs and their corresponding custom keys
urls = {
    "deep-dive-into-rag-with-langchain": "https://dev.ubuntuhive.tech/en-us/articles/deep-dive-into-rag-with-langchain/",
    "exploring-new-chatgpt-features": "https://dev.ubuntuhive.tech/en-us/articles/exploring-new-chatgpt-features-/",
    "build-small-apps-with-llms": "https://dev.ubuntuhive.tech/en-us/articles/build-small-apps-with-llms/",
    "docker-orchestra-swarm-k8s-kubernetes-for-beginners": "https://dev.ubuntuhive.tech/en-us/articles/docker-orchestra-swarm-k8s-kubernetes-for-beginners/",
    "devops-from-scratch-automated-basics": "https://dev.ubuntuhive.tech/en-us/articles/devops-from-scratch-automated-basics/",
    "from-networks-to-http-and-apis": "https://dev.ubuntuhive.tech/en-us/articles/from-networks-to-http-and-apis/",
    "data-and-cloud-infrastructure-as-code": "https://dev.ubuntuhive.tech/en-us/articles/data-and-cloud-infrastructure-as-code/"
}

# Store in the database under the 'articles' key
db["articles"] = urls
from openai import OpenAI
import os



# Set up your OpenAI API credentials
# my_api_key = ''
client = OpenAI(
    # This is the default and can be omitted
    api_key=os.environ["OPENAI_TOKEN"],
)


MODEL = "gpt-3.5-turbo"
# Define the function to generate answers
def generate_answer(question):
# example with a system message
    response = client.chat.completions.create(
        model=MODEL,
        messages=[
            {"role": "system", "content": "You are a helpful assistant in a discord server answering question and being helpful."},
            {"role": "user", "content": question},
        ],
        temperature=0,
    )

    return response.choices[0].message.content

What was used:

  • dotenv api
  • Disord token
  • Discord api bot
  • Python3
  • openai api key
  • replit

Step3 Welcome New members

import discord
import my_openai as opai
import os
from discord.ext import commands
from replit import db
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

intents = discord.Intents.default()
intents.message_content = True
# Initialize the Discord bot
bot = commands.Bot(command_prefix='!',intents=intents)

@bot.event
async def on_ready():
    print(f'Logged in as {bot.user}!')

@bot.command(help="Ask the user what kind of summary they are looking for.")
async def choose_article(ctx):
    # Retrieve the articles from the Replit database
    articles = db["articles"]
    # Create a message with options
    options = "\n".join([f"Send {idx+1} for {key.replace('-', ' ').title()}" for idx, key in enumerate(articles.keys())])
    prompt = "Please choose from the below list:\n" + options
    await ctx.send(prompt)

    # Check function to validate the user's choice
    def check(m):
        return m.author == ctx.author and m.content.isdigit() and 1 <= int(m.content) <= len(articles)

    try:
        # Wait for user response
        msg = await bot.wait_for('message', check=check, timeout=60.0)  # 60 seconds to reply
        choice = int(msg.content) - 1
        selected_key = list(articles.keys())[choice]
        selected_article = articles[selected_key]
        # You can add additional functionality here to summarize the article
        await ctx.send(f"You selected: {selected_key.replace('-', ' ').title()}\nURL: {selected_article}")
        await ctx.send("Please wait while I get you the summary...")
        await ctx.send(opai.generate_summary(selected_article))

    except Exception as e:
        await ctx.send('No valid input received or timeout reached. Please try again.')

@bot.command(help="Sends a welcome message with useful resources.")
async def new_member(ctx):
    articles = db["articles"]
    most_recent_article_key = list(articles.keys())[-1]  # Getting the most recent article key
    most_recent_article_url = articles[most_recent_article_key]  # Getting the URL

    # Welcome message and resources
    welcome_message = (
        f"Welcome to the server, {ctx.author.mention}! 🎉 Here are some resources you might find helpful:\n"
        f"1. Check out our latest article: {most_recent_article_url}\n"
        f"2. Visit our Ubuntu Hive website for more insights: https://dev.ubuntuhive.tech/en-us/\n"
        f"3. Learn more about tech with this comprehensive tutorial: [Insert Your Tutorial Link Here]\n"
        f"4. Other misc resources and info: [Insert More Links or Info Here]\n"
    )

    await ctx.send(welcome_message)

# Run the bot
token = os.getenv("DISCORD_TOKEN")
if token:
  bot.run(token)
else:
  print("Error: Discord token not found in environment variables. Please ensure DISCORD_TOKEN is set.")
from replit import db

# URLs and their corresponding custom keys
urls = {
    "deep-dive-into-rag-with-langchain": "https://dev.ubuntuhive.tech/en-us/articles/deep-dive-into-rag-with-langchain/",
    "exploring-new-chatgpt-features": "https://dev.ubuntuhive.tech/en-us/articles/exploring-new-chatgpt-features-/",
    "build-small-apps-with-llms": "https://dev.ubuntuhive.tech/en-us/articles/build-small-apps-with-llms/",
    "docker-orchestra-swarm-k8s-kubernetes-for-beginners": "https://dev.ubuntuhive.tech/en-us/articles/docker-orchestra-swarm-k8s-kubernetes-for-beginners/",
    "devops-from-scratch-automated-basics": "https://dev.ubuntuhive.tech/en-us/articles/devops-from-scratch-automated-basics/",
    "from-networks-to-http-and-apis": "https://dev.ubuntuhive.tech/en-us/articles/from-networks-to-http-and-apis/",
    "data-and-cloud-infrastructure-as-code": "https://dev.ubuntuhive.tech/en-us/articles/data-and-cloud-infrastructure-as-code/"
}

# Store in the database under the 'articles' key
db["articles"] = urls
from openai import OpenAI
import os

# Set up your OpenAI API credentials
# my_api_key = ''
client = OpenAI(
    # This is the default and can be omitted
    api_key=os.environ["OPENAI_TOKEN"],
)


MODEL = "gpt-3.5-turbo"
# Define the function to generate answers
def generate_answer(question):
# example with a system message
    response = client.chat.completions.create(
        model=MODEL,
        messages=[
            {"role": "system", "content": "You are a helpful assistant in a discord server answering question and being helpful."},
            {"role": "user", "content": question},
        ],
        temperature=0,
    )

    return response.choices[0].message.content

def generate_summary(articles):
  response = client.chat.completions.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a helpful assistant in a discord server. You are great as providing summaries of text when given an article link. when prompted, provide a max of 200 words summary of the provided link"},
        {"role": "user", "content": articles},
    ],
    temperature=0,
  )

  return response.choices[0].message.content

Important Links

Join us on Discord

The Ubuntu TechHive on Discord

COME HANGOUT!
Join us on Discord