How to Create a Discord Bot for NSFW Image Moderation: A Complete Guide

Introduction

Overview

Discord has emerged as one of the most popular communication platforms for gamers, communities, and teams worldwide. With its user-friendly interface and extensive customization options, it’s no wonder that millions of users flock to Discord for both casual and professional interactions. However, as with any large online community, maintaining a safe and respectful environment is crucial. This is where moderation comes into play.

Moderation is essential for fostering a positive community experience. It helps in preventing inappropriate content, such as NSFW (Not Safe For Work) images, from disrupting the harmony of a server. NSFW content, which includes explicit or offensive images, can not only tarnish the community's atmosphere but also violate Discord’s terms of service. Therefore, implementing effective moderation tools is vital for server admins and moderators.

The purpose of this guide is to provide a comprehensive walkthrough for creating a Discord bot specifically designed for NSFW image moderation. By the end of this guide, you will have a fully functional bot capable of identifying and handling NSFW images, ensuring your server remains a safe space for all members.

Who This Guide Is For

This guide is tailored for:

  • Server Admins and Moderators: If you are responsible for managing a Discord server and want to enhance its moderation capabilities, this guide will equip you with the necessary tools to do so effectively.

  • Developers Interested in Creating Moderation Tools: Whether you are an experienced developer or someone looking to hone your skills in bot development, this guide will provide valuable insights and practical steps to build a robust NSFW image moderation bot.

Prerequisites

Before diving into the creation of the bot, there are a few prerequisites to ensure you have a smooth experience:

  • Basic Understanding of Python Programming: This guide assumes that you have a basic grasp of Python. Familiarity with concepts such as functions, loops, and handling libraries will be beneficial.

  • Knowledge of Using Discord: You should be comfortable navigating Discord, including understanding server roles, permissions, and basic server management.

  • Necessary Tools:

    • Python: Ensure that you have Python installed on your computer. This guide will provide 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. Signing up for API access and obtaining necessary keys will be part of the process.

With these prerequisites in place, you’ll be well-prepared to follow along and create a powerful Discord bot for moderating NSFW images. Let’s get started!

Basic Bot Setup

Creating a New Discord Application

To get started with creating your Discord bot for NSFW image moderation, you first need to set up a new application on the Discord Developer Portal. This application will provide you with the necessary credentials 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 go to the Discord Developer Portal.

  • Log in using your Discord account credentials. If you don’t have a Discord account, you’ll need to create one.

Create a New Application

  • Once logged in, you’ll see a dashboard with 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, prompting you to enter a name for your application. Choose a name that reflects the purpose of your bot (e.g., "NSFW Image Moderator Bot") and click "Create".

 
Create New Application
 

Configure Your Application

  • After creating the application, you’ll be directed to the application’s settings page. Here, you can configure various aspects of your application.

  • On the left sidebar, click on "Bot" to access the bot settings.

  • Turn on 'Message Content Intent'.

Turn On Message Content Intent

Retrieve Your Bot Token

  • Once the bot is created, you’ll see a section titled "Token" under the bot settings. Click on the "Copy" button to copy your bot token. This token is essential for authenticating your bot and allowing it to interact with the Discord API.

  • Important: Keep your bot token secure and never share it publicly. If your token is compromised, 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, check the "bot" scope under "SCOPES".

Check Bot Scope
  • 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

Set Bot Permissions
  • 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 redirected to a page where you can select the server to which you want to invite your bot. Choose the appropriate server and click "Authorize". You might be required to complete a CAPTCHA to confirm.

With your Discord application set up and your bot invited to your server, you’re ready to move on to the next step: writing the bot script. This foundational setup ensures that your bot is authenticated and has the necessary permissions to moderate NSFW images effectively.

Creating the Bot Script

Now that you have your Discord application set up and your bot invited to your server, it’s time to create the bot script. This script will allow your bot to connect to Discord and start interacting with your server.

We will use Python for the development, and you are free to use any preferred code editor. Python is a versatile and widely-used programming language, making it an excellent choice for creating a Discord bot.

Let’s start with a simple echo bot (the code is presented below) to ensure that the bot can receive messages from your Discord server and react to them. An echo bot is a basic bot that repeats any message it receives, which is a great way to verify that our bot is correctly 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 use the API4AI NSFW Recognition API. This API offers several benefits:

  • High Accuracy: Advanced machine learning models ensure high accuracy in detecting NSFW content.

  • Ease of Use: Simple and intuitive API endpoints make it easy to integrate into existing applications.

  • Scalability: Handles large volumes of requests efficiently, making it suitable for growing communities.

  • Affordable Pricing: Cost-effective plans available to suit different needs and budgets.

Understanding API4AI NSFW Recognition API

This API processes images and detects sexual content in them, marking the images as Safe For Work (SFW) or Not Safe For Work (NSFW). It also provides the confidence percentage for each of the two classes. The NSFW tag can detect inappropriate content of various kinds. The NSFW tag is responsible for identifying content such as porn, hentai, or more mild but explicit material that may be unsuitable for work and other public places. Detailed information about possible options for integration can be found in the documentation.

As mentioned, a full-featured solution is available via subscription on the Rapid API platform. In addition, it can be tested via demo main https://demo.api4ai.cloud. Just run the following command in the Terminal to see how it works:

  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

A Discord bot token will be parsed from the command line arguments. This approach allows for flexibility and security, as the token is not hard-coded into the script. Instead, it can be provided at runtime, making it easier to manage different environments and configurations. To achieve this, we will use a command line argument parsing library, ensuring that the token is correctly retrieved and used 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 last step is to run the bot with the necessary permissions to see message content and manage messages on servers (guilds). These permissions are crucial for the bot to function correctly, allowing it to read messages, identify NSFW content, and take appropriate actions, such as deleting the content or notifying users. Ensure that 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 Ready Python Code

That’s it! Below is the complete Python code for your NSFW Image Moderation bot. This code includes all the necessary components, such as parsing the Discord bot token from command line arguments, setting up the bot with the required permissions to view and manage message content, and implementing the asynchronous functions to handle image moderation. Follow the steps and customize 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 comprehensive guide, we have meticulously walked through the detailed process of creating a Discord bot specifically designed for NSFW (Not Safe For Work) image moderation. From setting up the initial development environment to integrating advanced image moderation capabilities, we have covered each step with precision to ensure you can effectively deploy a bot that meets your community's needs.

Effective moderation is crucial for managing any online community, as it helps maintain order and ensure a positive experience for all members. By implementing a bot that automatically detects and removes NSFW images, you play a vital role in upholding a respectful and safe environment. This proactive approach not only significantly enhances the user experience by preventing exposure to inappropriate content but also ensures compliance with Discord’s community guidelines. Such measures help in fostering a welcoming and inclusive community where members can interact freely without concern for offensive or harmful material.

Further Reading

To deepen your understanding of Discord bot development and explore more advanced moderation techniques, consider the following resources:

  • Discord.py Documentation:

    • Comprehensive documentation for the discord.py library, which is essential for developing Discord bots.

    • Discord.py Documentation

  • API4AI Documentation:

By exploring these resources, you can enhance your bot's capabilities, ensuring comprehensive and effective moderation. Continuous learning and adapting to new tools and techniques will help you manage your community more efficiently and keep it a welcoming space for everyone.

Previous
Previous

How Image Recognition Technology is Changing Alcohol Inventory Management

Next
Next

Why and How to Measure Brand Awareness in Sports Streaming and Events