Discord has emerged as a veritable titan among communication platforms, captivating not only gamers, but also diverse communities and businesses with its unmatched versatility.
Amidst this panoply of offerings, one particular facet stands out like a beacon, distinguishing Discord from its counterparts: the prodigious capacity to harness the power of bots.
These automated entities, when integrated into Discord servers, prove to be formidable assets, imbued with the ability to streamline and enhance the user experience.
A typical Discord server is a lively place where people interact. Sometimes, certain individuals break the rules and share inappropriate images, causing disagreements and conflicts.
The goal of our tutorial is to provide a solution so to solve this problem using a Discord moderation bot. This bot is a clever technology that helps address these challenges. By using the bot, server administrators can prevent the spread of inappropriate content automatically. This reduces the need for many human moderators and saves money spent on hiring them.
In summary, the Discord moderation bot is a helpful tool for server owners. It helps them maintain order and save money while protecting their communities.
NSFW API is very easy to use.
Merely by sending a request and get a response with the probability that the photo possesses an adult or Not Safe For Work (NSFW) nature.
import requests
RAPIDAPI_KEY = ''
path_to_img = 'nsfw.jpg'
with open(path_to_img, 'rb') as f:
response = requests.post('https://nsfw3.p.rapidapi.com/v1/results',
headers={'X-RapidAPI-Key': RAPIDAPI_KEY},
files={'image': f})
api_res_json = response.json()
nsfw_probability = api_res_json['results'][0]['entities'][0]['classes']['nsfw']
sfw_probability = api_res_json['results'][0]['entities'][0]['classes']['sfw']
First of all, let’s create a bot.
Go to https://discord.com/developers/applications?new_application=true and create a new application.
Then go to Bot and turn on message content intent
.
Now you can invite the bot to your server using the URL from the OAuth2->URL Generator menu. Do not forget to click bot
and set the permissions.
Let’s make a simple echobot.
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 = '2b4d252a-9c7a-4f17-85bf-d7b6390c165b' # get yours at Bot->Token menu
intents = discord.Intents.default()
intents.messages = True
intents.message_content = True
client = MyClient(intents=intents)
client.run(bot_token)
First of all, follow the steps from the previous chapter and create a bot application in the Discord developer portal.
Let’s start making a bot with a function for checking a photo with NSFW API.
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.
Now we are ready to make a bot class.
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 needed so that the bot does not react to its own messages.
if message.author == self.user:
return
All that users can send are 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 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()
)
A Discord bot token will be parsed from command line arguments.
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 https://rapidapi.com/api4ai-api4ai-default/api/nsfw3/details # noqa
return parser.parse_args()
The last step left is to run the bot with rights to see message_content and manage messages on servers(guilds).
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 is:
"""
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 https://rapidapi.com/api4ai-api4ai-default/api/nsfw3/details # 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()
In this tutorial, we developed a Discord bot for content moderation using our advanced solution for detecting unsafe content. By following our guide, you can create a bot that automatically enforces community guidelines, ensuring a safe environment for all users. We covered setting up the development environment, creating a Discord bot application, implementing moderation features, and utilizing our content detection solution. Let’s get started on building your powerful moderation bot for Discord!