Skip to content

Adding a banner to chat messages

Tips
  • What if you wanted to add a banner message to your chat messages, but didn’t know how? Here’s what that might look like, and how it would work

    0b4a91a4-35e2-4780-b3fc-1b235e1516bb-image.png

    I get a lot of support requests via Chat, and I can appreciate why because it’s convenient. However, whilst I’m helping you solve your issue, others are missing out on that information and resolution, so I will always request please that you ask questions in the forum categories, and only discuss sensitive information like usernames and passwords etc in chat.

    Let’s get started. It’s very simple providing you know what to target, which requires some examination of the HTML structure. In this case, we are going to target element [component="chat/message"] because it’s the element we need to inject into

    Firstly, the JS code

    function chatBanner() {
    $('[component="chat/message"]:last-of-type').append('<div id="chatbanner">This session is for private discussion only between the chosen participants. Please do not place support requests here and use the forum categories instead.</div>');
    }
    
    $(window).on('action:chat.loaded', function(data) {
    	$(document).ready(function() {
    		chatBanner()
    	});
    });
    

    And then some custom CSS

    div#chatbanner {
        padding: 10px 20px 10px 20px;
        background: var(--bs-alert-info-bg);
        border-radius: 0.375rem;
        margin: 0px 0 20px 0;
    }
    

    All done. This message will insert itself at the last [component="chat/message"] in the stream when the chat is loaded - you could make it display on each message, but that’s overkill in my view and people only need to see it once to read and understand.

    To accomplish only using the last of [component="chat/message"], we target [component="chat/message"]:last-of-type which is a common CSS denominator, and very powerful.

    Enjoy.

  • Thank you very much @phenomlab , It’s very useful ^^

    I just add a fa icon information to the code like this 😉

    $('[component="chat/message"]:last-of-type').append('<div id="chatbanner"><i class="fa fa-fw fa-circle-info link-primary" aria-hidden="true"></i> This session is for private discussion only between the chosen participants. Please do not place support requests here and use the forum categories instead.</div>');
    

    d29c4a0d-2248-45f6-91cc-5eb85cfbba11-image.png

    🙂

    On the other hand, we French use a lot of accent in our sentences like the word “j’aime” and if I put it here, the code does not work. So I found a sentence or I don’t put 😉

    I also wonder if this code will work on the new nodebb public chat room feature. I think yes but maybe we want to use a room to help live, so I think we will have to target this special room in the code to display another message (or none)

  • @DownPW said in Adding a banner to chat messages:

    On the other hand, we French use a lot of accent in our sentences like the word “j’aime” and if I put it here, the code does not work. So I found a sentence or I don’t put

    The reason for this is that the apostrophe is a system symbol, which means it needs to be escaped so that the text is read as was intended, and not as a system command. For example.

    The below text

    “This is an example paragraph that would not work if used in the traditional way. It’s going to be read incorrectly as code when it isn’t which means you’ll get an error instead of the text you actually wanted.”

    Would need to be entered as

    \"This is an example paragraph that would not work if used in the traditional way. It\'s going to be read incorrectly as code when it isn\'t which means you\'ll get an error instead of the text you actually wanted.\"
    

    The usage pattern is easy to see, but if you want to play with potential combinations, use the site below

    https://onlinestringtools.com/escape-string

    @DownPW said in Adding a banner to chat messages:

    I also wonder if this code will work on the new nodebb public chat room feature. I think yes but maybe we want to use a room to help live, so I think we will have to target this special room in the code to display another message (or none)

    It should work in the same way. It will likely need to be extended to support new (multiple) targets, but will work nonetheless.

  • Can you think you can update the code for v3.3 to target a specific room or several room?

  • @DownPW yes, that should be possible. I’ll have a look later on today.

  • Ha yes very cool

  • @DownPW In my testing, this works already.

    0986c977-26ec-4403-83f9-0e5ae10190ba-image.png

    EDIT: As per PM discussion, I see what you’re looking for. This would effectively provide that result. It relies on the name of the room to display the relevant message - from the code example below, you can modify this ro suit your needs

    // Chat message banner
    function chatBanner() {
        var roomName = $("h5[component='chat/header/title']").text().trim();
        if (roomName === "Test") {
            var banner = '<div id="chatbanner">This message will fire for chat rooms with the title of "Test"</div>';
        } else {
            var banner = '<div id="chatbanner">This session is for <strong>private discussion only</strong> between the chosen participants. Please do <strong>not</strong> place support requests here and create a <a href="#" onclick="app.newTopic();">new topic</a> instead.</div>';
        }
        return $('[component="chat/message"]:last-of-type').append(banner);
    }
    
    $(window).on('action:chat.loaded', function(data) {
        $(document).ready(function() {
            chatBanner()
        });
    });
    
    
  • As requested by @DownPW (plus the samples above), below is some updated code that will also fire on empty rooms

    // Chat message banner
    function chatBanner() {
        var roomName = $("h5[component='chat/header/title']").text().trim();
        var bannerContent;
        if (roomName === "Testing 2") {
            bannerContent = '<div id="chatbanner">This message will fire for chat rooms with the title of "Testing 2"</div>';
        } else {
            bannerContent = '<div id="chatbanner">This session is for <strong>private discussion only</strong> between the chosen participants. Please do <strong>not</strong> place support requests here and create a <a href="#" onclick="app.newTopic();">new topic</a> instead.</div>';
        }
        var chatMessagesContainer = $('[component="chat/messages"]');
        var existingMessages = $('[component="chat/message"]');
    
        if (existingMessages.length === 0) {
            // If there are no messages, append the banner to the messages container
            chatMessagesContainer.append(bannerContent);
        } else {
            // If there are messages, add the banner after the last message
            existingMessages.last().after(bannerContent);
        }
    }
    
    $(window).on('action:chat.loaded', function(data) {
        $(document).ready(function() {
            chatBanner()
        });
    });
    

    You obviously need to specify the room names you are using (in the case of the sample above, it’s “Testing 2”). I’ve also restructured the code so that the following enhancements apply

    Optimize Selector: Instead of using the [component="chat/message"] selector, which might be slower, I’ve decided to use classes (or where available, ID’s). This should improve performance, especially if the chat interface becomes more complex.

    Appending the Banner: The previous code attempted to append the banner to the content of the last message - seeing as I’ve modified the code so that a primary condition exists first where if there are no messages in the room, the banner will still be appended (it wasn’t before). This means that the banner is no longer an independent element, but incorporated into the message stream which should make it faster.

  • Hmmm tested your new code but I have the same banner message now

  • @DownPW Seems to work fine in my extensive testing

  • Ok so there is a problem on my side. Sorry, test it again

  • @DownPW let me know how you get on.

  • Work now with empty chat room, Thank you 🙂
    But they appear at the very bottom of the chat :

    98e475da-fa86-410d-ac8f-a752be0ba7b3-image.png

    Just see that the banner is displayed even after a system event :

    component="chat/system-message"

    02c5edc5-89b5-4f9f-a342-449ab1371155-image.png

    System events should be considered as a separate message for thebanner message to be displayed below.

  • @DownPW did the chat banner work in the way you expected here?

  • @phenomlab said in Adding a banner to chat messages:

    @DownPW did the chat banner work in the way you expected here

    A little bit. See hère:

    @DownPW said in Adding a banner to chat messages:

    Work now with empty chat room, Thank you 🙂
    But they appear at the very bottom of the chat :

    98e475da-fa86-410d-ac8f-a752be0ba7b3-image.png

    Just see that the banner is displayed even after a system event :

    component="chat/system-message"

    02c5edc5-89b5-4f9f-a342-449ab1371155-image.png

    System events should be considered as a separate message for thebanner message to be displayed below.

  • @DownPW I think this is what you want - let me know

    a1670323-e770-4717-b63e-759832e1b012-image.png

    in this case, the code has to be modified so it looks like the below

    // Chat message banner
    function chatBanner() {
        var roomName = $("h5[component='chat/header/title']").text().trim();
        var bannerContent;
        if (roomName === "Testing 3") {
            bannerContent = '<div id="chatbanner">This message will fire for chat rooms with the title of "Testing 3"</div>';
        } else {
            bannerContent = '<div id="chatbanner">This session is for <strong>private discussion only</strong> between the chosen participants. Please do <strong>not</strong> place support requests here and create a <a href="#" onclick="app.newTopic();">new topic</a> instead.</div>';
        }
        var chatMessagesContainer = $('[component="chat/system-message"]:last-of-type');
        var existingMessages = $('[component="chat/message"]');
    
        if (existingMessages.length === 0) {
            // If there are no messages, append the banner to the messages container
            chatMessagesContainer.first().after(bannerContent);
        } else {
            // If there are messages, add the banner after the last message
            existingMessages.last().after(bannerContent);
        }
    }
    
    $(window).on('action:chat.loaded', function(data) {
        $(document).ready(function() {
            chatBanner()
        });
    });
    

    This will place the banner after the last system message and before any of the messages themselves. If there are existing messages in the room, the banner will be placed at the footer of the last message so it is seen each time.

    484a7ebb-8246-4a44-8227-b0ab0f42ae56-image.png

  • Thanks Mark, you are a champion 🙂

    Test this code ASAP

  • I have tested now this last code, It’s clearly better, Thnks you again.
    Just one things mark @phenomlab, the banner don’t appear if there is empty (no message) :

    f7d5e292-9139-4efa-a3b4-f13e60171e48-image.png

  • @DownPW Does it appear if you reload the page?