You can make your website display a notification bubble when your bot sends a new message.
The notification bubble is only displayed if the Webchat window is closed when you receive the message. You can then:
Open the notification (by clicking it or pressing Enter / Space )
Dismiss the notification (by clicking ×)
Open Webchat using the FAB (which dismisses the notification automatically)
Since Webchat uses Markdown for rich text in messages, some messages may not render properly in the notification bubble without further processing.
Step 1: Add a Hook to your bot
In the Studio, navigate to the Hooks section.
Select Create Hook and set its type to Before Outgoing .
Paste the following code into the Hook:
await actions . webchat . customEvent ({
conversationId: event . conversationId ,
event: JSON . stringify ({
eventType: 'notification' ,
message: outgoingEvent . preview ,
})
})
This Hook notifies your website every time your bot sends a new message—that way, your website can display a notification bubble.
Now, you can configure your website to display the notification bubble.
Add the bubble HTML element
First, add the bubble element somewhere in your website’s HTML:
<!-- Notification Bubble -->
< div id = "msgDiv" class = "cb tri-right btm-right" role = "button" tabindex = "0" aria-live = "polite" aria-label = "Notification" style = "display:none" >
< span id = "msgText" ></ span >
< button class = "close-chip" type = "button" aria-label = "Dismiss" > × </ button >
</ div >
Add JavaScript
Then, add the following snippet to your website’s JavaScript:
function openNotification () {
if ( window . botpress ) {
window . botpress . open ();
} else {
alert ( 'Botpress integration not available.' );
}
}
( function () {
const msgDiv = document . getElementById ( 'msgDiv' );
const msgText = document . getElementById ( 'msgText' );
const closeBtn = msgDiv ?. querySelector ( '.close-chip' );
function showBubble ( text ) {
if ( ! msgDiv || ! msgText ) return ;
// Display the notification bubble
msgText . textContent = text || '' ;
msgDiv . style . display = 'block' ;
// Avoid stacking handlers on repeated events
msgDiv . onclick = () => openNotification ();
// Keyboard access
msgDiv . focus ();
msgDiv . onkeydown = ( e ) => {
if ( e . key === 'Enter' || e . key === ' ' ) {
e . preventDefault ();
openNotification ();
}
};
// Hide the notification bubble if Webchat is opened
window . botpress . on ( 'webchat:opened' , () => {
if ( msgDiv ) msgDiv . style . display = 'none' ;
});
// Optional auto-hide after a period
setTimeout (() => ( msgDiv . style . display = 'none' ), 15000 );
}
// Close/dismiss without action
if ( closeBtn ) {
closeBtn . addEventListener ( 'click' , ( e ) => {
e . stopPropagation ();
msgDiv . style . display = 'none' ;
});
}
// Extract payload from event
function extractPayload ( raw ) {
let data = raw ;
// If the data is a string
if ( typeof data === 'string' ) {
try { data = JSON . parse ( data ); } catch { /* ignore */ }
}
// Handle both strings and objects as event types
if ( data && typeof data . event === 'string' ) {
try { data = JSON . parse ( data . event ); } catch { data = { eventType: data . eventType , ... data }; }
} else if ( data && typeof data . event === 'object' ) {
data = data . event ;
}
return data || {};
}
if ( window . botpress ?. on ) {
// Listen for custom events from the bot
window . botpress . on ( 'customEvent' , ( payload ) => {
const webchat = document . querySelector ( 'iframe[title="Botpress"]' );
const data = extractPayload ( payload );
// Show the notification bubble if the Webchat window is closed
if ( data ?. eventType === 'notification' && webchat && webchat . classList . contains ( 'bpClose' )) {
showBubble ( data . message );
}
});
}
})();
See all 82 lines
This handles the behaviour of the notification bubble. For example:
Displays the message received from the event’s payload
Remains visible for 15 seconds before automatically closing
Can be selected by clicking or pressing Enter / Space
You can configure the behaviour to suit your needs by modifying the code snippet.
Add CSS
Finally, add this CSS snippet to your website’s stylesheet:
:root {
/* Change these to match your page's brand */
--bubble-bg : #ccddfa ; /* background */
--bubble-fg : #173569 ; /* text */
}
.cb {
position : fixed ;
right : 24 px ;
bottom : 102 px ;
z-index : 9999 ;
display : none ; /* shown by JS */
background : var ( --bubble-bg );
color : var ( --bubble-fg );
border-radius : 16 px ;
padding : 14 px 42 px 14 px 16 px ;
max-width : 340 px ;
line-height : 1.35 ;
box-shadow : 0 10 px 25 px rgba ( 0 , 0 , 0 , .18 );
cursor : pointer ;
font-family : Roboto, system-ui , -apple-system , Segoe UI, Roboto, "Helvetica Neue" , Arial ;
font-size : 15 px ;
transition : transform .2 s ease , box-shadow .2 s ease , opacity .2 s ease ;
animation : bubble-in .28 s cubic-bezier ( .2 , .8 , .2 , 1 ) both ;
}
.cb:hover {
transform : translateY ( -1 px );
box-shadow : 0 12 px 30 px rgba ( 0 , 0 , 0 , .22 );
}
.cb:focus {
outline : none ;
}
/* Chat tail */
.tri-right.btm-right::after {
content : "" ;
position : absolute ;
right : 22 px ;
bottom : -8 px ;
width : 16 px ;
height : 16 px ;
background : var ( --bubble-bg );
transform : rotate ( 45 deg );
box-shadow : 0 10 px 25 px rgba ( 0 , 0 , 0 , .18 );
border-bottom-right-radius : 4 px ;
}
/* Close chip (optional, inside the bubble) */
.cb .close-chip {
position : absolute ;
top : 8 px ;
right : 8 px ;
width : 26 px ;
height : 26 px ;
border-radius : 999 px ;
background : rgba ( 255 , 255 , 255 , .18 );
color : var ( --bubble-fg );
border : 0 ;
cursor : pointer ;
line-height : 1 ;
font-size : 16 px ;
}
.cb .close-chip:hover {
background : rgba ( 255 , 255 , 255 , .28 );
}
@keyframes bubble-in {
from { transform : translateY ( 10 px ) scale ( .98 ); opacity : 0 ; }
to { transform : translateY ( 0 ) scale ( 1 ); opacity : 1 ; }
}
See all 75 lines
You can modify the styling as needed.
Now, your website will display a notification bubble when your bot sends a new message.