TalkJS provides an API that you can use to add chat to your web and mobile apps. It includes features like the pre-built UI and out-of-the-box notifications. This tutorial will teach you how to create an Ionic chat app by integrating TalkJS.

We assume that you already have a basic understanding of Ionic. To follow this tutorial, you must have an existing Ionic application. Since the chat functionality usually requires user details, your app should have a mechanism for retrieving user data. Let's get started.

Getting ready

First, we must create a TalkJS account and get the App ID. We’ll start from a blank starter template and use Angular as our web framework on top of Ionic.

To install TalkJS with NPM, run the following command in the root folder of your project:

npm install talkjs –save

Let's add our App ID to our environment variables inside environment.prod.ts and environment.ts.

TALKJS_APP_ID: 'YOUR_APP_ID'

Setting up the UI

Now we need to create a page for our chat. Run the following command:

ionic g page chat

The Ionic CLI will create a new folder and scaffold the skeleton code for our chat page. We will also generate a service for communicating with TalkJS API.

ionic g service shared/services/chat

This command will scaffold a service inside the shared/services folder. Let's import the ChatService class and inject it into the constructor in chat.page.ts

import { ChatService } from '../shared/services/chat.service';
 
constructor(private chatService: ChatService) { }

We will add some hardcoded data to the chat.page.ts to use it for this chat example. You will probably pull this data from the database in a real app.

  users = [
    {
      id: 0,
      name: 'Ken',
      email: 'ken@test-email.io',
      photoUrl: 'https://i.picsum.photos/id/818/200/200.jpg?hmac=gfhJZngz3JDsSmE1obNFY5OeAQBVsJLED2VkwuGsC-o',
      welcomeMessage: 'Welcome to the chat!',
      role: 'default'
    },
    {
      id: 1,
      name: 'Denis',
      email: 'denis@test-email.io',
      photoUrl: 'https://i.picsum.photos/id/730/200/200.jpg?hmac=wK_2ZX79XZRP1wVJ-dW_r-OkOjiz1kK8eHIyTw2Lr6s',
      welcomeMessage: 'Hi',
      role: 'default'
    },
    {
      id: 2,
      name: 'Tim',
      email: 'tim@test-email.io',
      photoUrl: 'https://i.picsum.photos/id/521/200/200.jpg?hmac=J25eIJlH4Vz83r581TpDZbrmu21tzbZMognm7gqkoWo',
      welcomeMessage: 'Hello friend',
      role: 'default'
    },
    {
      id: 3,
      name: 'Sarah',
      email: 'sarah@test-email.io',
      photoUrl: 'https://i.picsum.photos/id/194/200/200.jpg?hmac=f1VYjvgDG_6vPwJyTb-Xl1HpXKM23stmhFUnmPE_yL8',
      welcomeMessage: 'How can I help you?',
      role: 'default'
    },
    {
      id: 4,
      name: 'Adam',
      email: 'adam@test-email.io',
      photoUrl: 'https://i.picsum.photos/id/653/200/200.jpg?hmac=tZtho3csFdJ2rLHTTlT7WhXtDwbXgJNIIUvOQQb2dIo',
      welcomeMessage: 'What\'s up?',
      role: 'default'
    }
  ];

To display the users array we will add the following code inside our chat.page.html file:

<ion-header>
  <ion-toolbar>
    <ion-title>Chat</ion-title>
  </ion-toolbar>
</ion-header>
 
<ion-content>
  <h3 class="page-title">Pick your chat partner</h3>
  <ion-list>
    <ion-item *ngFor="let user of users" type="button" (click)="chatInit(user)">
      <ion-avatar slot="start">
        <img [src]="user.photoUrl">
      </ion-avatar>
      <ion-label>
        <h3>{{ user.name }}</h3>
        <p>{{ user.email }}</p>
      </ion-label>
      <ion-icon name="chevron-forward"></ion-icon>
    </ion-item>
  </ion-list>
 
  <div #inboxContainer id="inboxContainer">
  </div>
  <button ion-button #closeInboxBtn color="light" id="closeInboxBtn" (click)="closeInbox()">
    <ion-icon name="chevron-back"></ion-icon> Close this chat
  </button>
</ion-content>

We are creating a list of users that we can chat with. By clicking on a user in the list we are passing the information of that user to chatInit function in order to initiate a chat session. We are not displaying inboxContainer and closeInboxBtn elements until the chat partner is selected. After that, we will mount TalkJS chat UI to the inboxContainer.

Let's add a little bit of styling to it by adding the following code to our chat.page.scss:

.page-title {
  margin: 20px 0;
  text-align: center;
}
 
#inboxContainer {
  height: 90vh;
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 999;
  display: none;
}
 
