NSFW Image Moderation on Discord: Creating Your Own Bot from Scratch
Tarana Murtuzova
Posted on August 2, 2024
Introduction
Discord has become one of the leading communication platforms for gamers, communities, and teams around the globe. Thanks to its intuitive interface and extensive customization options, it's no surprise that millions of users turn to Discord for both casual and professional interactions. However, like any large online community, it is crucial to maintain a safe and respectful environment. This is where moderation becomes essential.
Moderation is key to promoting a positive community experience. It helps prevent inappropriate content, such as NSFW (Not Safe For Work) images, from disrupting the server's harmony. NSFW content, which includes explicit or offensive images, can not only degrade the community's atmosphere but also breach Discord’s terms of service. Therefore, it is vital for server administrators and moderators to implement effective moderation tools.
This guide aims to offer a detailed tutorial for creating a Discord bot specifically tailored for NSFW image moderation. By the end of this guide, you will have a fully operational bot capable of detecting and managing NSFW images, ensuring your server remains a safe and welcoming space for all members.
Who This Guide Is For
This guide is designed for:
Server Admins and Moderators: If you manage a Discord server and aim to improve its moderation capabilities, this guide will provide you with the essential tools to do so effectively.
Developers Interested in Building Moderation Tools: Whether you're an experienced developer or looking to improve your skills in bot development, this guide offers valuable insights and practical steps to create a robust NSFW image moderation bot.
Prerequisites
Before you start creating the bot, ensure you meet the following prerequisites for a smooth experience:
Basic Understanding of Python Programming: This guide assumes you have a basic understanding of Python, including familiarity with functions, loops, and library management.
Knowledge of Using Discord: You should be comfortable navigating Discord, including understanding server roles, permissions, and basic server management.
Necessary Tools
- Python: Make sure you have Python installed on your computer. This guide will include instructions for setting up the development environment.
- Discord Account: You will need a Discord account to create and manage your bot.
- API Access: We will use third-party APIs for image moderation. Part of the process will involve signing up for API access and obtaining the necessary keys.
With these prerequisites in place, you'll be well-prepared to follow along and create an effective Discord bot for moderating NSFW images. Let's get started!
Basic Bot Setup
Creating a New Discord Application
To begin creating your Discord bot for NSFW image moderation, you need to set up a new application on the Discord Developer Portal. This application will provide you with the credentials required to connect your bot to Discord and manage its interactions. Follow these steps to create your new Discord application:
Log in to the Discord Developer Portal:
- Open your web browser and navigate to the Discord Developer Portal.
- Log in using your Discord account credentials. If you don’t have an account, you will need to create one.
Create a New Application:
- Once logged in, you’ll be directed to a dashboard displaying a list of your applications (if any). Click on the "New Application" button located at the top right corner of the screen.
- A pop-up window will appear, asking you to enter a name for your application. Choose a name that reflects your bot's purpose (e.g., "NSFW Image Moderator Bot") and click "Create".
Configure Your Application
- After setting up the application, you’ll be taken to the application's settings page where you can configure various details.
- In the left-hand sidebar, click on "Bot" to access the bot settings.
- Enable the 'Message Content Intent' option.
Retrieve Your Bot Token
- After creating your bot, locate the "Token" section under the bot settings. Click the "Copy" button to save your bot token. This token is crucial for authenticating your bot and enabling it to interact with the Discord API.
- Important: Keep your bot token secure and never share it publicly. If your token is exposed, anyone can control your bot.
Set Bot Permissions
- Scroll down to the "OAuth2" section in the left sidebar and click on it.
- In the "OAuth2 URL Generator" section, select the "bot" scope under "SCOPES".
- Under "BOT PERMISSIONS", select the permissions your bot will need. For an NSFW image moderation bot, you’ll typically need the following permissions: Read Messages, Manage Messages.
- Copy the generated URL under the "OAuth2 URL Generator" section.
Invite Your Bot to Your Server
- Paste the copied URL into your web browser's address bar and press Enter.
- You will be taken to a page where you can select the server you wish to invite your bot to. Choose the appropriate server and click "Authorize". You might need to complete a CAPTCHA to confirm.
With your Discord application configured and your bot added to your server, you’re ready to proceed to the next step: writing the bot script. This initial setup ensures that your bot is authenticated and has the required permissions to effectively moderate NSFW images.
Creating the Bot Script
With your Discord application configured and your bot invited to your server, it's time to develop the bot script. This script will enable your bot to connect to Discord and interact with your server.
We will use Python for this development, and you can choose any code editor you prefer. Python is a versatile and widely-used programming language, making it an excellent choice for creating a Discord bot.
Let’s start by writing a simple echo bot (code provided below) to ensure the bot can receive messages from your Discord server and respond to them. An echo bot is a basic bot that repeats any message it receives, making it an excellent way to verify that our bot is properly set up and communicating with the server.
import discord
class MyClient(discord.Client):
## Triggered when the bot is launched and ready.
async def on_ready(self):
print(f'We have logged in as {self.user}')
## Triggered when a user sends a message.
async def on_message(self, msg):
if msg.author == self.user:
return
await msg.channel.send(msg.content)
bot_token = 'YOUR_BOT_TOKEN' # Use yours that you saved before.
intents = discord.Intents.default()
intents.messages = True
intents.message_content = True
client = MyClient(intents=intents)
client.run(bot_token)
After running this script, you should see the following message: 'We have logged in as NSFW Image Moderator Bot'.
Integrating Image Moderation
Choosing an Image Moderation API
For effective NSFW image moderation, we will utilize the API4AI NSFW Recognition API. This API provides several advantages:
- High Accuracy: Utilizes advanced machine learning models to ensure precise detection of NSFW content.
- Ease of Use: Features simple and intuitive API endpoints, making it straightforward to integrate into your application.
- Scalability: Efficiently handles large volumes of requests, making it ideal for expanding communities.
- Affordable Pricing: Offers cost-effective plans to accommodate various needs and budgets.
Understanding API4AI NSFW Recognition API
This API analyzes images to identify and categorize sexual content, marking them as either Safe For Work (SFW) or Not Safe For Work (NSFW). It also provides a confidence percentage for each category. The NSFW tag can detect various types of inappropriate content, including explicit material such as porn, hentai, or milder but still explicit content that may not be suitable for work or public viewing. For detailed integration options, refer to the documentation.
A comprehensive solution is available via subscription on the Rapid API platform. You can also test it through the demo at https://demo.api4ai.cloud. To see it in action, run the following command in the Terminal:
$ curl -X "POST" \
"https://demo.api4ai.cloud/nsfw/v1/results" \
-F "url=https://storage.googleapis.com/api4ai-static/samples/nsfw-1.jpg"
Function for Checking a Photo with NSFW API
To integrate the API into our bot, let’s start with a function that sends images to the API and processes the response. Here’s a sample function:
import argparse
import asyncio
import discord
import requests
from requests.adapters import HTTPAdapter, Retry
API_URL = 'https://nsfw3.p.rapidapi.com'
NSFW_THRESHOLD = 0.8
async def is_nsfw_photo(img_url: str, nsfw_token: str):
url = API_URL + '/v1/results'
# We strongly recommend you use exponential backoff.
error_statuses = (408, 409, 429, 500, 502, 503, 504)
session = requests.Session()
retries = Retry(backoff_factor=1.5, status_forcelist=error_statuses)
session.mount('https://', HTTPAdapter(max_retries=retries))
api_res = session.post(url, data={'url': img_url},
headers={'X-RapidAPI-Key': nsfw_token}, timeout=20)
api_res_json = api_res.json()
if (api_res.status_code != 200 or
api_res_json['results'][0]['status']['code'] == 'failure'):
raise RuntimeError('Image cannot be processed.')
return api_res_json['results'][0]['entities'][0]['classes']['nsfw'] >= NSFW_THRESHOLD # noqa
Please note that the function is declared as async, as it will allow you to send several photos from the message at once for processing.
Making a Bot Class
Next, we’ll create a bot class that integrates the NSFW checking function. This class will handle connecting to Discord, processing messages, and reacting to NSFW content.
class ModerationBot(discord.Client):
def __init__(self, *args, nsfw_token: str = None, **kwargs):
discord.Client.__init__(self, *args, **kwargs)
self.nsfw_token = nsfw_token
async def on_ready(self):
print(f'We have logged in as {self.user}')
async def on_message(self, message: discord.Message):
if message.author == self.user:
return
photos = [a for a in message.attachments
if a.content_type in ('image/jpeg', 'image/png')]
tasks = [is_nsfw_photo(photo.url, self.nsfw_token) for photo in photos]
results = await asyncio.gather(*tasks)
if any(results):
await asyncio.gather(
message.author.send(f'You not allowed to send NSFW content to {message.channel.jump_url}.'),
message.delete()
)
This part is necessary to ensure that the bot does not react to its own messages:
if message.author == self.user:
return
Users can send various types of attachments, including videos, photos, and voice messages. That's why we have to distinguish photos from the rest of the attachments:
photos = [a for a in message.attachments
if a.content_type in ('image/jpeg', 'image/png')]
Most of the time, when the script sends a request, it is idling. That's why we made is_nsfw_photo async. Use asyncio.gather() to call is_nsfw_photo asynchronously.
tasks = [is_nsfw_photo(photo.url, self.nsfw_token) for photo in photos]
results = await asyncio.gather(*tasks)
If any photo in the message is NSFW, delete it and send a warning to the user. Here, too, it is better to use asyncio.gather() to avoid idling.
if any(results):
await asyncio.gather(
message.author.send(f'You not allowed to send NSFW content to {message.channel.jump_url}.'),
message.delete()
)
Parsing Arguments and Implementing the Main Function
To enhance flexibility and security, we will parse the Discord bot token from the command line arguments. This method prevents the token from being hard-coded into the script, allowing it to be supplied at runtime. This approach simplifies managing different environments and configurations. We will use a command line argument parsing library to ensure the token is accurately retrieved and utilized to authenticate the bot.
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('--discord-token',
help='Discord bot token. Go to '
'https://discord.com/developers/applications'
' for token.',
required=True)
parser.add_argument('--api-token',
help='NSFW API token.',
required=True) # Get your API key at RapidAPI # noqa
return parser.parse_args()
The final step is to run the bot with the required permissions to read message content and manage messages on servers (guilds). These permissions are essential for the bot to operate correctly, enabling it to read messages, detect NSFW content, and take appropriate actions, such as deleting the content or notifying users. Make sure the bot has been granted these permissions in the Discord Developer Portal before starting it.
def main():
"""Program entry point."""
args = parse_args()
intents = discord.Intents.default()
intents.guild_messages = True
intents.message_content = True
client = ModerationBot(intents=intents, nsfw_token=args.api_token)
client.run(args.discord_token)
if __name__ == '__main__':
main()
The Completed Python Code
That's all! Below is the full Python script for your NSFW Image Moderation bot. This code contains all essential elements, including parsing the Discord bot token from command line arguments, configuring the bot with the necessary permissions to read and manage message content, and implementing asynchronous functions to handle image moderation. Follow these steps and modify the code as needed to integrate it into your server.
"""
NSFW photo moderation bot for Discord.
Discord bot for moderating NSFW images on a server.
How to launch:
`pip install discord.py requests`
`python3 main.py --discord-token <BOT TOKEN> --api-token <NSFW API TOKEN>`
"""
import argparse
import asyncio
import discord
import requests
from urllib3 import Retry
from requests.adapters import HTTPAdapter
API_URL = 'https://nsfw3.p.rapidapi.com'
NSFW_THRESHOLD = 0.8
async def is_nsfw_photo(img_url: str, nsfw_token: str):
"""
Check if a photo is Not Safe For Work.
API4AI is used for checking.
Learn more at https://api4.ai/apis/nsfw
Parameters
----------
img_url : str
nsfw_token : str
"""
url = API_URL + '/v1/results'
# We strongly recommend you use exponential backoff.
error_statuses = (408, 409, 429, 500, 502, 503, 504)
session = requests.Session()
retries = Retry(backoff_factor=1.5, status_forcelist=error_statuses)
session.mount('https://', HTTPAdapter(max_retries=retries))
api_res = session.post(url, data={'url': img_url},
headers={'X-RapidAPI-Key': nsfw_token}, timeout=20)
api_res_json = api_res.json()
if (api_res.status_code != 200 or
api_res_json['results'][0]['status']['code'] == 'failure'):
raise RuntimeError('Image cannot be processed.')
return api_res_json['results'][0]['entities'][0]['classes']['nsfw'] >= NSFW_THRESHOLD # noqa
class ModerationBot(discord.Client):
"""
Discord py client implementing event handlers.
Official documentation: https://discordpy.readthedocs.io/en/stable
"""
def __init__(self, *args, nsfw_token: str = None, **kwargs):
"""
Client init function. Pass your NSFW API token here.
Learn discord.Client arguments at
https://discordpy.readthedocs.io/en/stable/api.html#discord.Client
Parameters
----------
args: tuple
discord.Client arguments
nsfw_token: str
kwargs: dict
discord.Client arguments
"""
discord.Client.__init__(self, *args, **kwargs)
self.nsfw_token = nsfw_token
async def on_ready(self):
"""
Print when the bot is ready.
Also, it will be online on your server.
"""
print(f'We have logged in as {self.user}')
async def on_message(self, message: discord.Message):
"""
Handle the on_message event.
Test all images in a message if there are any NSFW photos.
Checks only jpeg and png images.
Parameters
----------
message : discord.Message
sent by a user on a server.
"""
# Do not handle the bot's own message.
if message.author == self.user:
return
# In Discord, images, voice messages, videos, and others are attachments.
photos = [a for a in message.attachments
if a.content_type in ('image/jpeg', 'image/png')]
tasks = [is_nsfw_photo(photo.url, self.nsfw_token) for photo in photos]
results = await asyncio.gather(*tasks)
if any(results):
await asyncio.gather(
message.author.send(f'You not allowed to send NSFW content to '
f'{message.channel.jump_url}.'),
message.delete()
)
def parse_args():
"""Parse command line arguments."""
parser = argparse.ArgumentParser()
parser.add_argument('--discord-token',
help='Discord bot token. Go to '
'https://discord.com/developers/applications'
' for token.',
required=True)
parser.add_argument('--api-token',
help='NSFW API token.',
required=True) # Get your API key at RapidAPI # noqa
return parser.parse_args()
def main():
"""Program entry point."""
args = parse_args()
intents = discord.Intents.default()
intents.guild_messages = True
intents.message_content = True
client = ModerationBot(intents=intents, nsfw_token=args.api_token)
client.run(args.discord_token)
if __name__ == '__main__':
main()
Conclusion
In this thorough guide, we have carefully detailed the process of creating a Discord bot tailored for NSFW (Not Safe For Work) image moderation. From setting up the initial development environment to incorporating advanced image moderation features, we have covered each step to ensure you can successfully deploy a bot that suits your community's needs.
Effective moderation is essential for managing any online community, as it helps maintain order and provides a positive experience for all members. By implementing a bot that automatically detects and removes NSFW images, you play a crucial role in maintaining a respectful and safe environment. This proactive approach not only enhances the user experience by preventing exposure to inappropriate content but also ensures compliance with Discord’s community guidelines. These measures foster a welcoming and inclusive community where members can interact freely without the concern of encountering offensive or harmful material.
To expand your knowledge of Discord bot development and explore more advanced moderation techniques, consider the following resources:
Discord.py Documentation:
- The comprehensive documentation for the discord.py library is crucial for developing Discord bots.
- Discord.py Documentation.
API4AI Documentation:
- The detailed documentation for the API4AI NSFW Recognition API includes additional features and customization options.
- API4AI NSFW Recognition API Documentation.
By delving into these resources, you can enhance your bot's capabilities, ensuring thorough and effective moderation. Continuous learning and adapting to new tools and techniques will help you manage your community more efficiently and maintain a welcoming space for everyone.
Posted on August 2, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.