<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Amin Mahboubi</title>
    <description>The latest articles on Forem by Amin Mahboubi (@aminmahboubi).</description>
    <link>https://forem.com/aminmahboubi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F155497%2Fdfd0618c-88df-403b-abb5-c86cfff2ea07.jpeg</url>
      <title>Forem: Amin Mahboubi</title>
      <link>https://forem.com/aminmahboubi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/aminmahboubi"/>
    <language>en</language>
    <item>
      <title>Build an Interactive Messaging App with Stream, MML, Node and React</title>
      <dc:creator>Amin Mahboubi</dc:creator>
      <pubDate>Fri, 08 Jan 2021 20:20:27 +0000</pubDate>
      <link>https://forem.com/aminmahboubi/build-an-interactive-messaging-app-with-stream-mml-node-and-react-237c</link>
      <guid>https://forem.com/aminmahboubi/build-an-interactive-messaging-app-with-stream-mml-node-and-react-237c</guid>
      <description>&lt;p&gt;Message Markup Language (MML) enables you to build an interactive messaging experience. MML supports embedding elements as simple as a button to your message or as complex as date pickers and custom forms within your chat experience. MML also supports images, icons, and tables out of the box.&lt;/p&gt;

&lt;p&gt;The goal for MML is to provide a standardized way to handle the most common use cases for message interactivity. MML can be extended into custom components using the &lt;a href="https://getstream.github.io/mml-react/mml" rel="noopener noreferrer"&gt;MML React library&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  MML for React
&lt;/h2&gt;

&lt;p&gt;The first Stream SDK to support MML is the &lt;a href="https://getstream.io/chat/react-chat/tutorial/" rel="noopener noreferrer"&gt;Stream Chat React SDK&lt;/a&gt;. This feature accepts an MML string and renders it as React components. To see specific examples of use cases for MML on React, read our docs for &lt;a href="https://getstream.github.io/mml-react/mml" rel="noopener noreferrer"&gt;MML-React&lt;/a&gt;. Read more about MML in our &lt;a href="https://getstream.io/chat/docs/mml_overview/" rel="noopener noreferrer"&gt;chat docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Basic knowledge of Node.js (Javascript) and React is required to follow this tutorial. This code is supposed to run locally on your machine. Make sure you have installed &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; and &lt;a href="https://yarnpkg.com/getting-started/install" rel="noopener noreferrer"&gt;Yarn&lt;/a&gt;. You also need to install &lt;a href="https://github.com/facebook/create-react-app" rel="noopener noreferrer"&gt;create-react-app&lt;/a&gt;, which helps us kick off our React app.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;You need to create an account for &lt;a href="http://getstream.io/" rel="noopener noreferrer"&gt;Stream&lt;/a&gt; and start your chat trial. Once you made your account, proceed to the dashboard and grab your app key and secret, we'll need them later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2F32ba4fdd34b006848d3ce540608b5063%2Fdashboard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2F32ba4fdd34b006848d3ce540608b5063%2Fdashboard.png" alt="Stream Dashboard API Key and Secret"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the App
&lt;/h2&gt;

&lt;p&gt;Our projects consist of a simple backend app written in Node.js, &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express.js&lt;/a&gt;, and &lt;a href="https://www.npmjs.com/package/localtunnel" rel="noopener noreferrer"&gt;localtunnel&lt;/a&gt; to expose our localhost to the internet. The frontend app is a simple &lt;a href="https://github.com/facebook/create-react-app" rel="noopener noreferrer"&gt;create-react-app&lt;/a&gt; project which uses &lt;a href="https://github.com/GetStream/stream-chat-react" rel="noopener noreferrer"&gt;Stream-Chat-React&lt;/a&gt; components that support &lt;a href="https://github.com/GetStream/mml-react" rel="noopener noreferrer"&gt;MML&lt;/a&gt; out of the box. Let's start with our Frontend app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frontend
&lt;/h2&gt;

