Automatically reply to chat messages using TalkJS webhooks

We'll show you how to build a chat application that automatically responds to messages sent during certain hours using the TalkJS Chat API together with REST and Webhooks. To test our application locally we will use ngrok.

Setting up a chat with TalkJS

We will follow the Getting Started Guide to set up the chat. Remember to replace "YOUR_APP_ID" with your TalkJS appID which is found in the dashboard. The code should look as below:

Talk.ready.then(()=> {
    var me = new Talk.User({
        id: '000003',
        name: 'Jon',
        email: 'jon@example.com',
        photoUrl: 'https://talkjs.com/images/avatar-2.jpg'
    });
    var other = new Talk.User({
        id: '000004',
        name: 'Sam',
        email: 'sam@example.com',
        photoUrl: 'https://talkjs.com/images/avatar.jpg'

    });

    // Initialize chat Session
    window.talkSession = new Talk.Session({
        appId: 'YOUR_APP_ID',
        me: other
    });

    let conversation = talkSession.getOrCreateConversation(
        Talk.oneOnOneId(me, other)
    );

    conversation.setParticipant(me);
    conversation.setParticipant(other);

    conversation.setAttributes({
        subject: "Team TalkJS",
        photoUrl: "https://talkjs.com/images/logo.jpg"
    });

At this point we should have a chat between two users. We now want to configure the chat so that if user Sam sends a message during a certain time that the other user (or service provider) will be unavailable, there will be an automated response. To do this we will use webhooks.

Webhooks

Webhooks are user defined HTTP callbacks, often triggered by some event for example a message being sent, or a comment being posted to a blog. Webhooks work by sending POST requests to an application's server when certain events happen.

When webhooks are enabled in the TalkJS dashboard, your server will receive HTTP POST requests from the TalkJS Server notifying you about events that happen in your application between your users.

We will set up a server using Express to listen to these requests.

Express

Express is a minimal and flexible Node.js web application framework. We will use Express to set up a basic server to listen to the webhooks POST requests.

You also need to have Node installed.

Let us create a file named main.js for our express server.

After that install express:

npm install express ---save

Once installed we will set up our server to listen for incoming requests on port 3000, and for any POST requests that are on the url path 'webhooks/talkjs'. If there is a POST request we also want to send back a status 200 to the TalkJS server, and inside this callback we can implement the logic to send the automated response :

import express from 'express';

const port = process.env.PORT || 3000;

const app = express();
app.post('/webhooks/talkjs', (req, res)=> {
    res.sendStatus(200);

    // send back automated response
})

app.listen(port, ()=> {
    console.log(`Server started, listening on port: ${port}`)
})

After this if we run node main.js we should see our server running and a message in the console.

However our server is a local server, and for it to receive webhooks requests it must be exposed to the internet. For this we turn to a tool called ngrok.

ngrok

Ngrok is a cross-platform application that allows us to expose web servers running on our local machines to the internet. This means we can expose our express server to the internet and listen for TalkJS webhook POST requests.

Here's a more comprehensive tutorial for integrating ngrok with TalkJS.

You will need to install ngrok and then sign up. Once that is done we can start an ngrok tunnel forwarding to our local port 3000:

ngrok http 3000

This will start ngrok and in the console you should see the url which we will use to receive the TalkJS webhooks requests:

Ngrok also provides a real-time web UI where you can look at all of the HTTP traffic running over your tunnels at http://localhost:4040.

Now we need to log into the TalkJS dashboard and go to the settings for webhooks. There we will post the ngrok url shown in the console and add the suffix 'webhooks/talksjs' and also choose the events we wish to have POST requests for, in our case message sent and save:

Now whenever a message is sent in our chat (the one in index.html), it will trigger a webhooks event and a post request will be sent to our express server.

We now need to implement the logic to send a system message when our server receives a webhooks event. For this we will use the TalkJS REST API.

TalkJS REST API

The TalkJS REST API offers a way to programmatically interact with TalkJS features from the backend. It can be used, for example, to send messages, delete users and list conversations.

In our case we will use it to send a system message.

We will use node-fetch to make requests. We also need the appId, and the secret key for authentication. Both these are found in the TalkJS dashboard. To send messages the request must also include the conversation id.

We will define an asynchronous function named sendMessage, specify the url path as defined in the TalkJS docs and then create an object of the message we wish to send. The type of the message must be set to SystemMessage. We will then use fetch to send the request, and specify it as PUT, as shown below:

import fetch from "node-fetch";

const host = "https://api.talkjs.com";
const appId = "YOUR_APP_ID";
const secretKey = "YOUR_SECRET_KEY";
const conversationId = "3914bd533eed671af189";


async function sendMessage() {
    const url = host + `/v1/${appId}/conversations/${conversationId}/messages`;

    const message = [
        {
            text: "We are currently offline. However you can leave a message and we will get back to you. ",
            type: "SystemMessage"
        }
    ];

    const response = await fetch(url, {
        method: "POST",
        body: JSON.stringify(message),
        headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${secretKey}`
        }
    });

Now, whenever the function sendMessage is called, it will send a SystemMessage.

Responding to Messages

The automated system message must be send when a user sends a message outside a predefined time period. Whenever a message is sent, the TalkJS server sends a post request to our server (through ngrok), and our server sends back an HTTP 200 OK to acknowledge the event. We then check the time when current time and compare it to our opening and closing times, and if the time is outside operating hours we call the function sendMessage:

// Listen to webhook events
app.post('/webhooks/talkjs'(req, res)=> {
    res.sendStatus(200);
    console.log('webhook received');

    // Get UTC time
    let utcHoursNow = new  Date().getUTCHours();
    let onlineTime = (utcHoursNow >= openingTime && utcHoursNow <= clossingTime);

    if(!onlineTimes){
        sendMessage();
    }
})

Now whenever a user sends a message outside operating hours, they will receive an automated system message response.

Want to learn even more things you can build using TalkJS ? Check out more tutorials on our website. Happy coding!