Пишем чат с анализом настроения с помощью Next.js
Это руководство помогает создать очень простое приложение чата со эмоциональным анализом с помощью модулей Next.js (React), Pusher и Sentiment Node. Несмотря на то, что здесь затрагиваются лишь основы, есть множество продвинутых инструментов, которые помогут вам создать более продвинутое приложение чата.
13К открытий13К показов
Приложения, работающие в режиме реального времени существуют довольно давно. Их можно увидеть на примере мультиплеерных игр, сервисов для совместной работы, служб обмена сообщениями, инструментов анализа данных в реальном времени и т. п. Отдельные технологии разрабатывались на протяжении многих лет, чтобы упростить наиболее сложные аспекты создания приложений, зависящих от изменений в реальном времени.
Данный материал поможет вам создать простой чат, анализирующий эмоции человека по словам в его сообщениях.
Подготовка
Перед началом, убедитесь, что на вашей машине установлены Node и npm (или Yarn). Вот краткий обзор основных инструментов, которые будут нужны для создания чата:
- Next.js — фреймворк для приложений на платформе React, использующих серверный рендеринг (SSR). Он решает большинство проблем, возникающих при создании React-проектов с SSR .
- Pusher — инструмент для создания приложений, работающих в режиме реального времени, с помощью push-уведомлений и сообщений типа издатель-подписчик. Это основа будущего приложения.
- Sentiment — модуль, который использует базу слов AFINN-165 и классификацию Emoji Sentiment Ranking для эмоционального анализа по произвольным блокам входного текста.
- React — популярный JavaScript-фреймворк для создания масштабируемых веб-приложений с использованием компонентной архитектуры.
- Некоторые другие библиотеки, которые будут рассмотрены ниже.
Установка зависимостей
Создайте новый каталог и выполните следующие команды, чтобы установить необходимые зависимости для приложения.
Установка переменных окружения
В панели управления Pusher создайте новое приложение (есть бесплатный тариф), чтобы получить его учётные данные. Затем создайте файл .env
в корневом каталоге вашего приложения и добавьте в него полученные данные следующим образом:
Убедитесь, что вы используете имена переменных, которые указаны в приведённом выше фрагменте, т. к. далее вы будете ссылаться на них в нескольких местах кода.
После этого, создайте файл конфигурации Next.js с именем next.config.js в корневом каталоге приложения со следующим содержимым:
Поскольку Next.js использует Webpack для загрузки и обвязки модулей, необходимо настроить его, чтобы использовать переменные окружения, которые были определены выше, и сделать их доступными для компонентов React с помощью доступа к объекту process.env
.
Первые шаги
Настройка сервера
Настроим простой сервер, использующий Next.js. Также загрузим необходимые middleware (промежуточные функции обработки запроса) и настроим Pusher, используя учётные данные, добавленные ранее в переменные окружения.
Создайте файл server.js в корневом каталоге приложения и добавьте в него следующий фрагмент кода для настройки сервера:
Изменение скриптов npm
Измените блок scripts
в файле package.json так, чтобы файл выглядел следующим образом:
Всё необходимое для создания компонентов приложения готово. Если сейчас выполнить команду npm run dev
в терминале, то он запустит сервер на порте 3000, если, конечно, он доступен. Однако в браузере пока ничего не произойдёт, потому что на главной странице не создано ни одного компонента. Поэтому далее создадим компоненты приложения.
Создание index-страницы
Для работы Next.js нужно, чтобы компоненты страницы приложения находились в каталоге pages, поэтому добавим его в корневой каталог приложения и уже внутри него создадим новый файл index.js для главной страницы приложения.
Прежде чем поместить контент на главную страницу, добавим компонент Layout, который можно будет использовать на страницах приложения в качестве шаблона. Идём дальше и создаём каталог components в корне приложения. Помещаем новый файл Layout.js внутри только что созданного каталога со следующим содержимым:
Здесь мы используем компонент next/head
для добавления метаданных в заголовки всех страниц. Также добавляем ссылку на файл Bootstrap CDN, чтобы придать стиль приложению. Кроме всего прочего, заголовок страницы делаем динамическим и отображаем содержимое страницы используя {props.children}
.
Далее добавляем следующее содержимое в файл index.js, который был создан ранее:
Здесь для главной страницы приложения создаётся компонент IndexPage. Состояние компонента инициализируется с помощью пустого свойства user
. Свойство user
предназначено для хранения имени текущего активного пользователя.
Также здесь добавляется поле ввода для получения имени пользователя, если в данный момент оно не задано. Как только поле заполнено, имя сохраняется в свойстве user
по нажатию enter
или return
.
Если сейчас запустить приложение в браузере, можно увидеть следующее:
Создание компонента Chat
Добавим компонент Chat. Для этого создаём новый файл Chat.js в каталоге components и добавляем следующее содержимое:
Давайте разберёмся, что было сделано выше:
- Сначала инициализируется состояние компонента, чтобы оно вмещало пустой массив
chats
. Этот массив будет заполняться сообщениями по мере их поступления. Как только компонент установлен, внутри методаcomponentDidMount()
устанавливается соединение с Pusher. - Присоединяемся к Pusher-каналу с именем
chat-room
. Затем подписываемся на событиеnew-message
, которое запускается при поступлении нового сообщения в чат. После просто заполняемchats
, добавляя новый чат. - В том же методе
componentDidMount()
подписываемся на событиеconnected
, чтобы извлечь все сообщения чата из истории с помощью HTTP-запросаPOST/messages
и библиотекиaxios
, как только пользователь присоединился. После этого заполняемchats
сообщениями чата, полученными в ответ на запрос. - Компонент Chat ещё не завершён. Всё ещё необходимо добавить метод
render()
. Чтобы это сделать, добавьте следующий код в класс компонентаChat
:
Как видно из метода render()
, свойство activeUser
требуется для идентификации текущего активного пользователя. Также присутствует элемент <textarea>
, который необходим для ввода сообщения. К этому элементу добавлен обработчик событий onKeyUp
для отправки сообщения в чат при нажатии клавиш enter
или return
.
В обработчике handleKeyUp()
создаётся объект chat
, содержащий user
(текущий активный пользователь), message
(само сообщение) и timestamp
(время отправки сообщения). После нужно очистить поле <textarea>
и выполнить HTTP-запрос POST/message
, передавая объект chat
.
Теперь необходимо добавить компонент Chat на главную страницу. Сначала добавьте следующую строку к операторам import
в файле pages/index.js.
Затем установите метод render()
компонента IndexPage. Вставьте компонент Chat в пустой элемент <section>
. Он должен выглядеть следующим образом:
Теперь можно перезагрузить приложение в браузере, чтобы увидеть изменения.
Определение маршрутов чата
На данный момент при попытках отправить сообщение в чат ничего не происходит. Пока что нельзя увидеть ни сообщения, ни историю чата. Это потому, что ещё не реализованы два маршрута, к которым мы делаем запросы.
Создадим маршруты /message
и /messages
. Далее изменим файл server.js и добавим следующий код непосредственно перед вызовом server.listen()
внутри функции then()
.
Здесь создаётся своего рода хранилище для истории чата, чтобы хранить сообщения в массиве. Это полезно для новых пользователей, которые присоединяются к чату для просмотра предыдущих сообщений. Всякий раз, когда клиент отправляет POST-запрос к /messages
при подключении, он получает все сообщения в истории чата при ответе.
В запросе POST/message
приходит выборка данных из req.body
с помощью инструмента body-parser
, который мы добавили ранее. Затем используется модуль sentiment
, чтобы вычислить общую оценку настроения в сообщении. Далее изменяем объект chat
, добавив в него свойство sentiment
, содержащее оценку настроения.
Наконец, добавляем чат к истории чата в messages
, а затем запускаем событие new-message
в канале chat-room
, передавая объект chat
в событие.
Осталось всего несколько шагов, и приложение будет готово. Если перезагрузить приложение в браузере сейчас и попытаться отправить сообщение в чат, оно не будет отображено. Это не потому, что приложение не работает, оно работает отлично. Просто ещё не происходит вывод сообщений чата на экран.
Отображение сообщений чата
Создайте новый файл ChatMessage.js в каталоге components и добавьте в него следующее содержимое:
Компонент ChatMessage — простой компонент, требующий 2 свойства: message
— сообщение чата, и position
— положение сообщения справа или слева. Это полезно для размещения сообщений текущего пользователя на одной стороне экрана, а сообщений других пользователей — на другой.
Внесём следующие изменения в компонент Chat для отображения сообщений. Для этого изменим файл components/Chat.js.
Сначала добавим следующие константы перед определением класса компонента Chat
. Каждая константа представляет собой массив кодировок, обозначающих конкретный смайл Эмоджи. Также нужно убедиться, что компонент ChatMessage
импортирован.
Далее следует добавить следующий фрагмент кода между контейнером <div>
заголовка чата и контейнером <div>
окна сообщений, которое было создано ранее в компоненте Chat
.
Попробуем разобраться, что делает этот фрагмент кода. Сначала выполняется проход по каждому объекту chat
в массиве chats
. Затем выполняется проверка, совпадает ли отправитель сообщения с текущим пользователем, и определяется позиция сообщения в чате. Сообщения активного пользователя появляются справа.
Здесь также выполняется оценка sentiment
, чтобы установить настроение пользователя (весёлое, грустное или нейтральное) с использованием ранее определённых констант.
Имя пользователя отображается перед сообщением в чате на основе одного из следующих условий:
isFirst
— текущее сообщение является первым в списке.!inSequence
— текущее сообщение следует непосредственно за сообщением другого пользователя.hasDelay
— текущее сообщение имеет задержку более 1 минуты от предыдущего сообщения того же пользователя.- Также обратите внимание, как используется метод [String.fromCodePoint()], чтобы получить смайлики из кодировок, которые были определены в константах ранее.
Наконец, приложение чата завершено. Теперь можно проверить, как оно работает в браузере. Вот несколько скриншотов, показывающих чат между пользователями 9lad, Steve и Bob.
9lad
Steve
Bob
Заключение
Это руководство помогает создать очень простое приложение чата с эмоциональным анализом с помощью модулей Next.js (React), Pusher и Sentiment Node. Несмотря на то, что здесь затрагиваются лишь основы, есть множество инструментов, которые помогут вам создать более продвинутое приложение чата. Исходный код этого руководства можно найти на GitHub.
Также вы можете изучить документацию для каждого инструмента, который был использован в этом проекте, чтобы узнать больше о других способах реализации таких приложений.
13К открытий13К показов