&lt;p&gt;First, we need to create a new React application, install some dependencies, and then open the editor's frontend folder.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Open the src/App.css and replace its content with this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Next, we need to choose a user id and generate a token for this user. Let's call our user "jim", grab your app secret from &lt;a href="https://getstream.io/dashboard/" rel="noopener noreferrer"&gt;Stream Dashboard&lt;/a&gt; and head over to this the &lt;a href="https://getstream.io/chat/docs/token_generator/" rel="noopener noreferrer"&gt;user token generator&lt;/a&gt;. In the user id field, enter &lt;code&gt;jim&lt;/code&gt; and paste your app secret from the dashboard in the secret field. You now have a user token signed for this user. (Note that in production, you need to generate user token in your backend) Now we need to update our src/App.js file with this and put our API KEY from &lt;a href="https://getstream.io/dashboard/" rel="noopener noreferrer"&gt;Stream Dashboard&lt;/a&gt; in line 8 and our generate user token in line 11:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Awesome! Our fully functioning chat application is ready! We can now see our app by running &lt;code&gt;yarn start&lt;/code&gt; or &lt;code&gt;npm start&lt;/code&gt; from the terminal. Open &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; in your browser and click on the "Create a New Channel" button to create the first channel for Jim.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2F969534619f27be34ad647ad716712aa3%2Fmml-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2F969534619f27be34ad647ad716712aa3%2Fmml-1.png" alt="Frontend app powered by Stream Chat React components"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Backend
&lt;/h2&gt;

&lt;p&gt;Here things get interesting. We will create an API that accepts POST requests from the &lt;a href="https://getstream.io/chat/docs/webhooks_overview/" rel="noopener noreferrer"&gt;Stream Webhook&lt;/a&gt; system. Using webhooks allows you to integrate your server application with Stream Chat tightly. Our app will use the custom command webhook feature, and this will enable us to create interactive messages similar to how &lt;code&gt;/giphy funk&lt;/code&gt; command works in Slack.&lt;/p&gt;

&lt;p&gt;For our example app, we introduce a new command to our chat application that allows our users to create an appointment. When a user writes a message with &lt;code&gt;/appointment [title]&lt;/code&gt;, we will show a custom message to the user and follow a few steps to create an appointment in our server application. If you want to know more about how custom commands work best, see the &lt;a href="https://getstream.io/chat/docs/custom_commands_webhook/" rel="noopener noreferrer"&gt;Stream official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's create a new folder and start implementing our backend app:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We are going to create a basic Express app in the &lt;code&gt;index.js&lt;/code&gt; file. We are using the &lt;code&gt;localtunnel&lt;/code&gt; library, which allows us to tunnel our localhost API and expose it on the internet with a random public URL.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now you can run your API by running &lt;code&gt;node index.js&lt;/code&gt; in your terminal, and it should show you an output similar to this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note that the second URL is randomly generated every time you run your API. If you open it, you should see a JSON response like this &lt;code&gt;{"message": "API is live!"}&lt;/code&gt; in your browser.&lt;/p&gt;

