Dans cet article, nous allons créer plusieurs fois un Discord Bot en Python avec des capacités d'enregistrement à partir de zéro.
discord.py est une bibliothèque de wrapper pour l'API de Discord. Dans cet article, nous allons le diviser en plusieurs fois, de la création d'un Bot avec discord.py à l'ajout de vos propres fonctions. L'ordre est de commencer par la construction de l'environnement, d'implémenter un ensemble de fonctions, puis d'implémenter la fonction d'enregistrement.
En ajoutant des explications sur diverses choses, c'est devenu un article ridiculement long, alors j'ai décidé de le publier séparément.
Nous prévoyons d'écrire un total de 7 fois et avons fini d'écrire jusqu'à 5 articles.
Il peut y avoir une erreur dans la méthode d'implémentation dans cet article. Dans ce cas, veuillez l'indiquer dans la section des commentaires.
discord.py a toutes les fonctions qui peuvent atteindre l'endroit qui démange. Par exemple, lorsque vous voulez faire de la musique ** lecture ** Bot, vous devez à l'origine "vous authentifier avec WebSocket → vous connecter à WebSocket pour Voice Channel et vous préparer à envoyer de la voix → établir une connexion UDP et Opus encoder avec RTP Vous devez effectuer un traitement compliqué tel que "crypter et envoyer 20 ms de données musicales" [^ 1], mais ce discord.py a toutes ces fonctions implémentées et peut être utilisé facilement.
[^ 1]: Vous n'avez pas besoin de lire maintenant l'intérieur de ce support de clé. Il est normal de reconnaître que vous faites des choses difficiles.
Cependant, concernant la fonction ** enregistrement ** (réception de données audio),
https://github.com/Rapptz/discord.py/issues/1094
Comme mentionné dans ce numéro, il y a eu des demandes de mise en œuvre depuis plusieurs années, mais la RP au chef de famille n'a pas encore été effectuée. Pour le moment, la fonction d'enregistrement elle-même semble être implémentée dans Discord.js, qui est un wrapper pour la version JS. Si ce n'était pas impossible, j'ai essayé de l'implémenter moi-même, alors j'ai commencé à penser à écrire un article d'introduction sur discord.py avec une introduction.
Veuillez consulter ici pour Pipenv.
Veuillez voir ici pour docker-compose.
Tout d'abord, créez un bot à partir du [portail de développement] de Discord (https://discord.com/developers/applications). Créez un nom à partir de la nouvelle application. (Le nom du Bot est DBot ici)
Lorsque la création est terminée, l'écran ressemblera à ceci. Vous pouvez également modifier l'image de l'icône.
Ensuite, émettez les jetons requis pour créer le Bot. Si ce jeton est divulgué ** Par exemple, si le jeton est divulgué pour un bot avec des privilèges d'administrateur, un tiers peut faire fonctionner le serveur avec les privilèges d'administrateur pour tous les serveurs auxquels le bot est ajouté. Ce sera possible. Il est nécessaire de le gérer avec le plus grand soin afin qu'il ne fuit jamais. ** **
Pour émettre un token, sélectionnez [Add Bot] dans le menu Bot.
Pour le jeton Bot, cliquez sur le bouton ci-dessous à partir de l'écran après avoir créé l'écran Bot.
Ceci termine la création du Bot, mais l'URL d'authentification pour l'ajout du Bot au serveur n'a pas été émise. Vous pouvez émettre l'URL d'authentification à partir du menu OAuth2.
Dans SCOPE, sélectionnez bot et dans BOT PERMISSIONS, sélectionnez Bot autorité. Il n'y a aucun problème si vous mettez l'autorité "Administrateur" dans la phase de développement. Il existe de nombreux Bot existants qui nécessitent un administrateur, mais cela peut donner une impression légèrement dangereuse simplement parce que c'est un bot qui nécessite des privilèges d'administrateur, il peut donc être nécessaire de le réviser lorsqu'il est ouvert au public.
Vous pouvez inviter le Bot sur le serveur en cliquant sur l'URL qui apparaît au centre de l'écran. ** Pour installer Bot, vous devez disposer de l'autorité de gestion du serveur que vous souhaitez installer. ** [^ 2]
[^ 2]: propriétaire du serveur ou utilisateur avec le rôle "d'administrateur" ou "d'administrateur de serveur"
Dans ce projet, nous développerons sur la base de la structure de répertoires suivante. Vous n'avez pas encore besoin de le créer car il sera créé dans l'ordre.
.
|- src #Toutes les racines du code source pour les services
| |- app #Code source de l'application
| | |- [bot name] #Choisissez le nom du Bot comme vous le souhaitez.
| | | |- cogs # discord.Collectez des fichiers pour ajouter des fonctions à py dans ce dossier
| | | |- core #La définition de Bot lui-même, les fonctions auxiliaires, les extensions, etc. sont résumées ici.
| | | |- __init__.py #Traiter comme un module
| | | |- __main__.py #Fichier pour le démarrage
| | |
| | |- config.ini #Différents réglages sont effectués à l'extérieur du module
| | |- Pipfile # (Il est généré automatiquement pour que vous n'ayez pas à le créer)
| | |- entrypoint.dev.sh
| |
| |- dev.dockerfile
|
|- docker-compose.dev.yml
Si vous voulez simplement l'exécuter, vous n'avez besoin que d'un seul fichier, mais ici nous avons une structure de répertoires légèrement compliquée en supposant que vous souhaitez exécuter un service plus important.
Tout d'abord, exécutez Python. Créez un environnement virtuel avec Pipenv et exécutez Bot dans cet environnement.
$ mkdir src
$ cd src
$ mkdir app
$ cd app
$ mkdir dbot
$ echo 'print("Yay")' > ./dbot/__main__.py
$ pipenv --python 3.8.2
Ceci complète l'environnement Python. J'utilise un nom de fichier spécial appelé __main __. Py
, mais en écrivant du code Python dans ce fichier L'appel à __main __. Py
#Si Python est à l'origine sur votre PC
$ python -m dbot
Yay
#Lors de l'exécution dans l'environnement Pipenv créé
$ pipenv run python -m dbot
Vous pouvez le faire avec. Si vous souhaitez exécuter votre propre module, celui-ci est plus propre et meilleur.
Maintenant que vous pouvez exécuter le code Python, installons en fait discord.py et faisons fonctionner Bot.
J'ai divisé les répertoires en détail dans la section précédente, mais dans cet article, le but est de vérifier le fonctionnement, donc j'écrirai tout le code dans __main __. Py
.
$ pipenv install discord.py[voice]
Une fois l'installation terminée, éditez __main __. Py
avec un éditeur.
__main__.py
import discord
#Une chaîne de caractères comme celle-ci est un jeton(Le jeton ci-dessous convient)
TOKEN = "MTE0NTE0MzY0MzY0ODEwOTMx.Adiade.Oosak0_Majide_Hampana1tteee"
#Créer un objet pour déplacer le Bot
client = discord.Client()
@client.event
async def on_ready():
#Cette fonction est appelée lorsque le Bot est prêt à démarrer
print("Commencé")
@client.event
async def on_message(message):
#Cette fonction est affiché lorsqu'un message est envoyé
#Message contient diverses informations sur le message envoyé par l'utilisateur.
#Ne répondez pas aux messages du Bot
if message.author.bot:
return
print("Le message a été envoyé")
print("expéditeur", message.author.display_name)
print("Contenu", message.content)
#Si une phrase avec le contenu Yay est envoyée...
if message.author != client and message.content == 'Yay':
#Renvoyer le message au canal auquel le message a été envoyé
await message.channel.send("You're on discord.py!")
client.run(TOKEN)
Si vous pouvez entrer jusqu'à ce point, enregistrez-le et réexécutez.
Quand il démarre et que la console affiche «Démarré», essayez de taper le mot Yay sur le serveur où le Bot est réellement installé.
Ce qui suit est affiché sur la console.
$ pipenv run python -m dbot
Commencé
Le message a été envoyé
Administrateur de l'expéditeur
Contenu Yay
Yay! You're on discord.py!
C'est un code très court, mais c'est suffisant pour faire fonctionner un simple Bot. Voici quelques suppléments.
Dans ce code, il y a des endroits où @ client.event
est attaché au-dessus de la fonction [^ 3] appelée ʻa sync def on_Nanchara`. Ceux-ci sont basés sur les fonctions de Python, et chacun d'eux
[^ 3]: Strictement parlant, ʻa sync def ~~ `est une fonction collout
async
~ await
@client.event
--@
est une fonction appelée décorateurIl y a une fonction / une signification. Si vous êtes un débutant, il est normal de reconnaître que vous devez écrire ceci pour le moment.
En ajoutant un décorateur @ client.event
à une fonction qui commence par ʻon_, comme ʻon_ready
, ʻon_message`, ** lorsqu'un événement spécifique se produit **, ** effectuer un traitement spécifique **, etc. Peut être facilement décrit. Une liste des événements pris en charge peut être trouvée sur la page de référence de l'API (il y en a plusieurs).
https://discordpy.readthedocs.io/ja/latest/api.html#event-reference
De plus, il y a des endroits où ʻawait est utilisé pour appeler des fonctions, mais comment déterminer si une fonction nécessite ʻawait
est Page de référence. Dans l'explication de la fonction de /latest/api.html)
This function is a coroutine.
S'il y a un endroit où il est écrit, la fonction doit être préfixée avec ʻawait`.
De plus, dans discord.py, des informations telles que le contenu du message et l'expéditeur du message peuvent être acquises en tant que propriétés de classe. Par conséquent, même si vous ne connaissez pas l'état réel du code, il est facile de comprendre quel type de traitement est effectué simplement en regardant le code. D'autre part, jusqu'à ce que vous vous y habituiez, vous devez regarder quelle propriété ou méthode se trouve dans quelle classe comme référence. ([Supplément](# 1-% E3% 82% 88% E3% 81% 8F% E4% BD% BF% E3% 81% 86% E3% 82% AF% E3% 83% A9% E3% 82% B9% E3% 81% A8% E3% 82% A4% E3% 83% 99% E3% 83% B3% E3% 83% 88) présente certaines des classes discord.py.)
Bref, si vous avez des ennuis, jetez un œil à la référence. La réponse est à 95% là-bas. ** RTFM !!! **
De plus, ici, nous avons défini l'événement en instanciant directement discord.Client
, mais le même traitement est possible même si vous définissez votre propre classe qui hérite de discord.Client
. (Cette méthode d'écriture est utilisée pour la page de référence.)
__main__.py
import discord
TOKEN = "..."
class Bot(discord.Client):
async def on_ready(self):
print("Commencé")
async def on_message(self, message):
if message.author.bot:
return
print("Le message a été envoyé")
print("expéditeur", message.author.display_name)
print("Contenu", message.content)
if message.content == 'Yay':
await message.channel.send("You're on discord.py!")
Bot().run(TOKEN)
Pour le moment, exécutons ce service sur le conteneur Docker, en supposant que nous ajouterons des fonctions Bot plus tard.
Créez trois types de fichiers liés à Docker comme indiqué dans l'exemple de configuration de répertoire au début. Comme il s'appelle dev
, nous envisageons de séparer l'environnement pendant le développement et la production.
Comment écrire Dockerfile
est [cet article](https://qiita.com/Aruneko/items/796d7eeb61e1f36ae4a0#dockerfile%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96% Après B9), créez une image à exécuter après avoir installé le package Python avec builder.
dev.dockerfile
FROM python:3.8 as builder
WORKDIR /bot
RUN apt update -y && \
apt upgrade -y
COPY ./app/Pipfile ./app/Pipfile.lock /bot/
RUN pip install pipenv && \
pipenv install --system
FROM python:3.8-slim
WORKDIR /bot
RUN apt update -y && \
apt upgrade -y && \
apt install -y nodejs npm curl && \
npm install -g n && \
n stable && \
apt purge -y nodejs npm && \
apt install -y ffmpeg && \
apt autoremove -y
RUN npm install -g nodemon
ENV PYTHONBUFFERED=1
COPY --from=builder /usr/local/lib/python3.8/site-packages /usr/local/lib/python3.8/site-packages
COPY . /bot
Dans la partie construction de l'image pour l'exécution, nodemon et ffmpeg sont installés au milieu. nodemon est utilisé pour détecter les modifications de fichiers et redémarrer sans avoir à arrêter et redémarrer le Bot pendant le développement, et ffmpeg est utilisé pour effectuer des traitements liés aux médias tels que la lecture de musique.
ʻEntrypoint.dev.sh` commence à utiliser nodemon.
shell:entrypoint.dev.sh
nodemon --signal SIGINT -e py,ini --exec python -m dbot
Enfin, écrivez docker-compose.dev.yml
comme suit
yml:docker-compose.dev.yml
version: "3.8"
services:
dbot:
build:
context: ./src
dockerfile: dev.dockerfile
tty: true
working_dir: /bot/app
entrypoint: bash ./entrypoint.dev.sh
volumes:
- ./src:/bot
Avec ces paramètres, le src
suivant sera monté sur le bot
du conteneur, et lorsque le script est mis à jour sur l'hôte, le changement sera détecté et le Bot sera redémarré. En utilisant l'environnement docker, il est possible de l'étendre facilement lorsque vous souhaitez ajouter une base de données ou une façade Web ultérieurement.
Après avoir écrit jusqu'à présent, revenez à la racine du projet et exécutez la commande suivante.
$ chmod +x ./src/app/entrypoint.dev.sh
$ docker-compose -f docker-compose.dev.yml -p dev build #Créer une image
$ docker-compose -f docker-compose.dev.yml -p dev up #Commencez
Il a une longue description de docker-compose -f docker-compose.dev.yml -p dev
, mais il est nécessaire de le décrire comme ceci car l'environnement est divisé. Si c'est gênant, vous pouvez être heureux si vous créez un script comme celui-ci
run.sh
#!/bin/bash
cmd="docker-compose -f docker-compose.$1.yml -p $1 ${@:2}"
echo $cmd
eval $cmd
$ ./run.sh dev build
$ ./run.sh dev up
Après avoir confirmé le démarrage, éditons __main __. Py
comme un essai.
dbot_1 | [nodemon] 2.0.4
dbot_1 | [nodemon] to restart at any time, enter `rs`
dbot_1 | [nodemon] watching path(s): *.*
dbot_1 | [nodemon] watching extensions: py,ini
dbot_1 | [nodemon] starting `python -m dbot`
dbot_1 |Commencé
dbot_1 | [nodemon] restarting due to changes...
dbot_1 | [nodemon] starting `python -m dbot`
dbot_1 |Il a commencé
Détectant la sauvegarde, le Bot a été redémarré. Cela permet d'améliorer considérablement l'efficacité du développement.
Dans cet article, nous avons mis en place un environnement adapté à la construction et au développement de Bot de base.
La prochaine fois, j'expliquerai la conception pour créer un bot plus grand et les éléments intégrés qui ne sont pas présentés dans cet article.
Tous les arguments de fonction ne sont pas répertoriés, mais seuls les arguments fréquemment utilisés sont sélectionnés.
discord.Message
https://discordpy.readthedocs.io/ja/latest/api.html#message
Nom de la propriété | Moule | La description |
---|---|---|
id | int | Identifiant unique |
author | discord.Member | La personne qui a publié le message |
content | str | Contenu du message |
guild | discord.Guild | Le serveur sur lequel le message a été publié(guilde) |
channel | Si c'était dans le serveurdiscord.TextChannel | La chaîne sur laquelle le message a été publié(DM etc. sera une autre classe, mais je ne le mentionnerai pas ici) |
mentions | List[discord.Member] | Liste des personnes qui ont ignoré les mentions |
reactions | List[discord.Reaction] | Réaction du pictogramme au message |
created_at | datetime.datetime | Date et heure de publication |
edited_at | Optional[datetime.datetime] | Modifier la date et l'heure(Si non éditéNone ) |
jump_url | str | Lien pour accéder à ce message |
await delete()
await edit(content: str, ...)
edit (content = "hoge") code>. jj>
- Ce doit être un message posté par Bot lui-même. jj>
attendre add_reaction (emoji: str etc.) code> dt>
- Ajouter une réaction au message dd>
- Les pictogrammes Unicode peuvent être saisis tels quels: ramen: dd>
attendez remove_reaction (emoji: str etc., membre: discord.Member) code> dt>
- Supprimer la réaction de pictogramme spécifiée du membre spécifié dd>
attend clear_reaction (emoji: str etc.) code> dt>
- Supprimer la réaction de pictogramme spécifiée dd>
discord.Member
Nom de la propriété | Moule | La description |
---|---|---|
id | int | Identifiant unique |
name | str | Nom d'utilisateur |
nick | Optional[str] | Nom défini sur le serveur |
display_name | str | S'il y a nick, nick,Si ce n'est pas le nom |
mention | str | Une chaîne pour mentionner un membre |
guild | discord.Guild | Le serveur auquel appartient le membre |
roles | List[discord.Role] | Liste de tous les rôles des membres |
top_role | discord.Role | Meilleur rôle du membre |
avatar_url | str | URL de l'image de l'avatar |
joined_at | datetime.datetime | Date et heure auxquelles le membre a rejoint le serveur |
created_at | datetime.datetime | La date à laquelle le membre a enregistré le compte Discord |
La raison de la méthode suivante est affichée dans le journal d'audit.
await ban(reason: Optional[str], ...)
await unban(reason: Optional[str], ...)
await kick(reason: Optional[str], ...)
await add_roles(*roles: discord.Role)
await remove_roles(*roles: discord.Role)
discord.TextChannel
Nom de la propriété | Moule | La description |
---|---|---|
id | int | Identifiant unique |
name | str | Nom du canal |
guild | discord.Guild | Serveur avec canal |
members | List[discord.Member] | Liste des membres autorisés à voir la chaîne |
mention | str | Une chaîne à mentionner à la chaîne |
created_at | datetime.datetime | Date et heure de création |
await send(content: str, embed: discord.Embed, file: discord.File)
await purge(limit: int, check)
history(limit: int = 100) -> AsyncIterator
Appelez ʻasync for ... in ~~ `comme suit.
async for message in channel.history():
print(messane.author.name)
discord.Guild
Nom de la propriété | Moule | La description |
---|---|---|
id | int | Identifiant unique |
name | str | nom du serveur |
icon_url | str | URL de l'icône du serveur |
owner | discord.Member | Propriétaire du serveur |
member_count | int | Nombre de membres |
text_channels | List[discord.TextChannel] | Tous les canaux de texte du serveur |
members | List[discord.Member] | Tous les membres du serveur |
roles | List[discord.Role] | Tous les rôles sur le serveur |
emojis | List[discord.Emoji] | Liste des pictogrammes créés par le serveur |
created_at | datetime.datetime | Date et heure de création |
Il existe différentes méthodes, mais je les présenterai plus tard.
<! - Lier la colonne des pièces jointes ci-dessous->
Recommended Posts