# примеры использования, на данный момент, может измениться в будущем:
await ctx.send("my reply to your message", reference=discord.MessageReference(message_id=861988287927326702, channel_id=554470291913241936))
await ctx.send("my reply to your message", reference=discord.MessageReference.from_message(ctx.message))
await ctx.send("my reply to your message", reference=ctx.message.to_reference())
await ctx.reply("my reply to your message", mention_author=False)
await bot.http.request(
discord.http.Route(
"POST", "/channels/{channel_id}/messages", channel_id=ctx.channel.id
),
json={
"content": "test",
"message_reference": {
"guild_id": "453391932705247478",
"channel_id": "554470291913241936",
"message_id": "861988287927326702",
},
},
)
As bots grow and are added to an increasing number of guilds, some developers may find it necessary to break or split portions of their bots operations into separate logical processes. As such, Discord gateways implement a method of user-controlled guild sharding which allows for splitting events across a number of gateway connections. Guild sharding is entirely user controlled, and requires no state-sharing between separate connections to operate
В то время как боты растут, и растёт количество серверов, некоторые разработчики могут посчитать нужным разбавлять или разделять операции ботов на несколько логических процессов. Поэтому, Discord gateway (то, к чему бот подключается через websockets для прослушивания событий, и контроля статуса) представляют метод разделения серверов пользователем, который допускает разделение событий на несколько подключений к gateway. Разделение серверов полностью контроллируется пользователем, и не требует общего доступа меж разных подключений для управления.
Шардирование (горизонтальное партиционирование) — это принцип проектирования базы данных, при котором логически независимые строки таблицы базы данных хранятся раздельно, заранее сгруппированные в секции, которые, в свою очередь, размещаются на разных, физически и логически независимых серверах базы данных, при этом один физический узел кластера может содержать несколько серверов баз данных.
discord.utils.get
вы получаете канал того сервера, в котором было написано сообщение.GLOBAL_CHAT = 'глобальный-чат' # PEP8: Названия констант пишутся капсом
@client.event
async def on_message(message):
channel = discord.utils.get(message.guild.text_channels, name=GLOBAL_CHAT)
if message.author.id == client.user.id:
return # return предотвратит выполнение следующего кода
if message.channel.id != channel.id:
return
await message.delete() # удаляем сообщение один раз
for guild in client.guilds:
if channel := discord.utils.get(guild.text_channels, name=GLOBAL_CHAT):
# py3.8: walrus operator ("моржовый" оператор)
# равносильно следующему:
# channel = discord.utils.get(guild.text_channels, name=GLOBAL_CHAT)
# if channel: ...
try:
await channel.send('**{0.author}:** {0.content}'.format(message))
except discord.Forbidden:
print(f"Невозможно отправить сообщение на сервер {guild.name}: Недостаточно прав")
except discord.HTTPException as e:
print(f"Невозможно отправить сообщение на сервер {guild.name}: {e}")
class MyClass:
@client.command()
async def _init_(sefl,ctx):
self.moder = None
embed = discord.Embed(
title='Это мой заголовок',
description='Это мой основной текст',
color=0x83c837)
self.moder = await ctx.send(embed=embed)
@client.command()
async def test(sefl,ctx):
await ctx.send(
self.moder
)
@commands.command()
async def clear(ctx, user: discord.Member):
await ctx.channel.purge(limit=None, check=lambda m: m.author==user)
class TodoList extends React.Component {
state = {
todos: [
'Commit',
'Push'
]
}
render() {
return <ul>
{this.state.todos.map(item => {
return <li>{ todo }</li>
}
</ul>
}
}
const todos = [
'Init',
'Commit',
'Push'
]
// Начальный стейт
<ul>
<li>Commit</li>
<li>Push</li>
</ul>
// Добавлен элемент
<ul>
<li>Init</li> // <- разница начинается здесь и до конца древа
<li>Commit</li>
<li>Push</li>
</ul>
const todos = [
'Commit',
'Push',
'Merge'
]
// Начальный стейт
<ul>
<li>Commit</li>
<li>Push</li>
</ul>
// Добавлен элемент
<ul>
<li>Commit</li>
<li>Push</li>
<li>Merge</li> <- разница начинается здесь, от начала и до сих по ничего не менялось
</ul>
<li>Commit</li>
и <li>Push</li>
не менялись, однако реакт недостаточно умён чтобы это понять. Чтобы помочь ему следует воспользоваться специальным пропом key={}
. Он может быть значением любого типа, единственно требование — значение должно стабильно идентифицировать соответствующие данные.class TodoList extends React.Component {
state = {
todos: [
{ id: 0, text: 'Commit' },
{ id: 1, text: 'Push' }
]
}
render() {
return <ul>
{this.state.todos.map(item => {
return <li key={todo.id}>{ todo.text }</li>
}
</ul>
}
}
const todos = [
{ id: 2, text: 'Init' },
{ id: 0, text: 'Commit' },
{ id: 1, text: 'Push' }
]
// Начальный стейт
<ul>
<li>Commit</li> // id 0
<li>Push</li> // id 1
</ul>
// Добавлен элемент
<ul>
<li>Init</li> // id 2 новый элемент отобразится в начале
<li>Commit</li> // id 0
<li>Push</li> // id 1
</ul>
Math.random()
в качестве ключа, так вы почти гарантировано будете всегда получать нестабильные идентификаторы.import os
from discord.utils import get
import youtube_dl
# Ржака и другие Voice Chat
# Join
@client.command()
async def join(ctx):
global voice
channel = ctx.message.author.voice.channel
voice = get(client.voice_clients, guild = ctx.guild)
if voice and voice.is_connected():
await voice.move_to(channel)
else:
voice = await channel.connect()
await ctx.send(f'Бот присоединился к каналу: {channel}')
# Leave
@client.command()
async def leave(ctx):
channel = ctx.message.author.voice.channel
voice = get(client.voice_clients, guild=ctx.guild)
if voice and voice.is_connected():
await voice.disconnect()
else:
voice = await channel.connect()
await ctx.send(f'Бот отключился от канала: {channel}')
# Музло
@client.command()
async def play(ctx, url : str):
song_there = os.path.isfile('song.mp3')
try:
if song_there:
os.remove('song.mp3')
print('[log] Старый файл удален')
except PermissionError:
print('[log] Не удалось удалить файл')
await ctx.send('Пожалуйста, ожидайте. Файл обрабатывается.')
voice = get(client.voice_clients, guild = ctx.guild)
ydl_opts = {
'format' : 'bestaudio/best',
'postprocessors' : [{
'key' : 'FFmpegExtractAudio',
'preferredcodec' : 'mp3',
'preferredquality' : '192'
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
print('[log] Загружаю музыку...')
ydl.download([url])
for file in os.listdir('./'):
if file.endswith('.mp3'):
name = file
print(f'[log] Переименовываю файл: {file}')
os.rename(file, 'song.mp3')
voice.play(discord.FFmpegPCMAudio('song.mp3'), after = lambda e: print(f'[log] {name}, музыка закончила свое проигрывание'))
voice.source = discord.PCMVolumeTransformer(voice.source)
voice.source.volume = 0.07
song_name = name.rsplit('-', 2)
await ctx.send(f'Сейчас проигрывает музыка: {song_name[0]}')