&lt;p&gt;To integrate Stream with our backend, we need to get our API Key and Secret from Stream Dashboard similar to our frontend app. Once you got it, update your &lt;code&gt;index.js&lt;/code&gt; file with the following code. We initialized our &lt;code&gt;chatClient&lt;/code&gt; using our keys and created an express middleware to verify the request's integrity. That is a crucial step since our API is publicly accessible to everyone; we have to make sure the requests are coming from Stream. You can read more about this &lt;a href="https://getstream.io/chat/docs/webhooks_overview/#security-and-performance" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In the next step, we will update the &lt;code&gt;setupTunnelAndWebhook&lt;/code&gt; function to set up our webhook configuration and update our app's settings in Stream. First, we create our &lt;code&gt;appointment&lt;/code&gt; command and update our Channel type with it. Next, we update the app configuration to forward commands to our server application.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: this step needs to be done only once for a production app. We are running this step every time we run the app as our public URL changes with each run for this tutorial.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;So far, great! Finally, we can add the controller to handle the appointment command and respond to the user with our MML string. That is a rather complicated use case consisting of several steps to show the MML and Stream Webhooks' power.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;You can see the full backend code &lt;a href="https://github.com/mahboubii/mml-test-app/blob/master/backend/index.js" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Let's run our backend app by running &lt;code&gt;node index.js&lt;/code&gt; and our frontend app by running &lt;code&gt;yarn start&lt;/code&gt; and see how our app works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User writes a message with appointment command like &lt;code&gt;/appointment Doctor&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2F373b605b7cb4cc74b9f7b8483b3a477b%2Fmml-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2F373b605b7cb4cc74b9f7b8483b3a477b%2Fmml-2.png" alt="User starts the flow by running our custom command"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Stream webhook calls our server application, we update the message with an &lt;a href="https://getstream.github.io/mml-react/components/input#basic-usage" rel="noopener noreferrer"&gt;MML Input&lt;/a&gt; component and ask for user phone number&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2F99aef87afa19340461abfd88b1aca8ab%2Fmml-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2F99aef87afa19340461abfd88b1aca8ab%2Fmml-3.png" alt="User enters phone number"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;User enters the phone number and click on the submit button&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Our server application now receives another webhook call, which has a &lt;code&gt;form_date&lt;/code&gt; object that includes the user's phone number. It stores the number and updates the message to show an &lt;a href="https://getstream.github.io/mml-react/components/scheduler#basic-usage" rel="noopener noreferrer"&gt;MML Scheduler&lt;/a&gt; component&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2F306dfa9e97a23b944945c3e6539e8f20%2Fmml-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2F306dfa9e97a23b944945c3e6539e8f20%2Fmml-4.png" alt="User selects a time slot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;User now selects a time slot and click on the submit button&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another webhook call is received by our server application with the selected time slot. Now we make the message persistent, store the appointment in our database and update the message to show an &lt;a href="https://getstream.github.io/mml-react/components/add-to-calendar#basic" rel="noopener noreferrer"&gt;MML AddToCalendar&lt;/a&gt; component that allows the user to add the appointment to their calendar of choice.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2F4873bf2f73cbaf04dd770b36362d679d%2Fmml-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2F4873bf2f73cbaf04dd770b36362d679d%2Fmml-5.png" alt="User can add the appointment to their calendar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2Fb5c751475cb95af411df852fecef5ef8%2Fmml-6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstream-blog-v2.imgix.net%2Fblog%2Fwp-content%2Fuploads%2Fb5c751475cb95af411df852fecef5ef8%2Fmml-6.png" alt="Appointment received on our backend app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;We successfully created a sample Chat application powered by &lt;a href="https://getstream.io/chat/" rel="noopener noreferrer"&gt;Stream&lt;/a&gt; with custom commands, and MML React components.&lt;/p&gt;

&lt;p&gt;MML is a powerful and flexible feature that allows us to support a wide range of use cases in our applications. Stream supports different types of webhooks.&lt;/p&gt;

&lt;p&gt;For example, you can create a bot user in channels to respond with custom MML strings whenever a specific event happens or a new message is posted to a channel.&lt;/p&gt;

&lt;p&gt;The full source code for this tutorial can be found in &lt;a href="https://github.com/mahboubii/mml-test-app" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mahboubii" rel="noopener noreferrer"&gt;
        mahboubii
      &lt;/a&gt; / &lt;a href="https://github.com/mahboubii/mml-test-app" rel="noopener noreferrer"&gt;
        mml-test-app
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Build an Interactive Messaging App with Stream, MML, Node, and React
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;mml-test-app&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Build an Interactive Messaging App with Stream, MML, Node, and React&lt;/p&gt;
&lt;p&gt;Source code of the tutorial published on stream blog
&lt;a href="https://getstream.io/blog/build-an-interactive-messaging-app-with-stream-mml-node-and-react/" rel="nofollow noopener noreferrer"&gt;https://getstream.io/blog/build-an-interactive-messaging-app-with-stream-mml-node-and-react/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mahboubii/mml-test-app" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>chat</category>
      <category>messaging</category>
      <category>node</category>
      <category>react</category>
    </item>
  </channel>
</rss>
