Skip to content

Add Discord Bot Example using discord.py #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/examples/discord-py-bot/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.env.example
DISCORD_TOKEN="YOUR_DISCORD_BOT_TOKEN_HERE"
PERPLEXITY_API_KEY="YOUR_PPLX_API_KEY_HERE"
104 changes: 104 additions & 0 deletions docs/examples/discord-py-bot/README.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
title: Perplexity Discord Bot
description: A runnable discord.py bot that adds a /ask_perplexity command to your server, using the Sonar API for web-connected answers.
sidebar_position: 4
keywords: [discord, bot, discord.py, python, chatbot, perplexity, sonar api, command, slash command]
---

# Perplexity Discord Bot

A runnable `discord.py` application that adds a `/ask_perplexity` slash command to your Discord server, using Perplexity's Sonar API for real-time, web-connected answers.

## 🌟 Features

- **Direct Sonar API Integration**: Uses Perplexity's API for real-time, web-connected answers.
- **Slash Command Ready**: Implements a modern `/ask_perplexity` command that's easy to use.
- **Secure Configuration**: Uses environment variables (`.env`) for both Discord and Perplexity keys, keeping them safe.
- **Administrator Permissions**: Locked to server administrators by default for easy control over API usage.
- **Formatted Embeds**: Delivers answers in a clean, professional Discord embed.
- **Self-Contained Example**: Minimal, single-file code designed to be easy to run and understand.

## 📋 Prerequisites

- **Python 3.8+**
- **A Perplexity API Key**
- **A Discord Bot Token**

## 🚀 Installation & Setup

1. **Clone the Repository:** Fork and clone the `api-cookbook` repository to your local machine.

