Сегодня мы сделаем такой функционал:
Выдача роли при заходе на сервер, выдача роли по реакции
Бан, очистка сообщений
Поработаем с базой данных
Затронем API.
Так-же прикреплю полностью рабочий код в конце данной статьи.
База
Думаю как установить python вы разберетесь.
Прописываем в консольку:
Код Python:
python3 -m pip install -U discord.py
Импортируем все нужные нам для данного гайда модули, а так-же задаем нужные нам интенты.
Код Python:
import discord
import asyncio
import json
import requests
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(command_prefix="!", intents=intents) # вместо ! можно подставь любой префикс.
@bot.event
async def on_ready():
print("Bots Guide")
print(f'Logged in as \033[1m\033[31m{bot.user}\033[0m')
async def send_msg(channel, text):
channel = bot.get_channel(channel)
await channel.send(text)
bot.run('ваштокен')
Но где мне взять токен и включить интент?
Заходим сюда > discord.com/developers/applications/
Тыкаем по стрелочкам.
Дальше нам нужно немного пролистать вниз и нажать воть сюда
Чтобы узнать токен жмем сюда
И сразу вставляем его вместо ваштокен.
С начальной подготовкой мы справились и переходим к следующему шагу.
Next Level – Код бота:
Начнём мы с самого простого – команды для модерации сервера.
Сделаем очистку сообщений по заданному количеству, бан, а так-же роли по клику на реакцию.
Лично я буду добавлять ко всем данным командам логирование в определенный канал, однако это совсем не обязательно.
Начнем с очистки сообщений.
Код Python:
@bot.command(pass_context=True)
@commands.has_permissions(administrator=True) # проверка на права администрирования сервером
async def clear(ctx, limit: int): # задаем параметр команды limit который является целым числом
logs = bot.get_channel(974312499690233896); # вставляем айди канала с логами
channel = ctx.message.channel # определяем канал для удаления сообщений (там где была отправлена команда)
await ctx.message.delete() # удаляем сообщение содержащее команду
await ctx.channel.purge(limit=limit) # очищаем limit последних сообщений
embed=discord.Embed(title=f"Было удалено {limit} сообщений.", color=0xd36969) #задаем название эмбеда, цвет полосочки
embed.set_thumbnail(url='https://cdn-icons-png.flaticon.com/512/5181/5181185.png') # вставляем кортиночку
embed.set_footer(text=f"Выполнено " + ctx.author.name +"#"+ ctx.author.discriminator, icon_url=ctx.author.avatar_url) # футер с тем, кто выполнил команду
await ctx.send(embed=embed) # отправляем эмбед в канал где было удаление
logembed=discord.Embed(title=f"В чате {channel} удалено {limit} сообщений.", color=0x0B729D) # тот же эмбед только в логи.
logembed.set_thumbnail(url='https://cdn-icons-png.flaticon.com/512/5181/5181185.png')
logembed.set_footer(text=f"Выполнено " + ctx.author.name +"#"+ ctx.author.discriminator, icon_url=ctx.author.avatar_url)
await logs.send(embed=logembed) # отправляем эмбед в логи
@clear.error
async def clear_error(ctx, error):
if isinstance(error, commands.MissingPermissions): # если недостаточно прав (нет админки):
await ctx.message.delete() # удаляем сообщение содержащее команду
embed=discord.Embed(title="У вас недостаточно прав.", color=0xd36969) # эмбед
await ctx.send(embed=embed) # отправляем эмбед
А теперь разберемся и с баном.
Сделаем так-же выдачу роли при входе на сервер.
Код Python:
@bot.event
async def on_member_join(member):
guild = bot.get_guild(idservera) # вместо idservera - айди вашего сервера (ПКМ на сервер в списке, Копировать айди)
role = discord.utils.get(guild.roles, name="названиеРоли")
await member.add_roles(role)
А так-же сделаем выдачу ролей по реакциям ведь это так круто!
Код Python:
# начало клик-ролей
@bot.event
async def on_raw_reaction_add(payload):
ourMessageID = 975132259147456623 # айди сообщения (сначала создаем его командой !react, а потом копируем его айди и вписываем сюда)
if ourMessageID == payload.message_id:
member = payload.member # определяем юзера
guild = member.guild # определяем сервер
emoji = payload.emoji.name # эмоджи при нажатии на которое выдается роль
if emoji == '': # само эмоджи
role = discord.utils.get(guild.roles, name="・Lounge") # определяем роль которую будем выдавать
await member.add_roles(role) # выдаем рольку
@bot.event
async def on_raw_reaction_remove(payload):
ourMessageID = 975132259147456623 # айди сообщения (сначала создаем его командой !react, а потом копируем его айди и вписываем сюда)
if ourMessageID == payload.message_id:
guild = await(bot.fetch_guild(payload.guild_id))
emoji = payload.emoji.name # эмоджи при нажатии на которое выдается роль
if emoji == '': # само эмоджи
role = discord.utils.get(guild.roles, name="・Lounge") # определяем роль которую будем выдавать
member = await(guild.fetch_member(payload.user_id))
if member is not None: # проверяем есть ли он на сервере
await member.remove_roles(role) # забираем рольку
else:
print('not found')
@bot.command()
async def react(ctx):
channel = bot.get_channel(938448067357728798) # определяем канал, куда будет отправлено сообщение с эмбедом и реакциями
embed=discord.Embed(title="Заголовок эмбеда", description="""Описание какое-то.""", color=0x5e7abd) # сам эмбед
embed.set_thumbnail(url="https://cdn-icons-png.flaticon.com/512/1545/1545324.png") # кортиночка
embed.set_footer(text="ggdt.ru") # футер
mojj = await channel.send(embed=embed)
await mojj.add_reaction('') # отправляем эмбед + добавляем реакцию
#конец клик-ролей
Ну и бан сделаем.
Код Python:
@bot.command()
@commands.has_permissions(administrator=True) # проверка на права администрирования сервером
async def ban(ctx, member: discord.Member, reason=None): # определяем пользователя и причину
await ctx.message.delete() # удаляем сообщение содержащее команду
await member.ban(reason=reason) # баним с причиной которую указали аргументом
logs = bot.get_channel(974312499690233896); # вставляем айди канала с логами
embed=discord.Embed(title=f"Пользователь {member} был забанен.", description=f"Причина блокировки: {reason}", color=0xd36969)
embed.set_thumbnail(url='https://cdn-icons-png.flaticon.com/512/5426/5426867.png')
embed.set_footer(text=f"Выполнено " + ctx.author.name +"#"+ ctx.author.discriminator, icon_url=ctx.author.avatar_url)
await ctx.send(embed=embed) # отправляем эмбед в канал где была прописана команда
logembed=discord.Embed(title=f"Пользователь {member} был забанен.", description=f"Указанная причина блокировки: {reason}", color=0x0B729D)
logembed.set_thumbnail(url='https://cdn-icons-png.flaticon.com/512/5426/5426867.png')
logembed.set_footer(text=f"Выполнено " + ctx.author.name +"#"+ ctx.author.discriminator, icon_url=ctx.author.avatar_url)
await logs.send(embed=logembed) # отправляем эмбед в логи
@ban.error
async def ban_error(ctx, error):
if isinstance(error, commands.MissingPermissions):
await ctx.message.delete()
embed=discord.Embed(title="У вас недостаточно прав.", color=0xd36969)
await ctx.send(embed=embed)
А так-же чет захотелось сделать отправку эмбедов с discord.club (дабы отправлять эмбеды не залезая в код)
Код Python:
@bot.command()
async def embed(ctx, *, embedhere): # определяем сам эмбед
await ctx.message.delete() # удаляем сообщение с командой
embedcontent = json.loads(embedhere)
embed = discord.Embed.from_dict(embedcontent["embeds"][0]) # достаем эмбед из словаря
print(embedcontent) #для дебага
print(embed.to_dict()) #для дебага
await ctx.send(embed=embed) #отправляем эмбед в чат
Теперь когда вы пропишите “!embed { json embed }” у вас отправится красивенький эмбед.
А теперь немножечко поработаем с БД.
База данных:
Создадим рядом с ботом файлик bd.json.
Теперь добавим туда следующее:
Код Python:
{"bans": 0}
Переходим обратно к нашему боту и пишем функцию, которую будем использовать.
Код Python:
def AddBan(): # функция аддбан
"""Добавит +1 к банам, которые хранятся в bd.json"""
with open('bd.json', 'r') as f:
json_data = json.load(f)
json_data['bans'] += 1 # добавляем 1 к числу
with open('bd.json', 'w') as f:
f.write(json.dumps(json_data)) # записываем данные
А теперь просто добавим в конце команды ban эту строку ( после await logs.send ):
Код Python:
AddBan()
Ну и на закуску мы сделаем статистику.
Код Python:
@bot.command()
async def stats(ctx):
await ctx.message.delete()
with open('bd.json', 'r') as f:
json_data = json.load(f)
awards = json_data["bans"]
f.close() # читаем bd.json, а конкретно bans.
embed=discord.Embed(title="Общая статистика:", color=0x6098c3) #embed
embed.set_thumbnail(url='https://cdn-icons-png.flaticon.com/512/4985/4985595.png')#embed
embed.add_field(name="Выдано наград:", value=bans, inline=True)# как value мы используем bans из bd.json.
embed.add_field(name="Что-то еще:", value="0", inline=True)#embed
embed.set_footer(text=f"Выполнено " + ctx.author.name +"#"+ ctx.author.discriminator, icon_url=ctx.author.avatar_url)#embed
await ctx.send(embed=embed)#embed
С БД я вроде закончил.
Ну и закончим нашу статью работой с API.
Api:
Мы будем работать с discord-tracker и проверять кто сидит с юзером в войсе + получать их айдишники.
(работать будет только если это на серверах, на котором есть бот discord трекера.
Useless, просто как пример использования х)
Код Python:
@bot.command()
async def getid(ctx, member: discord.Member): # получаем мембера которого указали в команде
await ctx.message.delete() # удаляем сообщение с командой
url_param = f"https://discord-tracker.ru/tracker/get-victim-info/{ctx.member.id}/?format=json"
cookies = {
"sessionid":"cookie", # вместо cookie ваш кук
}
response = requests.get(url_param, cookies=cookies) # выше задаем куки и ссылку, тут формируем запрос
result = response.json() # а тут отправляем и получаем json
result_str = ''
for i in result['in_voice']['channel']["members"]: # циклично находим всех юзеров с ответа
usernames = i["name"]
userids = i['id']
result_str += f'{usernames} {userids}\n' # выдаем имена и айди
await ctx.send(f'```{result_str}```') # выдаем готовый ответ
Полный код ниже:
#!/usr/bin/env python
# -*- coding: utf-8 -*- # строка нужна, чтобы не было ошибки Non-UTF-8 code starting with '\xd1' in file ...
import discord
import asyncio
import json
import requests
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(command_prefix="!", intents=intents)
@bot.event
async def on_ready():
print("Lounge Event Local bot started up.")
print(f'Залогинился как \033[1m\033[31m{bot.user}\033[0m')
async def send_msg(channel, text):
channel = bot.get_channel(channel)
await channel.send(text)
def AddBan(): # функция аддбан
"""Добавит +1 к банам, которые хранятся в bd.json"""
with open('bd.json', 'r') as f:
json_data = json.load(f)
json_data['bans'] += 1 # добавляем 1 к числу
with open('bd.json', 'w') as f:
f.write(json.dumps(json_data)) # записываем данные
@bot.event
async def on_member_join(member):
guild = bot.get_guild(idservera) # вместо idservera - айди вашего сервера (ПКМ на сервер в списке, Копировать айди)
role = discord.utils.get(guild.roles, name="названиеРоли")
await member.add_roles(role)
# Либо это /\ либо \/ это
# начало клик-ролей
@bot.event
async def on_raw_reaction_add(payload):
ourMessageID = 975132259147456623 # айди сообщения (сначала создаем его командой !react, а потом копируем его айди и вписываем сюда)
if ourMessageID == payload.message_id:
member = payload.member # определяем юзера
guild = member.guild # определяем сервер
emoji = payload.emoji.name # эмоджи при нажатии на которое выдается роль
if emoji == '?': # само эмоджи
role = discord.utils.get(guild.roles, name="・Lounge") # определяем роль которую будем выдавать
await member.add_roles(role) # выдаем рольку
@bot.event
async def on_raw_reaction_remove(payload):
ourMessageID = 975132259147456623 # айди сообщения (сначала создаем его командой !react, а потом копируем его айди и вписываем сюда)
if ourMessageID == payload.message_id:
guild = await(bot.fetch_guild(payload.guild_id))
emoji = payload.emoji.name # эмоджи при нажатии на которое выдается роль
if emoji == '?': # само эмоджи
role = discord.utils.get(guild.roles, name="・Lounge") # определяем роль которую будем выдавать
member = await(guild.fetch_member(payload.user_id))
if member is not None: # проверяем есть ли он на сервере
await member.remove_roles(role) # забираем рольку
else:
print('not found')
@bot.command()
async def react(ctx):
channel = bot.get_channel(938448067357728798) # определяем канал, куда будет отправлено сообщение с эмбедом и реакциями
embed=discord.Embed(title="Заголовок эмбеда", description="""Описание какое-то.""", color=0x5e7abd) # сам эмбед
embed.set_thumbnail(url="https://cdn-icons-png.flaticon.com/512/1545/1545324.png") # кортиночка
embed.set_footer(text="ggdt.ru") # футер
mojj = await channel.send(embed=embed)
await mojj.add_reaction('?') # отправляем эмбед + добавляем реакцию
#конец клик-ролей
@bot.command()
async def getid(ctx, member: discord.Member): # получаем мембера которого указали в команде
await ctx.message.delete() # удаляем сообщение с командой
url_param = f"https://discord-tracker.ru/tracker/get-victim-info/{ctx.member.id}/?format=json"
cookies = {
"sessionid":"cookie", # вместо cookie ваш кук
}
response = requests.get(url_param, cookies=cookies) # выше задаем куки и ссылку, тут формируем запрос
result = response.json() # а тут отправляем и получаем json
result_str = ''
for i in result['in_voice']['channel']["members"]: # циклично находим всех юзеров с ответа
usernames = i["name"]
userids = i['id']
result_str += f'{usernames} {userids}\n' # выдаем имена и айди
await ctx.send(f'```{result_str}```') # выдаем готовый ответ
@bot.command()
async def embed(ctx, *, embedhere): # определяем сам эмбед
await ctx.message.delete() # удаляем сообщение с командой
embedcontent = json.loads(embedhere)
embed = discord.Embed.from_dict(embedcontent["embeds"][0]) # достаем эмбед из словаря
print(embedcontent) #для дебага
print(embed.to_dict()) #для дебага
await ctx.send(embed=embed) #отправляем эмбед в чат
# Команды для модерации сервера.
@bot.command(pass_context=True)
@commands.has_permissions(administrator=True) # проверка на права администрирования сервером
async def clear(ctx, limit: int): # задаем параметр команды limit который является целым числом
logs = bot.get_channel(974312499690233896); # вставляем айди канала с логами
channel = ctx.message.channel # определяем канал для удаления сообщений (там где была отправлена команда)
await ctx.message.delete() # удаляем сообщение содержащее команду
await ctx.channel.purge(limit=limit) # очищаем limit последних сообщений
embed=discord.Embed(title=f"Было удалено {limit} сообщений.", color=0xd36969) #задаем название эмбеда, цвет полосочки
embed.set_thumbnail(url='https://cdn-icons-png.flaticon.com/512/5181/5181185.png') # вставляем кортиночку
embed.set_footer(text=f"Выполнено " + ctx.author.name +"#"+ ctx.author.discriminator, icon_url=ctx.author.avatar_url) # футер с тем, кто выполнил команду
await ctx.send(embed=embed) # отправляем эмбед в канал где было удаление
logembed=discord.Embed(title=f"В чате {channel} удалено {limit} сообщений.", color=0x0B729D) # тот же эмбед только в логи.
logembed.set_thumbnail(url='https://cdn-icons-png.flaticon.com/512/5181/5181185.png')
logembed.set_footer(text=f"Выполнено " + ctx.author.name +"#"+ ctx.author.discriminator, icon_url=ctx.author.avatar_url)
await logs.send(embed=logembed) # отправляем эмбед в логи
@clear.error
async def clear_error(ctx, error):
if isinstance(error, commands.MissingPermissions): # если недостаточно прав (нет админки):
await ctx.message.delete() # удаляем сообщение содержащее команду
embed=discord.Embed(title="У вас недостаточно прав.", color=0xd36969) # эмбед
await ctx.send(embed=embed) # отправляем эмбед
@bot.command()
@commands.has_permissions(administrator=True) # проверка на права администрирования сервером
async def ban(ctx, member: discord.Member, reason=None): # определяем пользователя и причину
await ctx.message.delete() # удаляем сообщение содержащее команду
await member.ban(reason=reason) # баним с причиной которую указали аргументом
logs = bot.get_channel(974312499690233896); # вставляем айди канала с логами
embed=discord.Embed(title=f"Пользователь {member} был забанен.", description=f"Причина блокировки: {reason}", color=0xd36969)
embed.set_thumbnail(url='https://cdn-icons-png.flaticon.com/512/5426/5426867.png')
embed.set_footer(text=f"Выполнено " + ctx.author.name +"#"+ ctx.author.discriminator, icon_url=ctx.author.avatar_url)
await ctx.send(embed=embed) # отправляем эмбед в канал где была прописана команда
logembed=discord.Embed(title=f"Пользователь {member} был забанен.", description=f"Указанная причина блокировки: {reason}", color=0x0B729D)
logembed.set_thumbnail(url='https://cdn-icons-png.flaticon.com/512/5426/5426867.png')
logembed.set_footer(text=f"Выполнено " + ctx.author.name +"#"+ ctx.author.discriminator, icon_url=ctx.author.avatar_url)
await logs.send(embed=logembed) # отправляем эмбед в логи
AddBan()
@ban.error
async def ban_error(ctx, error):
if isinstance(error, commands.MissingPermissions):
await ctx.message.delete()
embed=discord.Embed(title="У вас недостаточно прав.", color=0xd36969)
await ctx.send(embed=embed)
@bot.command()
async def stats(ctx):
await ctx.message.delete()
with open('bd.json', 'r') as f:
json_data = json.load(f)
awards = json_data["bans"]
f.close() # читаем bd.json, а конкретно bans.
embed=discord.Embed(title="Общая статистика:", color=0x6098c3) #embed
embed.set_thumbnail(url='https://cdn-icons-png.flaticon.com/512/4985/4985595.png')#embed
embed.add_field(name="Выдано наград:", value=bans, inline=True)# как value мы используем bans из bd.json.
embed.add_field(name="Что-то еще:", value="0", inline=True)#embed
embed.set_footer(text=f"Выполнено " + ctx.author.name +"#"+ ctx.author.discriminator, icon_url=ctx.author.avatar_url)#embed
await ctx.send(embed=embed)#embed
bot.run('ваштокен')
2 Comments
Я думаю, что Вы ошибаетесь.
Такой вопрос по поводу роли за клик по эмодзи, как сделать что бы можно было не 1 эмоджи, а несколько, вот я добавил несколько, но выдается только одна, что делать?