You are on page 1of 19
anor ‘Build A Chat App With Sentiment Analysis Using Nex!js Images haven't loaded yet. Please exit printing, wait for images to load, and try to a print again. low me el m oe SS hun 12. 13 min read Build A Chat App With Sentiment Analysis Using Next.js Build a realtime chat application with Pusher ‘This eutorial was written by Chris Nwamba and originally appeared on the Pusher Blog. Realtime applications have been around for quite a long time as we can see in contexts such as multi-player games, realtime collaboration services, instant messaging services, realtime data analytics tools, to ‘mention a few. As a result, several technologies have been developed over the years to tackle and simplify some of the most challenging aspects of building apps that are sensitive to changes in realtime. In this tutorial, we'll build a very simple realtime chat application with sentiments, With sentiment analysis, we will be able to detect the mood of a person based on the words they use in their chat messages. Prerequisites Before you begin, ensure that you have Node and npm or Yarn installed on your machine. Here is a run-down of the core technologies we will be using. hitps:icodeburst obits chat-app-with-sentiment-analysis-using-nextjs-c43ebt3ea643 sno anor Build A Chat App With Sentiment Analysis Using Next js 1. Nextis—A framework for building server-side rendered(SSR) React applications with ease. It handles most ofthe challenges that come with building SSR React apps. 2. Pusher Pusher is a technology for building apps with varying realtime needs like push notifications and pub/sub messaging. It is the engine behind the realtime ability of our comments widget. 3. Sentiment—Sentiment is a module that uses the AFINN-165 ‘wordlist and Emoji Sentiment Ranking to perform sentiment analysis on arbitrary blocks of input text. 4. React—A very popular JavaScript DOM rendering framework for building scalable web applications using a component-based architecture. 5. Afew other libraries will be used as we will see in a moment. Also ensure that you have Node installed on your machine. Installing dependencies Create a new directory for the application and run the following command to install the required dependencies for the app. + create a new directory mkdir realtime-chat~app + Initiate a new pact and install app depend pm ie ppm i 1 react rea: npm install express hod! Setting environment variables Create a new application on your Pusher Dashboard to get your application credentials. Create a .env file in the root directory of your application and add your application credentials as follows. hitpsicodeburstiovbulle chatapp-with-sentiment-analysis-using ana anor hitpsicodeburstiovbulle chatapp-with-sentiment-analysis-using Build A Chat App With Sentiment Analysis Using Next js PUSHER APP_SECRET=YOUR_APP_SECRET Ensure that you use the same variable names as specified in the above snippet. We will make reference to them at several points in our code. Next create a Next,js configuration filenamed nex:.config.js inthe root directory of your application with the following content: (+ next config.2 */ const webpai require (‘webpack') require (*dotenv") .config(}? nodule-exports = { webpack: config => { const env = Object-keys (process env} «reduce ( (acc, curr) > env.${eurs}*) = cel ‘proces: JSON. string! fy (process.env{curr]}; One config.plugins.pu: (now webpack.DefinePlugin (env) Since Next.js uses Webpack in the background for module loading and bundling, we are simply configuring Webpack to be able to provide the environment variables we have defined and make them available to our React components by accessing the process.env object. Getting started Seti ‘We will go ahead to set up a simple server using Next js to wrap an Express application server. We will also load the necessary ‘middlewares for the Express server and then we will configure Pusher g up the server using the credentials we added to our environment variables. Create a server. file in the root directory of your application and add the following code snippet to it to set up the server: ana anor ‘Build A Chat App With Sentiment Analysis Using Nex!js (+ serverje */ const cors = require(*cors"): const next = require(next"): const Pusher = require (*pusher"); const express ~ raquire('express') const bodyParser ~ require (‘bady-parser'); const dotenv = require (*dotenv") .configt) const Sentinent = require(*sentiment'): const dev = process.env.NODE_ENV [== *production'; const port = process env.PORT || 3009; const app = next ({ dev 12 const handler = app.getRequestiandlez ()7 const sentiment = new Sentiment (); // Ensure that your pusher credentials are properly set an the venv file 1/ Using the specified variables const pusher = new Pusher ( appld: process.env. PUSHER APP_1D, key: process. env. PUSHER APP KEY, Jecret: process.env.PUSHER APP_SECREZ, env. PUSHER_APP_CLUSTER, cluster: process: encrypted: ve ape-prepare() then (() => ( ver = express (); server use (cors ()) + server.use (bodyParser. json (1); server.use (body2arser-urlencoded(( extended: true server.get("*", (req, res) => { return handler(reg, res); ne sorver.listen(port, ex => { if (err) chrow err; console,log(*> Ready on /Locathost:$ (port) "): ne » teh(ex => 4 console.error (ex.stack) process.exit (1); ne Modify npm scripts Finally, we will modify the scripts section of the package.j0n file to look like the following snippet: hitps:icodeburst obit chat-app-with-sentiment-analysis-using-nextjs-c430bt3ea643 ana anor Build A Chat App With Sentiment Analysis Using Next js 7 package.jzon */ sscripte": { je severe", wild": “next build”, are": "NODE_EAV-production node server.je" We have gotten all we need to start building our app components. If you run the command npn -un dev on your terminal now, it will start up the application server on port 3000 if tis available. However, nothing happens on the browser yet, because we have not built any index page component. Let’s start building the app components. Building the index page Next js requires that you create the page components of your app in a pages directory. We will go ahead and create a pages directory in our app root directory and create anew incex.is file inside it for the index page of our application. Before we add content to the index page, we will build a tayeut component that can be used in our app pages as a kind of template. Go ahead and create a components directory in your app root. Create a new teyout.is file inside the just created components directory with the following content: ponents/Layour.j */ nport React, ( Fragment } from 'xeact!? smport Head from ‘next /nead"; const Layout = props = rink-to-£i { Le (evt keycode === 13) ( const user = evt.target.valuer this.setscate({ user })7 render () { const {us } = thie.state: const nameInputstyles = ( background: ‘transparent’, color: "#935", border: 0, bordexBoltom: ‘1px solid #666", borderRadius: 0, fontsize: ‘3ren', FontWeight: 500, boxshadow: ‘none important? return (
ontainer-fluid position
Hellal (user) ) What is ye , { fuser & |
olnd-4 position relative d-flex flox-wrap h-100 align-itens-start align= content-between bg-white px-0"> M export default () => ( ) We created a component indexbsqe for the index page of our app. We initialized the state of the component with an empty ans property. The nane property is meant to contain the name of the currently active user. We also added an input field to receive the name of the user, if no user is currently active. Once the input field is filled and the ester or return key is pressed, the name supplied is stored in state. If we test the app on our browser now, we should see a screen that looks like the following screenshot: htps:icodeburst iotbuilt-s-chat-app-with-sentimentanalysis-using-nextjs-c430bt3ea643 m9 anor Build A Chat App With Sentiment Analysis Using Next js Maat ta Building the Chat component We will go ahead and build the chat component. Create a new chat.js file inside the components directory and add the following content: jponenta/Chat.is */ import React, { Component, Fragment } from 'react"; Amport axioe fron taxios'; import Pusher from ‘pushe-3s'y class Chat extends Component { state = ( chats: () } conponentbidvount () { this.pusher = new Pusher (process.env.PUSHER APP_KEY, cluster: process.eny. PUSHER APP_CLUSTER, encrypted: true De thie.channel = this.pusher.subseribe (*chat-roon!) this.channel.bind(*new-nessage", ({ chat = mull }) > const { chats } = this.statey chat 44 chats.pash chat) this-setstate({ chats 1) htps:icodeburst iotbuilt-s-chat-app-with-sentimentanalysis-using-nextjs-c430bt3ea643 ang anor Build A Chat App With Sentiment Analysis Using Next js this.pusher.connection.bind( "connected", () => ( axios.post ("/nessages") then (response const chate = response.data.message: ate({ chats }) this-set componentinilLUnmoust () ( this.pusher-disconnect ()7 1 export default chats Here is a simple break down of what we've done: 1. We first initialized the state to contain an empty chats array property. This chats property will be populated with chat ‘messages as they keep coming. When the component mounts, we set up a Pusher connection and channe1 subscription inside the corpenentDiattount () lifecycle method. 2. You can see that we are subscribing to a Pusher channel called chat-roon for our chat application. We are then binding to the sew-nessage event on the channel, which is triggered when a new chat message comes in, Next, we simply populate the state hae. property by appending the new chat. 3. Also, on the conponentDiatiount )-method, we are binding to the connected event on the Pusher client, when itis freshly connected, to fetch all the chat messages from history by making a vos messages HTTP request using the axios library. Afterwards, we populate the state cha:s property with the chat messages received in the response. 4, The chas component is not completed yet. We still need to add a render() method. Let’s do that quickly. Add the following snippet tothe ctat component class. 7+ componenta/chat.js handlexeyUp = evt => ( const value = evt.target.valuey LE (eve keycode <= 12 Gé fave ehigeKey) ( const { activelaer: user } = this.propay htps:icodeburst iotbuilt-s-chat-app-with-sentimentanalysis-using-nextjs-c430bt3ea643 sna anor ‘Build A Chat App With Sentiment Analysis Using Nex!js const chat = ( user, message: value, timestamp: +new bate }s evt-target.value = ¢ axioe.poat (*/nessage', chat): render() { return (this.proze.activelser 64
this.props.activeUser}
famem"border-top bordex-gray w-100 pxn¢ d ) Assen inthe sendes() method, we require an activevsex prop to identify the currently active user. We also rendered a element for entering a chat message. We added an onkeyvp event handler to the to send the chat message when you press the enter or vecuen button, On the handiexeyve) eventhandler, we construct a chat object containing the ser sending the message (currently active user), the neseage itself, and then the sinestan> for when the message was, sent, We clean up the and then make a Post /nassage HITTP request, passing the chs: object we created as payload. Let’s add the cha: component to our index page. First, add the following line to the ispost statements in the sages/iodex. js file. I pages/index.ja */ 1 other inport statements here import Chat from '../eonponents/Chat'; Next, locate the render() method of the rndexeage component. Render the chs: component in the empty element. It should look like the following snippet: hitpsicodeburst obits chat-app-with-sentiment-analysis-using-nextjs-c430bt3ea643 ron anor Build A Chat App With Sentiment Analysis Using Next js J pages/index.js */ [user 66 | ins-start align-content-between b ‘You can reload the app now in your browser to see the changes. Defining the messaging routes For now, nothing really happens when you try to send a chat message. You don't see any message or any chat history. This is because we have not implemented the two routes we are making requests to. We will go ahead and create the /nossage and /nessages routes. Modify the js file and add the following just before the call to server.tisten() insidethe then() callback function. J+ server.ja */ 17 server.get{"*") is here const chatiistory = { messages: () J server.post(‘/message', (req, res, next) => ( const { user = null, message = '', timestanp = snow bate } = req.bodys const sentinentseore = sentinent analyze ressage) -score; const chat = { user, message, tinestanp, sentiment: chatilistory.m fages.push (chat) + pusher.trigger("chat-roon', ‘nev-message', { chat })1 ve server.post(‘/messages', (req, res, next) -> res.json({ ...chacHistory, status: "success" 1); Me W/ server.listen() is here . First, we created a kind of in-memory store for our chat history, to store chat messages in an array. This is useful for new clients that join the chat room to see previous messages. Whenever the Pusher client makes hitpsicodeburst obits chat-app-with-sentiment-analysis-using-nextjs-c430bt3ea643 anne anor Build A Chat App With Sentiment Analysis Using Next js a pos7 requestto the /ne the messages in the chat history in the returned response. + endpoint on connection, it gets all Onthe vost /nessage route, we are fetching the chat payload from req.body through the help ofthe body-parses middleware we added a sentiment score of the chat message. Next, we reconstruct the chat object, adding the wr. We then use the sentinent module to calculate the overall cntinent property containing the sentiment score. Finally, we add the chat to the chat history sessases , and then trigger @ sew-nessage eventonthe cha:-room Pusher channel, passing the chat object in the event data. This does the real time magic. We are just a few steps away from completing our chat application. If you load the app on your browser now and try sending a chat message, you don't see any feedback yet. That’s not because our app is not working. It is working perfectly. It’s simply because we are not yet rendering the chat messages on the view. Let's head on to that and finish this up. Displaying the chat messages Create anew chattessage.J» file inside the cosponents directory and add the following content to it. /* components/Chattessage.is */ Amport React, ( Component} from treact's class Chattessage extends Component ( render () { const { position = ‘left', message } ~ this-props: const isAight = position.tolowercase() === ‘right'y const align = isRight 7 ‘text-right’ : ‘text-Left'y const justify = ieRignt ? ‘Sustisy-content-end! ‘juseity-content-stare'; const messageBoxstyles = { Flexcrow: const messagestyles = fontWeight: $00, LineHeaght: 1.4, whitespace: ‘pre-weap' h return
(message! ‘export default chatMessage; The chatvessage component is a very simple component requiring two props: message forthe chat message and position forthe positioning of the message -either «ight or icc . This is useful for positioning the messages of the active user on one side and then the messages of other users on the other side as we would do in a moment. Finally, we will modify the conpenen=s/Chat. js file to render the chat ‘messages from the state. Make the following changes to the chaz component. First add the following constants before the class definition of the chat component. Each constant is an array of the code points required fora particular sentiment emoji. Also ensure to import the chatWessage component. /* components/Chat.js */ HY Modste inp import ChatMessage from './ChatNesage"; here « SAD_BMOJI = (55357, 568641; BAPPY_sMogI = (55357, 56832); const NEUTRAL, EMOJI = ($5357, 56848]; 11 Chat conponent clase here Then, add the following snippet between the chat header and the chat message box we created earlier in the cha: ‘component, J+ components/Chat.js */ hitps:icodeburst obit chat-app-with-sentiment-analysis-using-nextjs-c430bt3ea643 rane anor ‘Build A Chat App With Sentiment Analysis Using Nex!js (/* CART HEADER HERE **/}
[ehis.state,chats.map({chat, index) => ( const previous = Math.nax(0, index - 1)7 const previousChat = this.state.chats(previous const position = chat.user === thia.prope.activeuser 2 right" : “Lett const IeFicat = previous === index: const insequence = chat,user === previousChat users const hasDelay ~ Math.ceil ((chat.timestarp — proviouschat.timestamp) / (1000 * 60)) > 17 const. mood ~ chat.sentiment > 0 ? HAPPY_ENOIT (chat-sontinent === 0 ? NEUTRAL EMOJI : SAD_EMOJT); return ( { GsFirst [| Hnsequence || haspelay) 66 (
(string. fromcedepoint (...mocd) } (chat-user || 'Anonynous') vy M m
(/** CORT MESSAGE BOX HERE **/) Let's try to understand what this code snippet is doing. First, we are going through each chat object in the state chats array property. We check ifthe sender of the message is the same as the currently active user and use that to determine the position of the displayed chat message. As you can see, the active user's messages will appear on the right. We also use the sentinent score in the chat object to set the mood of the user while typing the message to either happy , sad OF neutral htps:icodeburst iotbuilt-s-chat-app-with-sentimentanalysis-using-nextjs-c430bt3ea643 sana anor Build A Chat App With Sentiment Analysis Using Next js using the earlier defined constants. We conditionally render the same of the user before the chat message based on one of the following conditions being met. 1. sersest - the current chat message is the first in the list 2, insequence - the current chat message directly follows a ‘message from another user 3. hasbelay - the current chat message has a delay of over 1 minute from the previous message of the same user 4. Also notice how we are using the (string. froncodePoint ()) (netps://developer .nozilla.org/en- 08/docs /web/Javascript/Reference/Global_Objects /String/fronCod ePoint) method added in ES6 to get the emoji from the code points we defined in our constants earlier. Weare finally done with our chat app. You can go ahead to test what you have built on your browser. Here are some screenshots showing a chat between Slad, Steve and Bob. glad htps:icodeburst iotbuilt-s-chat-app-with-sentimentanalysis-using-nextjs-c430bt3ea643 ssi anor Build A Chat App With Sentiment Analysis Using Next js Steve Bob htps:icodeburst iotbuilt-s-chat-app-with-sentimentanalysis-using-nextjs-c430bt3ea643 rena anor Build A Chat App With Sentiment Analysis Using Next js Conclusion In this tutorial, we have been able to build a very simple chat application with chat sentiment using Next.js (React), Pusher and ‘Sentiment Node module, While this tutorial focuses on just the basics, there are a lot of advanced stuffs you can do to make a better chat app. ‘You can check the source code of this tutorial on GitHub. Do check the documentation for each technology we used in this project to learn more about other ways of using them. I hope that this, tutorial is helpful for you! 2 PUSHER We rzke communication and collaboration API that power apps allover the world, Supported by easy to integrate SOKs for web robile 2s well as mast popular hitpsicodeburst obits chat-app-with-sentiment-analysis-using-nextjs-c430bt3ea643 wna anor ‘Build A Chat App With Sentiment Analysis Using Nex!js If this post was helpful, please click the clap &) button below a few times to show your support! §4 htps:icodeburst iotbuilt-s-chat-app-with-sentimentanalysis-using-nextjs-c430bt3ea643 rena anor Build A Chat App With Sentiment Analysis Using Next js htps:icodeburst iotbuilt-s-chat-app-with-sentimentanalysis-using-nextjs-c430bt3ea643 sono

You might also like