2. **Navigate to this Example:**
```bash
cd docs/examples/discord-py-bot/
```
3. **Install Dependencies:**
```bash
pip install -r requirements.txt
```
4. **Get Your Secret Keys:**
- **Perplexity API Key:** Get your key from the [Perplexity AI Account Settings](https://www.perplexity.ai/settings/api).
- **Discord Bot Token:**
1. Go to the [Discord Developer Portal](https://discord.com/developers/applications).
2. Click **"New Application"** and give it a name.
3. Go to the **"Bot"** tab and click **"Reset Token"** (or "Add Bot" first if needed).
4. Copy the token. This is your bot's password – keep it safe!

5. **Set Up Your Environment File:**
- Rename the `.env.example` file to `.env`.
- Open the `.env` file and add your secret keys:
```
DISCORD_TOKEN="YOUR_DISCORD_BOT_TOKEN_HERE"
PERPLEXITY_API_KEY="YOUR_PPLX_API_KEY_HERE"
```

## 🔧 Usage

### 1. Invite Your Bot to a Server

- In the Discord Developer Portal, go to "OAuth2" -> "URL Generator".
- Select the `bot` and `applications.commands` scopes.
- Under "Bot Permissions," select **Administrator**.
- Copy the generated URL, paste it into your browser, and invite the bot to your server.

### 2. Run the Bot Script

Simply execute the `bot.py` script from your terminal:
```bash
python bot.py
This will connect the bot to Discord and sync the /ask_perplexity command.
3. Use the Command in Discord
In any channel in your server, an administrator can type:
code
Code
/ask_perplexity prompt:What is the latest news in the world of generative AI?
📄 Output Example
The bot will defer the interaction and then respond with a formatted embed containing the answer:
code
Code
HatchMate [APP]
🌐 Perplexity's Response

The latest news in generative AI includes advancements in large language models... (and so on).

Your Prompt```
What is the latest news in the world of generative AI?
Requested by YourUsername
code
Code
## 🛠️ Extending the Bot

- **Role-Based Access**: Modify the permission checks to allow specific roles, not just administrators.
- **Model Selection**: Add an option to the slash command to choose between different models like `sonar-pro` or `sonar-small-online`.
- **Conversation History**: Implement a database (like SQLite or Redis) to store recent messages and send them with new prompts for conversational context.

## ⚠️ Limitations

- The permission system is basic (administrator-only) to keep the example simple and database-free.
- The command is single-turn and does not remember conversation history.
- API rate limits may apply based on your Perplexity account status.

## 🙏 Acknowledgements

- This project uses the [Perplexity AI API](https://docs.perplexity.ai/).
- Built with the [discord.py](https://discordpy.readthedocs.io/en/stable/) library.
119 changes: 119 additions & 0 deletions docs/examples/discord-py-bot/bot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# This code is a simplified example of a Discord bot that integrates with the Perplexity AI API. This is a complete, minimal bot script that someone can run directly. Notice I have simplified the permission logic to only check for administrators to remove the need for an external database, making the example much more focused on the Perplexity API.

# bot.py
import os
import discord
from discord.ext import commands
from discord import app_commands
import openai
from dotenv import load_dotenv

# --- Step 1: Load Environment Variables ---
# This ensures your secret keys are kept safe in a .env file.
load_dotenv()
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
PERPLEXITY_API_KEY = os.getenv("PERPLEXITY_API_KEY")

# --- Step 2: Bot Setup ---
# We define the bot's intents, which tell Discord what events our bot needs to receive.
intents = discord.Intents.default()
bot = commands.Bot(command_prefix="!", intents=intents)

# --- Step 3: Create a Command Cog ---
# Cogs are how modern discord.py bots organize commands, listeners, and state.
class AIChatCog(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot

# Initialize the Perplexity AI Client using the key from our .env file.
# The `base_url` is the crucial part that directs the OpenAI library to Perplexity's API.
if PERPLEXITY_API_KEY:
self.perplexity_client = openai.OpenAI(
api_key=PERPLEXITY_API_KEY,
base_url="https://api.perplexity.ai"
)
print("Perplexity AI Client Initialized.")
else:
self.perplexity_client = None
print("CRITICAL: PERPLEXITY_API_KEY not found in .env file.")

# Define the slash command.
# The `has_permissions` check restricts this command to server administrators.
@app_commands.command(name="ask_perplexity", description="Ask a question to Perplexity AI (with web access).")
@app_commands.describe(prompt="The question you want to ask.")
@app_commands.checks.has_permissions(administrator=True)
async def ask_perplexity(self, interaction: discord.Interaction, prompt: str):
if not self.perplexity_client:
return await interaction.response.send_message(
"The Perplexity AI service is not configured on this bot.",
ephemeral=True
)

# Defer the response to give the API time to process without a timeout.
await interaction.response.defer(thinking=True)

try:
# Create the list of messages for the API call, following the standard format.
messages = [{"role": "user", "content": prompt}]

# Call the Perplexity API with the desired model.
response = self.perplexity_client.chat.completions.create(
model="sonar-pro",
messages=messages
)

answer = response.choices[0].message.content

# Create and send a nicely formatted Discord embed for the response.
embed = discord.Embed(
title="🌐 Perplexity's Response",
description=answer,
color=discord.Color.from_rgb(0, 255, 0) # Perplexity Green
)
embed.set_footer(text=f"Requested by {interaction.user.display_name}")

# Truncate the original prompt if it's too long to fit in an embed field.
truncated_prompt = (prompt[:1020] + '...') if len(prompt) > 1024 else prompt
embed.add_field(name="Your Prompt", value=f"```{truncated_prompt}```", inline=False)

await interaction.followup.send(embed=embed)

except Exception as e:
# Inform the user if an error occurs.
error_message = f"An error occurred with the Perplexity API: {e}"
print(error_message)
await interaction.followup.send(error_message, ephemeral=True)

# A local error handler specifically for this command's permission check.
@ask_perplexity.error
async def on_ask_perplexity_error(self, interaction: discord.Interaction, error: app_commands.AppCommandError):
if isinstance(error, app_commands.MissingPermissions):
await interaction.response.send_message("You must be an administrator to use this command.", ephemeral=True)
else:
# For other errors, print them to the console.
print(f"An unhandled error occurred: {error}")
# Potentially send a generic error message back to the user as well.
if not interaction.response.is_done():
await interaction.response.send_message("An unexpected error occurred.", ephemeral=True)


# --- Step 4: Main Bot Events and Startup Logic ---
@bot.event
async def on_ready():
print(f'Logged in as {bot.user}!')
try:
# Add the cog to the bot so its commands are registered.
await bot.add_cog(AIChatCog(bot))

# Sync the slash commands to Discord. This makes them appear for users.
synced = await bot.tree.sync()
print(f"Synced {len(synced)} command(s).")
except Exception as e:
print(f"Error during setup: {e}")

# This is the entry point for running the bot.
if __name__ == "__main__":
if not DISCORD_TOKEN or not PERPLEXITY_API_KEY:
print("CRITICAL: DISCORD_TOKEN and/or PERPLEXITY_API_KEY not found in .env file. Bot cannot start.")
else:
bot.run(DISCORD_TOKEN)
4 changes: 4 additions & 0 deletions docs/examples/discord-py-bot/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# requirements.txt
discord.py
openai
python-dotenv