Я хочу создать бота для разногласий, чтобы помогать изучать ИТ-материалы в разногласиях. Поэтому я научился создавать его из учебника Very Academy.
ОБЗОР ШАГОВ
I. Discord — создать бота
II.Django DRF — API
III. Логика бота
IV. Развертывание в Heroku
Начиная
I. Discord — создать бота
Сначала перейдите на https://discord.com/developers/applications, чтобы создать приложение.
Проверьте разрешения бота на вкладке «бот». Затем проверьте списки, чтобы подать заявку на вашего бота.
Затем перейдите на вкладку OAuth2.
Генератор URL-адресов OAuth2
Создайте ссылку-приглашение для своего приложения, выбрав области и разрешения, необходимые для его работы. После проверки нужных списков вы получите ссылку и скопируете этот URL-адрес для авторизации.
Создайте новый каталог в IDE для этого бота-викторины.
Создайте файл, например, «quizbot.py»
Создание API Django
Откройте терминал, мы создадим небольшой контейнер и будем работать в этой легкой виртуальной среде. Это гарантирует, что все, что мы делаем, не будет прерывать основную среду.
> py -m venv {namesomething}
После ввода этой команды будет создана папка для работы в этой среде.
Затем активируйте эту виртуальную среду с помощью команды:
>venv\Scripts\activate
Войдите, и вы увидите зеленый (venv), что означает, что все, что мы здесь делаем, будет работать с этой виртуальной средой.
Установите пакет, который позволит нам взаимодействовать с разногласиями.
(venv) PS …> pip install discord.py
Подключение к нашему раздору с использованием этого пакета.
import discord client = discord.Client()
Бот работает в событиях, мы будем описывать событие с помощью асинхронного программирования.
Создайте первое событие
В канале разногласий, когда сообщение было отправлено, это событие будет обнаружено нашим ботом, и мы сможем отправить ответ с сообщением.
Если сообщение отправлено самим ботом, оно попадет в цикл, поэтому мы предотвратим в первом операторе if ничего не возвращать или игнорировать это.
Для второго оператора if, если сообщение было отправлено не ботом, а пользователь вводит «привет» в канал чата, наш бот ответит «Привет, я бот».
Протестировать первое событие
Скопируйте и вставьте токен с сайта discord.com/developers/application на вкладке «Бот» вашего приложения.
client.run( ‘YOUR_APP_TOKEN’ )
Вам нужно поместить этот токен в другое место и не фиксировать его в репозитории Git из соображений безопасности, но пока мы оставим его здесь.
В терминале запустите команду Python, чтобы запустить нашего бота.
py quizbot.py
Если все работает, то на канале дискорда вы увидите, что наш бот включен.
II.Django DRF — API
Создайте приложение Django
>pip install django
Создать новую папку
Мы можем использовать команду администратора для создания проекта.
> django-admin startproject quizbot
Создайте новое приложение внутри папки
Внутри нового каталога, который мы только что создали, снова используйте команду администратора и создайте в нем новую папку. Таким образом, мы можем работать в меньшем куске.
> cd quizbot > django-admin startapp quiz
Внутри папки quizbot откройте settings.py.
И внутри INSTALLED_APP добавьте имя приложения следующим образом:
INSTALLED_APPS =[ ‘quizbot.quiz’ ]
Внутри quizbot › викторина › apps.py
Измените имя на:
name = ‘quizbot.quiz’
Создать базу данных
quizbot›викторина›models.py
Здесь мы создадим нашу базу данных викторин.
Вот пример кода, в котором вы можете определить {название, баллы и сложность} «Вопроса».
from django.db import models from django.utils.translation import ugettext as _ # Create your models here. class Question(models.Model): LEVEL = ( (0, _(‘Any’)), (1, _(‘Beginner’)), (2, _(‘Intermediate’)), (3, _(‘Advanced’)), (4, _(‘Expert’)) ) title = models.CharField(_(‘title’), max_length=255) points = models.SmallIntegerField(_(‘points’)) difficulty = models.IntegerField(_(‘Difficulty’), choices=LEVEL, default=0) is_active = models.BooleanField(_('Is Active'), default=True) created_at = models.DateTimeField(_('Created'), auto_now=False, auto_now_add=True) updated_at = models.DateTimeField(_('Updated'), auto_now=True, auto_now_add=False)
Создайте новую модель для «Ответа»
Ответ должен быть связан с вопросом, нам понадобится «ForeignKey» для связи с вопросом. Этих ответов не может быть, если нет вопросов.
class Answer(models.Model): question = models.ForeignKey(Question, related_name='answer', verbose_name=_("Question"), on_delete=models.CASCADE) answer = models.CharField(_('Answer'), max_length=255) is_correct = models.BooleanField(_("Correct Answer"), default=False) is_active = models.BooleanField(_('Is Active'), default=True) created_at = models.DateTimeField(_('Created'), auto_now=False, auto_now_add=True) updated_at = models.DateTimeField(_('Updated'), auto_now=True, auto_now_add=False)
Внести в базу
Откройте терминал из корневого каталога.
Готов к миграции в базу данных.
> py manage.py makemigrations
Теперь перейдите в базу данных
> py manage.py migrate
Создайте суперпользователя для входа с нашей машины и создания вопросов.
> py manage.py createsuperuser
Введите имя пользователя, адрес электронной почты, пароль.
Затем включаем наш проект на сервер.
> py manage.py runserver
Откройте localhost:8000/admin, введите свое имя пользователя и пароль.
У нас есть только 2 таблицы по умолчанию, поэтому мы добавим новую таблицу.
викторина›викторина›admin.py
Чтобы получить доступ к нашим моделям
from . import models
Зарегистрировать стол
from django.contrib import admin from . import models # Register your models here. #build data at one area using TabularInline, cuz we don't want to seperately create a question and answer class AnswerInlineModel(admin.TabularInline): model = models.Answer fields = [ 'answer', 'is_correct', ] @admin.register(models.Question) class QuestionAdmin(admin.ModelAdmin): fields = [ 'title', 'points', 'difficulty' ] list_display = [ 'title', 'updated_at', ] inlines = [ AnswerInlineModel, ] @admin.register(models.Answer) class AnswerAdmin(admin.ModelAdmin): list_display = [ 'answer', 'is_correct', 'question' ]
Откройте localhost, и вы должны увидеть новую таблицу.
Сделайте первый вопрос
{ P.S. Если вы пропустите опечатку в файле models.py в каком-либо месте, вы можете выполнить миграцию и перенести ее снова.
Установите фреймворк Django Rest.
> pip install djangorestframework
В настройках.py
и внутри INSTALLED_APP добавьте остальную структуру, как показано ниже:
INSTALLED_APPS =[ ‘quizbot.quiz’, ‘rest_framework’ ]
Теперь нам нужно предоставить способ, позволяющий нашим данным собираться из базы данных, а затем отправляться таким образом, чтобы наш бот мог их использовать и понимать, а затем отправлять их в канал разногласий.
Сериализаторы
Сериализатор позволяет приложению получать информацию из нашей базы данных и преобразовывать ее в другой формат, который понимает и может использовать другое приложение.
Создайте новый файл с именем «serializers».
В сериализаторе нам нужно определить данные, которые мы хотим отправить обратно.
Бот сделает запрос к API и определит, какие данные отправлять обратно в API.
Данные здесь — это «ответ», поэтому мы можем узнать ответ и отобразить его пользователю и «вопросу» одновременно.
from rest_framework import serializers from .models import Question, Answer class AnswerSerializer(serializers.ModelSerializer): class Meta: model = Answer fields = [ 'id', 'answer', 'is_correct', ] class RandomQuestionSerializer(serializers.ModelSerializer): answer = AnswerSerializer(many=True, read_only=True) class Meta: model = Question fields = [ 'title','answer' ]
URL-адрес сборки
quizbot›urls.py
Импорт просмотров
from .quiz.views import RandomQuestion
Также в urlpatterns = [ .. ]
Добавьте путь:
path(‘api/random/’,RandomQuestion.as_view(), name=’random’),
Создать вид
quizbot›викторина›views.py
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from .models import Question from .serializers import RandomQuestionSerializer # Create your views here. class RandomQuestion(APIView): def get(self, request, formate=None , **kwargs): question = Question.objects.filter().order_by('?')[:1] serializer = RandomQuestionSerializer(question,many=True) return Response(serializer.data)
Теперь запустите сервер и проверьте:
>py manage.py runserver
В локальном хосте: 8000/api/random/
Если у вас есть несколько вопросов, и вы нажмете, чтобы перезагрузить страницу, вы увидите, что она выбрала случайный вопрос, возвращенный вам.
III. Логика бота
В корневом терминале установите пакет Python для запросов.
> pip install requests
quizbot.py
import discord import requests import json client = discord.Client() def get_question(): qs = '' id = 1 answer = 0 response = requests.get("http://127.0.0.1:8000/api/random/") json_data = json.loads(response.text) qs += "Question: \n" qs += json_data[0]['title'] + "\n" for item in json_data[0]['answer']: qs += str(id) + "." + item['answer'] + "\n" if item['is_correct']: answer = id id += 1 return(qs, answer) @client.event async def on_message(message): if message.author == client.user: return if message.content.startswith('it!quiz'): qs, answer = get_question() await message.channel.send(qs) client.run('YOUR_APP_TOKEN')
ТЕСТИРОВАНИЕ
1. Запустите сервер
> py manage.py runserver
2. Запустите бота
>py quizbot.pz
Проверить ответ от пользователя
установить асинкио
› pip установить asyncio
Не забудьте импортировать asyncio сверху
и добавьте это в quizbot.py
import asyncio def check(m): return m.author == message.author and m.content.isdigit() try: guess = await client.wait_for('message', check=check, timeout=5.0) except asyncio.TimeoutError: return await message.channel.send('Timeout')
P.S. это Python, поэтому нам нужно быть очень точными в том, как мы выравниваем код! В противном случае вы получите ошибку
Проверьте это снова
Добавьте логику, чтобы сообщить пользователю, правильно ли он ответил
if int(guess.content) == answer: await message.channel.send(‘You got it right!’) else: await message.channel.send(‘Try again’)
И снова тестирование
запустить › py quizbot.py
Наконец, мы подошли к последней части этого урока.
IV. Развертывание в Heroku
- Во-первых, вам нужна учетная запись в Heroku, поэтому создайте ее.
- Установите Heroku CLI, я установил Wins64.
3. Установите Git, он установится автоматически.
После установки обязательно сохраните все и перезапустите VScode (если вы используете эту IDE)
Откройте Vscode и проверьте, все ли установлено.
> git --version > heroku --version cd {to the right directory} || if you're at the right dir -> skip git init
Мы не хотим включать «venv» в git
Создайте новый файл «.gitignore», чтобы игнорировать файлы/папки, которые мы не собираемся помещать в репозиторий и загружать в Heroku.
git add . git commit -m "commit"
Войдите в Heroku и создайте новое приложение
heroku login heroku create
Когда вы войдете в Heroku create, обновите страницу Heroku, и вы увидите новое приложение.
Измените этот URL-адрес на URL-адрес вашего нового приложения, это будет что-то вроде
“http://…..herokuapp.com/api/random”
quizbot›settings.py
Разрешить, где он может работать на Heroku и локальном хосте.
Мы внесли изменения, поэтому добавьте и зафиксируйте эти изменения в репозитории git.
git add . git commit -m "commit changes" git push heroku master
Последняя команда не работает.
Нам нужно создать новые файлы, чтобы это заработало.
Установите сервер для запуска нашего приложения Django на Heroku.
В терминале в корневом каталоге
> pip install gunicorn
Тогда беги,
>pip freeze > requirements.txt
Скажите Джанго запустить этот сервер
Создайте новый файл с именем «Procfile».
Создайте новую папку под названием «static» с файлом «txt.txt».
Внесите некоторые изменения в quizbot›settings.py.
import os
Прокрутите вниз и вставьте это под STATIC_URL = «/static/»
STATIC_URL = os.path.join(BASE_DIR, «статический»)
STATIC_ROOT = os.path.join(BASE_DIR, "static")
Снова добавить и зафиксировать изменения
git add . git commit -m "commit changes" git push heroku master
Если вы видите «сжатие» после нажатия, это работает.
ТЕСТИРОВАНИЕ
На URL вашего приложения
https://…...herokuapp.com/api/random/
> py quizbot.py
И еще раз протестируйте в Discord канале.
Наконец, сделайте наш API полностью онлайн на сервере Heroku.
> heroku run bash > $ ls > $ python quizbot.py
ПРОБЛЕМЫ
Heroku бесплатен, сервер временно отключается, и в любое время, когда вам нужно обслужить, все, что вам нужно сделать, это отправить запрос, а получение вопроса занимает больше времени.
ЗАКОНЧЕННЫЙ!
Спасибо за ваше время.
Больше контента на plainenglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку здесь.