#closeInboxBtn {
  display: none;
  position: fixed;
  bottom: 0px;
  height: 10vh;
  width: 100%;
  font-size: 18px;
  line-height: 2;
  background-color: #ff0000;
  font-weight: 600;
 
  ion-icon {
    position: relative;
    top: 6px;
    font-size: 25px;
  }
}

We need to define an element we'll use to display the inbox and a close button to hide the inbox. We will use the ViewChild decorator.

  @ViewChild('inboxContainer') inboxContainer!: ElementRef;
  @ViewChild('closeInboxBtn') closeInboxBtn!: ElementRef;

Now let's go to the chat.service.ts file to write the code that will interact with the TalkJS API. We need to import the App ID from the environment file and Talk from TalkJS.

import Talk from 'talkjs';
import { environment } from 'src/environments/environment';

We’ll use the currentUser object to store the data of the user that is currently logged in to this instance of TalkJS.

currentUser: Talk.User;

Now let's start the session by using Talk.Session. Session represents a connection between the mobile app and TalkJS. A session begins after authentification through App ID and ends when the app is closed. Let's add a function to initiate a TalkJS session.

  async startSession() {
    return Talk.ready.then(() => {
      this.currentUser = new Talk.User({
        id: 99,
        name: 'Omar',
        email: 'omar@test-email.io',
        photoUrl: 'https://i.picsum.photos/id/681/200/200.jpg?hmac=GBX3TnpfRpzN-ZDEpA01hkf2-G7DkpMs53xqLpv8pa4',
        welcomeMessage: 'Hey there!',
        role: 'default'
      });
 
      const session = new Talk.Session({
        appId: environment.TALKJS_APP_ID,
        me: this.currentUser
      });
 
      return session;
    });
  }

First, we need to assign the value to the currentUser object and create the session object. Of course, this data is usually retrieved from the database.

Starting a conversation

  async startConversation(session: Talk.Session, user: any) {
      const otherUser = new Talk.User({
        id: user.id,
        name: user.name,
        email: user.email,
        photoUrl: user.photoUrl,
        welcomeMessage: user.welcomeMessage,
        role: user.role
      });
 
      const conversation = session.getOrCreateConversation(Talk.oneOnOneId(this.currentUser, otherUser));
 
      conversation.setParticipant(this.currentUser);
      conversation.setParticipant(otherUser);
 
      return conversation;
  }

We are passing a session and a user object that will be used to create a conversation. The user object contains the data assigned to the otherUser constant, and it represents a user talking to our currentUser. The getOrCreateConversation method can be used to begin a conversation between our two users. Let’s do that and then use setParticipant to add them to it. The oneOnOneId uses the users’ IDs to create a unique ID for the conversation. The conversation object here contains the entire chat history as well.

Creating the inbox element

  async createInbox(session: Talk.Session, user: any) {
      const conversation = await this.startConversation(session, user);
      const inbox = session.createInbox();
      inbox.select(conversation);
      return inbox;
  }

As we can see, we are passing a session object, and a user object to this function so we can initiate a conversation. The conversation is created by assigning the return value of the startConversation function to the conversation constant. We are using createInbox function to display the chat UI.

Removing the inbox element

  removeInbox(inbox: Talk.Inbox) {
    inbox.destroy();
  }

We can pass the inbox instance to our removeInbox method and remove it by using the destroy function provided by TalkJS.

Wrapping it up

Now all we need to do is to import an instance of TalkJS into our chat.page.ts and write the logic for invoking the functions that are defined in chat.service.ts.

import Talk from 'talkjs';

We need to define a variable that will contain the data that is returned by ChatServices createInbox function.

  inbox: Talk.Inbox;

When the user clicks on a list item the chatInit function is called.

  async chatInit(user: any) {
    const session = await this.chatService.startSession();
    this.inbox = await this.chatService.createInbox(session, user);
    this.inbox.mount(this.inboxContainer.nativeElement);
    this.showChat();
  }

After starting a session and creating an inbox we need to display the chat on the screen by using the showChat function.

  showChat() {
    this.inboxContainer.nativeElement.setAttribute('style', 'display: block');
    this.closeInboxBtn.nativeElement.setAttribute('style', 'display: block');
  }

The user can click on the close button to close the chat by calling closeChat function.

  closeChat() {
    this.chatService.removeInbox(this.inbox);
    this.closeInboxBtn.nativeElement.setAttribute('style', 'display: none');
    this.inboxContainer.nativeElement.setAttribute('style', 'display: none');
  }

Conclusion

This tutorial has gone over the process of adding TalkJS to an Ionic app, and making that integration reusable and content-agnostic. In addition, it has introduced you to some of the basic concepts of TalkJS and how they relate to one another.









You’ve successfully subscribed to TalkJS
Welcome back! You’ve successfully signed in.
Great! You’ve successfully signed up.
Your link has expired
Success! Check your email for magic link to sign-in.