Create a Simple Messaging App!

Hey, there fellow developers …

In this example, I’ll demonstrate how to create a simple messaging app to engage users on your website, this is important for support websites, eCommerce stores, social media websites, and many more scenarios.

We’ll be using the real-time APIs to publish messages. On the backend, store the message in a database for future reference then publish the message to the user’s channel. Example:

// Theoratical users
const john = {
    name: 'John',
    id: 'random-text-1'
}

const ahmad = {
    name: 'Ahmad',
    id: 'random-text-2'
}

Now to communicate with each other, ideally, when John visits my profile, you need to check MY settings if I accept non-friends messages and that John isn’t blocked by me. (not included in the example, let me know if you’re interested to know how).

Then, once John clicks “Message Ahmad”, a chat window will be opened based on my ID, and you’ll need to subscribe John to my messages’ channel as well as his.

Prepare the environment

import wixRealtime from 'wix-realtime';

const messages = []; // Storing the conversation messages locally.

1. Add a messages listener.

In this step, we’ll handle the messages sent by me “Ahmad” to John.

// Subscribe to my channel
const ahmadChannel = { name: 'user-messages', resourceId: `msg-${ahmad.id}` }
wixRealtime.subscribe(ahmadChannel, (notification, channel) => {
    /* All received messages from "Ahmad" are meant for John, we can
    control that later on */
    const message = {
        _id: notification.payload.id, // a unique message identifier
        origin: 'forign', // Determain who own the message.
        date: new Date(), // The date that the message was received on.
        message: notification.payload.message // The actual mesage
    }
    
    // Add the message to the messages array
    messages.push(message);
    
    // Update the repeater displayed messages:
    $w('#repeaterMsgs').data = messages;
})

2. Allow John to receive his messages on other devices.

Most of the time, you’ll have more than one device opened, say for example on your computer and your phone, this will ensure that whatever John sends me from his computer will also appear on the conversation on his phone.

/* Subscribe to John messages. This is important because we want other tabs/pages
that the website is opened on to listen to the messages and display them as well,
so when John sends a message to me from his laptop, the message will also appear
on his phone or computer. */

const myChannel = { name: 'user-messages', resourceId: `msg-${john.id}` }
wixRealtime.subscribe(myChannel, (notification, channel) => {
    /* All received messages from the user himself, but we need to check whether
    the message is sent from this device/tab/window or not */
    
    if (messages.map(items => items._id).indexOf(notification.payload.id) === -1) {
        // Store the message and display it
        const message = {
            _id: notification.payload.id, // a unique message identifier
            origin: 'me', // Determain who own the message.
            date: new Date(), // The date that the message was received on.
            message: notification.payload.message // The actual mesage
        }
        
        // Add the message to the messages array
        messages.push(message);
    
        // Update the repeater displayed messages:
        $w('#repeaterMsgs').data = messages;
    } else {
        // Ignore the message because it's already here.
    }    
})

3. Allow John to send messages (Backend & Frontend).

To allow John to send me a message, we need a backend module and a frontend app.

A) Prepare the backend function that will publish the messages:

import wixRealtimeBackend from 'wix-realtime-backend';

export function sendMessage(message, toId) {
    // Specify the user channel
    const channel = { name : 'user-messages', resourceId: `msg-${toId}`};
    
    // Prepare the payload
    const payload = {
        id: String(Math.floor(Math.random() * 10000)),
        message: message
    }
    
    // Prepare the payload options
    const payloadOptions = {
        users: [toId],
        includePublisher: true
    }
    
    */ users: List of users to receive the message, in our case only one person
    should receive it, which is the specified person */
    
    // Publish the message to the specified recipants
    return wixRealtimeBackend.publish(channel, payload, payloadOptions) .then(() => {
          // You can store the message in a database here
          
          return Promise.resolve();
    });
}

In this step, you can store the messages in a database to view them on tabs opened later, see when it’s delivered, seen, and more. (Not included in the example).

B) Now prepare the frontend app to send the message, we’ll create a function that will be triggered when the user clicks on “Send” or hit “Enter”.

// Import our backend function, make sure to replace the module below with your module name
import chat from 'backend/myModule.jsw';

function send(message) {
    // Check if there's something to send or not.
    if (typeof message === 'string' && message.length > 0) {
        // Add the message to the messages array
        messages.push(message);
    
        // Update the repeater displayed messages:
        $w('#repeaterMsgs').data = messages;
        
        // Send the message
        return chat.sendMessage(message).then(() => {
            // Handle the case where the message is successfully sent
        }).catch(err => {
            console.error(err);
            // Mark the failed message as "not sent" with red marker or something.
        })
    }
}

$w('messageInputBox').onInput(event => {
    // Enable the "Send" button if there's a message and disable it if otherwise
    if (event.target.value) {
        if (!$w('sendBtn').enabled) { $w('sendBtn').enable() }
    } else {
        if ($w('sendBtn').enabled) { $w('sendBtn').disable() }
    }
})

// Trigger the the function to send the message.
$w('sendBtn').onClick(() => send($w('messageInputBox').value));
$w('messageInputBox').onKeyPress((event) => {
    if (event.key === 'Enter') {
        // Check if the user wants to send the message or create a new line
        if (event.shiftKey) {
            // Create a new line
            $w('messageInputBox').value = `${$w('messageInputBox').value}\n`;
        } else {
            // Disable the text input
            $w('messageInputBox').disable().then(() => send($w('messageInputBox').value));
        }
    }
})

Here you have it, folks, if you have any questions feel free to ask in the comments below, if you want to request a tutorial about this topic you can do that too.

Take a look at my previous tutorials videos.

Hope this was helpful~!
Ahmad

7 Likes

:+1::pray::fire:

1 Like

Interesting stuff → like always! Thumbs up!

1 Like

Hi,
I can not load the full page.

Sorry about that, there’s an error on Wix side that prevents the page from loading and they’re investigating the issue now, I’ll update you once the issue is fixed.

Thanks.

1 Like

The issue has been fixed!

1 Like

Can this be used dynamically?

Definitely!

@ahmadnasriya Can you give a live website link where you implemented this? Please?

1 Like