🎉 New! Web Push Notifications for Chatkit. Learn more in our latest blog post.
Hide
Products
chatkit_full-logo

Extensible API for in-app chat

channels_full-logo

Build scalable realtime features

beams_full-logo

Programmatic push notifications

Developers

Docs

Read the docs to learn how to use our products

Tutorials

Explore our tutorials to build apps with Pusher products

Support

Reach out to our support team for help and advice

Sign in
Sign up

Integrate a multilingual chatbot into Chatkit using Vue

  • Gideon Onwuka
May 24th, 2019
You need Node, npm and Ngrok installed on your machine.

In this tutorial, I'll walk you through adding a chatbot to your Chatkit app. At the end of this tutorial, you will build a translator bot that translates a message from one language to another language. Also, you'll become familiar with Chatkit webhooks.

Here is a preview of what we'll be building in a moment:

Bots are tomorrow’s technology, today. It helps in automating and simplifying life for both users and providers. The demand for this technology today is high and increasing.

You can also get the complete code for this tutorial on GitHub.

Prerequisites

To follow along with this tutorial, you will need to:

- Have a basic knowledge of JavaScript.
- Have a basic understanding of [Vue.js](https://vuejs.org/).
- Have [Node.js](https://nodejs.org/) installed on your system.
- Have npm installed on your system.
- Have [Ngrok](https://ngrok.com/) installed.

If you have all those installed, then let's get started!

Client setup - create a Vue project

Vue provides a CLI for scaffolding a new Vue project. First, you'll need to install the Vue CLI globally on your system (if you don't have it installed already). After that, we’ll create a new Vue project with the CLI commands.

Now, create a new Vue project by running the following commands in any convenient location on your system:

    # Install Vue CLI globally on your system
    $ npm install -g @vue/cli

    # Create a new Vue project (for the prompt that appears, press enter to select the default preset.)
    $ vue create chatkit-chatbot

    # Change your directory to the project directory
    $ cd chatkit-chatbot

    # Install Chatkit client SDK
    $ npm install @pusher/chatkit-client

    # Install axios - a library for making request
    $ npm install axios

    # Run the app!
    $ npm run serve

Accessing the URL displayed on your terminal will take you to a Vue default page.

Create a Chatkit app

To get started with Chatkit, you’ll first need to create a Chatkit instance. Head to the dashboard, hit Create, then give your instance a name. I will call mine “translator bot”.

Once you’ve created your Chatkit instance, head to the Credentials tab and take note of your Instance Locator and Secret Key.

On the same Credentials tab, enable test token provider and then note your Test Token Provider Endpoint:

Note that the test token is not to be used for productions. You can read more how you can create a token provider in your Node app here if you are going live.

Next, create a .env file to the root folder of the project and update your Chatkit keys to it:

    # ./.env

    APP_PORT=3000

    CHATKIT_SECRET_KEY=<YOUR_CHATKIT_SECRET_KEY>
    VUE_APP_CHATKIT_INSTANCE_LOCATOR=<YOUR_CHATKIT_INSTANCE_LOCATOR>
    VUE_APP_CHATKIT_TOKEN_ENDPOINT=<YOUR_CHATKIT_TOKEN_ENDPOINT>
    VUE_APP_SERVER=http://localhost:3000

    YOUR_PROJECT_ID=
    GOOGLE_APPLICATION_CREDENTIALS=

Remember to replace <YOUR_CHATKIT_SECRET_KEY>, <YOUR_CHATKIT_INSTANCE_LOCATOR>, <YOUR_CHATKIT_TOKEN_ENDPOINT> with your correct app keys you have noted above.

Create users

Next, create a number of users so we can use them to chat.

Also, create a user with a username as trbot that will stand in as our bot. Fill the User Identity and Display Name as trbot. We need this user to send responses to rooms where the bot is mentioned in.

Create rooms

Finally, create a number of rooms from your dashboard so we can use them for testing.

Google translate

We’ll make use of the Google Translate service to translate text from one language to another. We need a Google cloud account and API keys to be able to use the service.

To set up your API key:

  • Copy out the Project ID. Then add the Project ID to the .env file:
    YOUR_PROJECT_ID=<Project ID>

Replace <Project ID> with the project ID you just copied.

  • Next, go to APIs & Services then Credentials

  • Under Create credentials, click on Service account key

Once the page loads,

  • Then select JSON under Key type.

  • Finally, click on the Create button to download your API key

Your API key will be downloaded automatically.

Create a new folder named server in the root folder of the project that will contain the files for the server and then copy the downloaded JSON file ( trbot-*.json) to the folder.

Note: This is your API key, you should not commit it to a public repository.

Next, add the path to the file to the .env file:

        GOOGLE_APPLICATION_CREDENTIALS=trbot*.json

Make sure to use the correct file name instead of trbot-*.json.

Setup the server

Next, open up a new terminal and then change your current directory to the server folder. Then install the following dependencies that we’ll need for the server:

    # Install Express
    $ npm install express cors body-parser @google-cloud/translate @pusher/chatkit-server  path

The above dependencies include:

  • @google-cloud/translate The translator Node SDK for communication with Google Translate API
  • express A Node framework we are using to build our server
  • @pusher/chatkit-server Chatkit Node.js SDK
  • dotenv A npm package for parsing configs from .env files
  • cors, bodyParser, path

Then create a Node app by adding the below code to server/app.js:

    // ./server/app.js

    const express = require('express');
    const cors = require('cors');
    const bodyParser = require('body-parser');
    const {Translate} = require('@google-cloud/translate');
    const Chatkit = require('@pusher/chatkit-server');
    const resolve =  require("path").resolve;
    require('dotenv').config({path:  resolve(__dirname, "../.env")})

    const app = express(); // create an express app
    const port = process.env.APP_PORT

    // Initialises chatkit client
    const chatkit = new Chatkit.default({
        instanceLocator: process.env.VUE_APP_CHATKIT_INSTANCE_LOCATOR,
        key: process.env.CHATKIT_SECRET_KEY
    })

    // Instantiates a client
    const translate = new Translate({
        projectId: process.env.YOUR_PROJECT_ID,
    });

    app.use(cors());
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

    app.get('/', async (req, res) => {
        res.send({ hello: 'World!'});
    });

    app.listen(port, () => console.log(`Example app listening on port ${port}!`));

In the code above, after importing the packages that we have installed,

  • We created an Express app using const app = express();
  • Next, we initialize the Chatkit SDK and the Translator SDK
  • Then finally, we created an endpoint - / (app.get('/',…) for testing to know if the app works. So, if you visit http://localhost:3000/, you will get a message - { hello: 'World!'}

Next, create a new endpoint for getting rooms that we have on our Chatkit app so we can list them on the chat.

Add the below code the server/app.js file:

    // ./server/app.js

    // [...]
    app.get('/get_rooms', (req, res) => {
        chatkit.getRooms({})
            .then(rooms => {
                res.status(200).send({
                    status: 'success',
                    data: rooms
                });
            })
            .catch(err => {
                res.status(200).send({
                    status: 'error',
                    message: err
                });
            })
    })
    // [...]

This will make a request to Chatkit's server to fetch the public rooms available on our app. It'll return a JSON containing an array of rooms if there is no error, otherwise, it will return a JSON data containing the error message.

Finally, start up the server:

    node app.js

If it starts successfully, you will see a message printed to the terminal - “Node app listening on port 3000!”

Building the chat interface

Now that we have both our client and server apps both running, the next thing we’ll do is to create simple chat interface so we can integrate our translator bot.

Vue enables us to build reusable components which make up our app user interface. We’ll split the app UI into smaller components so we can build them separately:

For brevity’s sake, we’ll divide the app into four components:

  • Messages.vue - for listing messages
  • InputForm.vue - contains a form for sending message
  • Rooms.vue - for listing groups and contains a form for creating a new group
  • Login.vue - displays the login form

Create the Messages.vue, InputForm.vue, Login.vue and Rooms.vue files inside the src/components folder.

To keep the component file as minimal as possible, I have added all the CSS of the components to a single CSS file. Create the CSS file as App.css in the src folder of the project and then add the below styles to it:

    /* ./src/App.css */
    html,body{
        overflow: hidden; 
        width: 100%;
        height: 100%;
        box-sizing: border-box;
        background: #cfd3d3;
    }
    .main{
        width: 99%;
        height: 100vh;
        border: 1px solid green;
        display: grid;
        grid-template-columns: 1fr 4fr;
    }
    .message-area{
        display: grid;
        position: relative;
        grid-template-areas: "head"
                             "messages"
                             "input";
        height: 100vh;
        grid-template-rows: 50px auto 110px;
    }
    .room-wrapper{
       border: 1px solid gray;
       height: 100vh; 
       background: rgba(247, 250, 252, 0.945);
    }
    .search{
        display: block;
        padding: 6px;
    }
    .input-search {
        width: 93%;
        font-size: 17px;
        text-indent: 3px;
        outline: none;
        resize: none;
        flex-direction: row;
        padding: 10px;
        overflow:hidden;
        border:1px solid #556677;
    }
    .rooms{
        margin-top: 3px;
        overflow-y: auto;
        height: 92%;
    }
    .room {
       border-top: 1px solid gray;
       padding: 15px;
       cursor: pointer;
    }
    .room:hover{
        background: rgba(222, 226, 230, 0.952);
    }
    .input-area{
        grid-area: input;
        display: grid;
        grid-template-columns: 1fr;
        /* background: antiquewhite; */
        background: rgba(247, 250, 252, 0.945);
        padding: 20px;
    }
    .input{
        width: 100%;
    }
    .input-message {
        width: 98%;
        border-radius: 8px;
        border: gray;
        font-size: 17px;
        text-indent: 3px;
        display: block;
        outline: none;
        resize: none;
        overflow: auto;
        flex-direction: row;
        padding: 10px;
        overflow:hidden;
        border:3px solid #556677;
    }
    .message-header{
        grid-area: head;
        display: grid;
        grid-template-columns: 1fr 1fr;
        background: rgba(247, 250, 252, 0.945);
        border-bottom: 1px solid rgb(110, 106, 106);
    }
    .message-header-left{
        text-align: left;
        padding: 10px;
    }
    .message-header-right{
        text-align: right;
        padding: 10px;
    }
    .messages {
        grid-area: messages;
        overflow-y: auto;
        overflow-x: hidden;
        padding: 15px 30px;
        background: #929292ad;
    }
    .float-left {
        float: left;
        clear: both;
        background-color: white;
        color: rgba(28, 19, 64, 0.87);
    }
    .float-right {
        float: right;
        clear: both;
        color: #000000;
        background: #cbe4cbf2;
    }
    .message {
        border-radius: 3px;
        width: fit-content;
        padding: 7px;
        margin: 3px 0px;
        clear: both;
        max-width: 50%;
        min-width: 10%;
        word-wrap: break-word;
        font-size: 18px;
    }
    .chat-name{
       font-size: 17px;
       margin: 1px 0px 7px 0px;
       color: #177a2d;
    }
    .login {
        width: 500px;
        border: 1px solid #cccccc;
        background-color: #ffffff;
        margin: auto;
        margin-top: 30vh;
        box-sizing: border-box;
    }
    .input-form {
        margin-bottom: 9px;
        display: block;
    }
    .input{
        display: block;
        margin: 15px;
        width: 93%;
        height: 40px;
        outline: none;
        font-size: 17px;
        text-indent: 5px;
    }
    .submit{
        display: block;
        width: 95%;
        margin: auto;
        padding: 10px;
        margin-bottom: 20px;
        font-size: 17px;
        cursor: pointer;
    }

The Login component

We’ll be using the Single File Component structure for our components.

Add the Login component markup:

    <!-- ./src/components/Login.vue -->
    <template>
        <div class="login">
          <div class="form"> 
                <form @submit.prevent="login">
                    <input 
                        type="text" 
                        class="input" 
                        placeholder="Enter a username"
                        v-model="username"
                        required>
                    <button type="submit" class="submit" :disabled="status === 'processing'"> Login </button>
                </form>
          </div>
        </div>
    </template>

Here, we are making use of @submit.prevent to prevent the page from reloading once a user hits submits the form and passed in the login function so it is called instead.

Next add the script for the Login component:

    <!-- ./src/components/Login.vue -->
    <script>
    export default {
      name: "login",
      props: ['status'],
      data () {
        return {
            username: "",
        }
      },
      methods: {
        login() {
            this.$emit('login', this.username)
            this.username = ""
        }
      }
     }
    </script>

Here, we define the login function that is called once the user submits the form. In the function, we emit an event named “login” so that we can process the login from the parent Component (App.vue) once the user submits the form.

The Rooms component

Next, add the Rooms component markup for the listing of rooms:

    <!-- ./src/components/Rooms.vue -->
    <template>
        <div class="room-wrapper">
            <div class="search">
                <input type="text" placeholder="search..." class="input-search">
            </div>
            <div class="rooms"> 
                <div class="room" 
                    v-for="(room, ind) in rooms"
                    :key="ind"
                    @click="joinRoom(room)"
                    :class="(activeRoom.id === room.id) ? 'active_room' :''"
                >
                    {{room.name}}
                </div>
            </div>
        </div>
    </template>

Using the v-for directive, we loop the rooms available and list them. We also add a @click event handler to listen to click events from the user when they want to join a room. Once a room is clicked, we call the joinRoom function.

Next, add the script of the Rooms component:

    <!-- ./src/components/Rooms.vue -->
    <script>
    export default {
      name:'rooms',
      props: ['rooms'],
      data() {
        return {
          activeRoom: {}
        }
      },
      methods: {
        joinRoom(room) {
          this.activeRoom = room
          this.$emit('joinRoom', room)
        }
      }
    }
    </script>

    <style scoped>
      .active_room{
        background: rgba(197, 202, 207, 0.952);
      }
    </style>

Here, we define the joinRoom function which we are calling on the template section. In the joinRoom function, we set the activeRoom state to the room that was just clicked. Then we emit an event named joinRoom to the parent component so we can add the user to the room.

The Messages component

Next, add the Messages component for the listing of messages:

    <!-- ./src/components/Messages.vue -->
    <template>
        <div ref="messages" class="messages">
            <div v-for="message in messages" :key="message.id">
                <div :class="['message-container message', messageDirection(message, 'float-')]"> 
                    <div class="chat-name"> {{ message.sender.name }} </div>
                    <template v-for="part in message.parts"> 
                        {{part.payload.content}}
                    </template>
                </div>
            </div>
        </div>
    </template>

Here, we loop through the messages that will be passed to this component and then list them. I have also added a float-left and float-right css that will position a message to the left and to the right respectively.

So the messageDirection function will determine if a message will be floated to the left or to the right of the page depending on who is sending the message.

Next, add the script section of the Messages component:

    <!-- ./src/components/Messages.vue -->
    <script>
    export default {
        name: "messages",
        props: ['messages', 'currentUser'],
        methods: {
          messageDirection(message, css='') {
            return (message.senderId !== this.currentUser.id) ? `${css}left` : `${css}right`
          }
        },
    }
    </script>

The InputForm component

Add the InputForm component markup for rendering the form for adding new messages:

    <!-- ./src/components/InputForm.vue -->
    <template>
        <div class="input-area"> 
            <div class="input">
                <textarea
                    v-if="activeRoom"
                    class="input-message" 
                    v-model="new_message" 
                    placeholder="Type a message" 
                    rows="1"
                    @keyup.shift.enter="resizeInput"
                    @keyup.exact.enter="sendMessage">
                </textarea>
                <div v-else style="text-align:center"> 
                    Click on a room to start chatting...
                </div>
            </div>
        </div>
    </template>

And then the script section:

    <!-- ./src/components/InputForm.vue -->
    <script>
    export default {
      name: "input-from",
      props: ['activeRoom', ],
      data () {
        return {
            new_message: "",
        }
      },
      methods: {
        sendMessage(el) {
            if (!this.new_message) return;
            this.$emit('newMessage', this.new_message)
            this.new_message = ""
            el.target.style = 'height:auto;';
        },
        resizeInput(el) {
            if (el.target.scrollHeight < 80) {
                setTimeout(function() {
                    el.target.style = 'height:auto; padding:0';
                    el.target.style = 'height:' + el.target.scrollHeight + 'px';
                }, 0);
            }
        }
      }
    }
    </script>

The App component

This is the main component file that will house all the other components that we have created.

Next, replace the content of the App.vue file with the below:

    <!-- ./src/App.js -->
    <template>
        <div id="app">
            <div v-if="!currentUser">
                <!-- The login component -->
                <Login @login="login" :status="status"/>
            </div>
            <div class="main" v-else>
                <!-- The rooms component -->
                <Rooms @joinRoom="subscribeToRoom" :rooms="rooms"/>
                <div class="message-area">
                    <div class="message-header"> 
                        <div class="message-header-left"> Group Name </div>
                        <div class="message-header-right">  @{{currentUser.id}} </div>
                    </div>
                    <!-- The messages component -->
                    <Messages 
                        :messages="messages" 
                        :currentUser="currentUser" 
                    />
                    <!-- The inputform component -->
                    <InputForm 
                        @newMessage="addMessage"
                        @joinedRoom="joinedRoom=true" 
                        :activeRoom="activeRoom"
                    />
                </div>
            </div>
        </div>
    </template>

The is the overall mark-up of our app grouped together.

Notice the components that we created earlier:

  • <Login… Remember, we emitted an event named *login* once the user submits the login form. Here, we are using the @login (short form of v-on:login) and thereby call a login function to process the login.
  • <Rooms… As with the Login component, we listen to the joinRoom event that will be triggered on the component using @joinRoom and then handle the event by calling subscribeToRoom function.
  • <Messages… The same thing applies as with other components
  • <InputForm… The same thing applies as with other component

Next, add the script section of the App.vue file:

    // ./src/App.vue

    <script>
    import { ChatManager, TokenProvider } from '@pusher/chatkit-client'
    import axios from 'axios'

    import Messages from '@/components/Messages'
    import InputForm from '@/components/InputForm'
    import Rooms from '@/components/Rooms'
    import Login from '@/components/Login'

    import './App.css'

    export default {
      name: 'app',
      components: {
        Messages,
        InputForm,
        Rooms,
        Login
      },
      data() {
        return {
            messages: [],
            chatManager: null,
            currentUser: null,
            rooms: [],
            activeRoom: null,
            status: null
        }
      },
      methods: {
      },
    }
    </script>

Now, reload the app to confirm that the page renders properly.

Making the chat work

So far, we have our chat interface ready but we still can’t converse because we are yet to connect the app to Chatkit. We’ll be doing so next.

To start using the SDK, we first need to initialize it. Do so by adding the below function in the methods: {…} block in the App.vue file:

    // ./src/App.vue

    // [...]
        setupChatKit(username) {
          // Initialise the token provider
          const tokenProvider = new TokenProvider({
            url: process.env.VUE_APP_CHATKIT_TOKEN_ENDPOINT
          });

          // Initialise the chatkit manager
          const chatManager = new ChatManager({
            instanceLocator: process.env.VUE_APP_CHATKIT_INSTANCE_LOCATOR,
            userId: username,
            tokenProvider: tokenProvider
          });

          chatManager
            .connect()
            .then( currentUser => {
              this.currentUser = currentUser
              // Fetch rooms
              axios.get(`${process.env.VUE_APP_SERVER}/get_rooms`)
                .then(data => {
                  this.rooms = data.data.data
                })

            })
            .catch( error => {
              this.status = 'error'
            });
        },
    // [...]

When we want to initialize Chakit, we can call this function to do so.

Add the login function in the methods: {…} block in the App.vue file:

    // ./src/App.vue

    // [...] 
       login(username) {
            this.status = 'processing'
            this.setupChatKit(username)
        },
    // [...]

So if the user logs in, then we initialize the Chatkit app. Note that we are not doing any real authentication here. This is the best place to authenticate your users if you restrict access to your chat app.

Next, let’s add a function for subscribing to rooms. To receive notification from a room like when a new message is added to a room, we need to be subscribed to that room.

Add the below function in the methods: {…} block of the App.vue file:

    // ./src/App.vue

    // [...]
        subscribeToRoom(room) {
            this.messages = []
            this.currentUser
                .subscribeToRoomMultipart({
                    roomId: room.id,
                    hooks: {
                        onMessage: message => {
                            this.messages.push(message)
                        }
                    },
                    messageLimit: 40
                })

            this.activeRoom = room
        },
    // [...]

Next, add a function for adding new messages to the methods: {…} block of the App.vue file:

    // ./src/App.vue

    // [...]
        addMessage(message) {
            this.currentUser.sendSimpleMessage({
                    roomId: this.activeRoom.id,
                    text: message,
              })
        },
    // [...]

The translator bot

Good! At this point what is left is to integrate our translator bot. The job of the bot will be to translate messages from one language to another whenever it is called upon.

This is a sample conversation flow with the bot:

A message directed to the bot has to be in this format - @trbot translate 'What you want the bot to translate' to language, where:

  • @trbot Is the bot’s ID. Remember that we’ve created a user with that ID that will stand in as our bot.
  • translate Has to be present so that we know that you are taking to the bot.
  • 'What you want the bot to translate' The message you want the bot to translate. It has to be in either single or double quotes.
  • to Has to be present after the message that you want to translate.
  • language The language that you want the text to be translated to. This is either the language name (like English, French, and so on) or the language code (like en, fr, and so on).

Chatkit’s webhook

A webhook is an HTTP POST request made to an endpoint of your choosing to notify you of some event. With the webhook, we can tell Chatkit to make a request to a given URL once a certain type of events happens.

For our use-case, we want to be notified when a message is added to a room. We are most concerned with the Message Created event that will be triggered when a message is added to a room.

Extract data from message

When a message hits our webhook, we need to determine if the message is directed to our bot. Using a regular expression, we can determine if the message is in the form directed to the bot. If the message satisfies the regular expression, we return the matched parameters or false otherwise.

Add the function for extracting data from a message:

    // ./server/app.js

    // [...]
    function extractData(data) {
        const regex = /(@trbot)\s+translate.*\['"\](.+)['"].*to\W*(\w+)/gim
        const found = regex.exec(data);

        if (!found || found.length < 4) {
          return false
        }

        return {text: found[2], language: found[3]}
    }
    // [...]

Get the language code

To use the Google Translate API, we need the language code of the language that we want to translate a text to.

Add the function for getting the code of a language:

    // ./server/app.js

    // [...]
    async function getLanguageCode(lang) {
        const [languages] = await translate.getLanguages();

        var foundLang = languages.find((language) => {
            return (language.code ===  lang.toLowerCase() 
                || language.name.toLowerCase() === lang.toLowerCase());
        });

        return foundLang ? foundLang.code : false;
    }
    // [...]

In the function above, we call the getLanguages function from the Translate SDK to get all the languages available for translations. Then we find the code of the language we are looking for and then return the code if found otherwise false.

Send response to the room

Now when we translate a message, we need to send the result to the room as trbot.

Add the function for doing so:

    // ./server/app.js

    // [...]
    function trbotSendMessage(roomId, message) {
        return chatkit.sendSimpleMessage({
            userId: 'trbot',
            roomId: roomId,
            text: message,
        })
    }
    // [...]

Create the webhook endpoint

Finally, let’s create an endpoint for the webhook for translating messages.

When Chatkit makes POST request to our endpoint, it sends along with the message that was created in this format.

Add the function for creating the /translate endpoint:

    // ./server/app.js

    // [...]
    app.post('/translate', async (req, res) => {
        const messages = req.body.payload.messages // sent from chatkit
        const room_id = messages\[0\]['room_id'] // sent from chatkit

        // Extract the params from the message - like the language, the text message
        const data = extractData(messages\[0\]['parts']\[0\]['content'])

        // Return response early - see https://pusher.com/docs/chatkit/webhooks#retry-strategy
        res.sendStatus(200)

        if (data) { // if message is directed to trbot
            const {text, language} = data
            const langCode = await getLanguageCode(language)

            if (!langCode) {
                trbotSendMessage(room_id, 'Sorry, you need to pass in a valid language' )
            }

            const translation = await translate.translate(text, langCode)
            trbotSendMessage(room_id, translation[0] )
        } 
    })
    // [...]

If the message is directed to trbot, we call the translate function to translate the message - await translate.translate(….

Then finally, once we have the translation for the text, we send it to the same room that the message is coming from using trbotSendMessage(…

Enable the webhook

Although we have our endpoint for translating message ready which is accessible from http://localhost:3000/translate it can only be accessible from your local system. We need to expose the URL so it can be accessible by Chatkit which we can do using ngrok.

Open up ngrok and expose the URL:

    ./ngrok http 3000

Now note any of the Forwarding URLs which can now be accessed from anywhere.

Head to your Chatkit Dashboard and enable the webhook:

  • Click on the Settings tab
  • Fill in the NAME as trbot or any convenient name.
  • Fill in the TARGET URL the Ngrok generated URL (eg: https://.ngrok.io/translate). Remember to add the /translate after the URL.

Testing the chat

Good job! you have successfully built a bot.

Now let’s test the app to see that it works.

  • Restart the Node server terminal
  • Open the app in two or more tabs on your browser
  • Now join a room and start chatting

Conclusion

In this tutorial, we successfully built a translator bot using the Google Translate service. We explored a way by which you can add bots to your Chatkit app using the webhook feature.

There is no limit of what you can build from here. What we've built is just a tip of what you can do with bots.

You can find the complete code of this tutorial on GitHub.

Clone the project repository
  • Chat
  • CSS
  • JavaScript
  • Node.js
  • Vue.js
  • Chatkit

Products

  • Channels
  • Chatkit
  • Beams

© 2019 Pusher Ltd. All rights reserved.

Pusher Limited is a company registered in England and Wales (No. 07489873) whose registered office is at 160 Old Street, London, EC1V 9BW.