Logo

dev-resources.site

for different kinds of informations.

Build an Intercom clone in Nuxt.js - Part Two

Published at
12/29/2022
Categories
appwrite
database
realtime
nuxt3
Author
chukwutosin_
Categories
4 categories in total
appwrite
open
database
open
realtime
open
nuxt3
open
Author
12 person written this
chukwutosin_
open
Build an Intercom clone in Nuxt.js - Part Two

This article is the second in a two-part series about building an Intercom clone with Nuxt.js. Reading the first article will help in understanding this article.

In the first article, we focused on building the client area, where users can send messages to be received by the admin. In this article, we will be building the admin end, which interacts with messages sent from the client end.

Repository

https://github.com/folucode/intercom-clone-nuxtjs-part2

Setting up the application

To set up our application, weā€™ll clone this repository and run the command below in the project directory:

$ npm i
Enter fullscreen mode Exit fullscreen mode

This repository contains all the initial setups we'll need for our app, helping us focus on our app's main functionality.

Note: We will encounter some errors if the app is run as is.

Building the application

Open index.vue, which is located in the pages folder. In the scripts tag, paste the code below to initialize the Appwrite modules:

    <script>
    import { Client, Account, Databases, Query } from 'appwrite';
    import { randomStr } from '../utils';

    const client = new Client();
    client
      .setEndpoint('http://localhost/v1') // Our Appwrite Endpoint
      .setProject('[PROJECT-ID]');

    const account = new Account(client);
    const database = new Databases(client);

    account.createAnonymousSession().then(
      (response) => {
        console.log(response);
      },
      (error) => {
        console.log(error);
      }
    );

    const sessionID = randomStr();

    ...
Enter fullscreen mode Exit fullscreen mode

Only signed-in users can interact with the Appwrite database, so we created an anonymous session in the code above as a workaround. After that, we generate a unique sessionID.

Note: The PROJECT_ID resides in the Appwrite console.

Setting up a real-time connection

To set up a real-time connection with Appwrite in our app, we check to ensure an active user session in the mounted lifecycle method. If so, we set up a real-time connection with Appwrite by subscribing to the documents channel.

Subscribing to the documents channel means we listen for changes in the documents in our database. The documents are the individual data we store in our database.

    ...

    export default {
      data() {
        return {
          chatSessions: [],
          sessionID: '',
          messages: [],
          text: '',
        };
      },
      mounted() {
        if (account.get !== null) {
          try {
            client.subscribe('documents', (response) => {

            });
          } catch (error) {
            console.log(error, 'error');
          }
        }
      },
    };
    </script>
Enter fullscreen mode Exit fullscreen mode

Fetching chat sessions

We want to see all the active chat sessions from our client app. To do so, weā€™ll need to create a method called getChatSessions and call it in the mounted lifecycle method.

    ...
    methods: {
        async getChatSessions() {
          let response = await database.listDocuments(
            '[DATABASE-ID]',
            '[CHAT-SESSIONS-COLLECTION-ID]',
          );
          this.chatSessions = response.documents;
        },
    ...
Enter fullscreen mode Exit fullscreen mode

It can be called in the mounted method like so:

    ...
    mounted() {
        this.getChatSessions();

        if (account.get !== null) {
          try {
            client.subscribe('documents', (response) => {
              this.getChat(this.sessionID)
            });
          } catch (error) {
            console.log(error, 'error');
          }
        }
      },
    ...
Enter fullscreen mode Exit fullscreen mode

So, once the component renders, we get a list of chat sessions that users have created.

Fetching the chats

To be able to see all the messages in a chat session, we need to create a function that fetches all the messages.

In the methods object, create a new method called getChat.

    ...
    async getChat(sessionID) {
          let response = await database.listDocuments(
            '[DATABASE-ID]',
            '[CONVERSATIONS-COLLECTION-ID]',
            [Query.equal('sessionID', sessionID)]
          );
          this.messages = response.documents;
        },
    ...
Enter fullscreen mode Exit fullscreen mode

This function fetches all the chats in the conversations collection with the associated sessionID.

In the mounted method, call getChat in the subscribe callback function, like so:

    ...
    mounted() {
        this.openChatSession();

        if (account.get !== null) {
          try {
            client.subscribe('documents', (response) => {
              this.getChat(sessionID)
            });
          } catch (error) {
            console.log(error, 'error');
          }
        }
      },
    ...
Enter fullscreen mode Exit fullscreen mode

When we start up our app, we should see something like this:

Clicking any of the chat sessions on the left-hand side would bring up all the messages in that chat.

Sending a message

For us to be able to send a message, weā€™ll add a new method called sendMessage in the methods object.

    ...
    async sendMessage() {
          await database.createDocument(
            '[DATABASE-ID]',
            '[CONVERSATIONS-COLLECTION-ID]',
            'unique()',
            {
              sessionID,
              message: this.text,
              sender: 'admin',
            }
          );

          this.text = '';
        }
    ...
Enter fullscreen mode Exit fullscreen mode

The sendMessage method adds a new record to the conversations collection. This time, the sender is admin, so we can differentiate who is sending a message.

After that, we clear the input field. Then, so that we can see our message, we need to add getChat.

Our app should now look like this:

If we open a chat session from the client app, it will show up here, and we can reply to messages from the users.

Conclusion

In this article, we learned how to create a simple clone of the admin end of Intercom by leveraging Appwrite's real-time features. The admin end we built can view the list of open chats. Clicking on a chat opens a real-time chat window that communicates with the client interface built in part one of this series.

Resources

nuxt3 Article's
30 articles in total
Favicon
RenderizaciĆ³n DinĆ”mica de Componentes en Vue 3 y Nuxt 3: GuĆ­a PrĆ”ctica y Caso Real
Favicon
Nuxt3 CSR Background Image Lazy loading
Favicon
DartsMash: a platform for darts enthusiasts
Favicon
Nuxt3 : limitation on Layers & Modules
Favicon
Using postgresql with nuxt3 by ORM(sequelize)
Favicon
Nuxt3 : API error handling
Favicon
Nuxt Icon
Favicon
Integrating Nuxt 3 with Recaptcha v3 for Token Handling šŸ¤–šŸ”
Favicon
Nuxt 3 Starter
Favicon
Nuxt 3 Builder: A Tailored Editor for Developers
Favicon
Build an X clone w/ Nuxt UI
Favicon
Nuxt3 Form with Feedback
Favicon
Custom 404 Page in Nuxt
Favicon
Nuxt 3 authentication with pinia
Favicon
Nuxt 3, UnoCSS, and Preset rem to px
Favicon
ConfiguraĆ§Ć£o e instalaĆ§Ć£o do Nuxt 3
Favicon
The DevOnly component in Nuxt 3: A developer's best friend
Favicon
Storyblok Nuxt 3 news šŸ—ž
Favicon
Implementing OpenID Connect (OIDC) Authentication with Nuxt 3
Favicon
Authentication in Nuxt 3
Favicon
Adding ESLint and Prettier to Nuxt 3 āœØ (2024)
Favicon
API Management in Nuxt 3 with TypeScript
Favicon
Docker and Nuxt 3
Favicon
Pinia and Nuxt 3
Favicon
Adding Pinia to Nuxt 3 šŸ (2023)
Favicon
Adding Vitest to Nuxt 3 āš” (2023)
Favicon
Adding Tailwind CSS to Nuxt 3 šŸƒ (2023)
Favicon
How I set up eslint in my projects
Favicon
How to create and minify Vuetify 3 Nuxt 3 project bundle
Favicon
Build an Intercom clone in Nuxt.js - Part Two

Featured ones: