npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

rasa-webchat-josh

v0.0.9

Published

Chat web widget for React apps and Rasa Core chatbots; created from rasa webchat

Downloads

11

Readme

webchat

A simple webchat widget to connect with a chatbot. Forked from react-chat-widget Further forked from rasa-webchat

Features

  • Text Messages
  • Quick Replies
  • Images and Videos
  • Snippet style for links (only as responses for now)
  • Markdown support
  • Easy to import in a script tag or as a React Component
  • Persistent sessions
  • Event Observer

demonstration

Setup

In a ` tag

In your <body/>:

<div id="webchat"/>
<script src="https://storage.googleapis.com/mrbot-cdn/webchat-0.5.0.js"></script>
<script>
  WebChat.default.init({
    selector: "#webchat",
    initPayload: "/get_started",
    interval: 1000, // 1000 ms between each message
    customData: {"userId": "123"}, // arbitrary custom data. Stay minimal as this will be added to the socket
    socketUrl: "http://localhost:5500",
    socketPath: "/socket.io/",
    title: "Title",
    subtitle: "Subtitle",
    inputTextFieldHint: "Type a message...",
    connectingText: "Waiting for server...",
    fullScreenMode: false,
    profileAvatar: "http://to.avat.ar",
    openLauncherImage: 'myCustomOpenImage.png',
    closeLauncherImage: 'myCustomCloseImage.png',
    params: {
      images: {
        dims: {
          width: 300,
          height: 200,
        }
      },
      storage: "local"
    }
  })
</script>

About images: width and height define the size in pixels that images in messages are crop-scaled to. If not present, the image will scale to the maximum width of the container and the image.

It is recommended to use a particular version (i.e. "webchat-.js") however the file "webchat-latest.js" is also available and is updated continuously with the latest version.

As a React component

Install the package from GitHub by running:

npm install --save rasa-webchat-josh
npm install --save react-event-observer

Then once it is installed it can be implemented as follows.

import React, { Component } from 'react';
import ReactObserver from 'react-event-observer';
import {
  Widget,
  BOT_MESSAGE_RECEIVED,
  CHAT_OPENED,
  CHAT_CLOSED
} from 'rasa-webchat-josh';

class CustomWidget extends Component {

  constructor(props){
    super(props);
    this.observer = ReactObserver();
    this.initializeListeners();
  }

  //Event listener
  initializeListeners(){
    this.msgAddListener = this.observer.subscribe(BOT_MESSAGE_RECEIVED,(data) =>{
      console.log("Message added **; size "+data);
    });
    this.chatOpened = this.observer.subscribe(CHAT_OPENED,(data) =>{
      console.log("Chat opened; isChatOpen "+data);
    });
    this.chatClosed = this.observer.subscribe(CHAT_CLOSED,(data) =>{
      console.log("Chat closed; isChatOpen "+data);
    });    
  }

  render(){
    return(
      <div>
      <Widget
        interval={2000}
        initPayload={"/get_started"}
        socketUrl={"http://localhost:5500"}
        socketPath={"/socket.io/"}
        title={"Title"}
        inputTextFieldHint={"Type a message..."}
        connectingText={"Waiting for server..."}
        embedded={true}
        openLauncherImage="myCustomOpenImage.png"
        closeLauncherImage="myCustomCloseImage.png"
        observer={this.observer}
        params={{
          images: {
            dims: {
              width: 300,
              height: 200
            }
          },
          storage: "local"
        }}
      />
      </div>
    )
  }
}
  • Make sure to have the prop embedded set to true if you don't want to see the launcher.

Backend

Rasa Core

Use the SocketIOInput channel: See instructions in the Rasa Core documentation

Others

Your backend must expose a socket with socket.io

Receiving messages from the chat
@socketio.on('user_uttered')
    def handle_message(message):
        # do something
Sending messages from the backend to the chat widget
sending plain text
emit('bot_uttered', {"text": "hello"}, room=session_id)
sending quick replies
message = {
  "text": "Happy?",
  "quick_replies":[
    {"title":"Yes", "payload":"/affirm"},
    {"title":"No", "payload":"/deny"}
  ]}
emit('bot_uttered', message, room=socket_id)
sending a link Snippet

Admittedly a bit far fetched, thinking that Snippets would evolve to carousels of generic templates :)

message = {
  "attachment":{
    "type":"template",
    "payload":{
      "template_type":"generic",
      "elements":[
        {
          "title":"Title",
          "buttons":[ {
            "title":"Link name",
            "url": "http://link.url"
          }
        ]
      }
    ]
  }
}
}
emit('bot_uttered', message, room=socket_id)
sending a Video Message
message = {
  "attachment":{
    "type":"video",
    "payload":{
      "title":"Link name",
      "src": "https://www.youtube.com/watch?v=f3EbDbm8XqY"
    }
  }
}
emit('bot_uttered', message, room=socket_id)
sending an Image Message
message = {
      "attachment":{
        "type":"image",
        "payload":{
          "title":"Link name",
          "src": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT_IX5FSDQLrwm9qvuXu_g7R9t_-3yBSycZ8OxpRXvMDaTAeBEW"
        }
      }
    }
emit('bot_uttered', message, room=socket_id)

Usage

Session Persistence

storage specifies the location where the the conversation and state of the WebChat is stored in the browser's storage.

storage: "session" defines the state to be stored in the session storage. The session storage persists on reload of the page, and is cleared after the browser or tab is closed, or when sessionStorage.clear()is called.

storage: "local" defines the state to be stored in the local stoage. The local storage persists after the the browser is closed, and is cleared when the cookies of the browser are cleared, or when localStorage.clear()is called.

API

| Method | Description | |-------------------------|--------------------------------------------------------------------------------------------------------------------| | WebChat.toggle() | Toggle the open/close state of the chat window, send initPayload if webchat is not initialized and is toggled open | | WebChat.open() | Open the chat window, send initPayload if webchat is not initialized | | WebChat.close() | Close the chat window | | WebChat.isOpen() | Get the open/closed state of the widget | | WebChat.show() | Show the chat widget, send initPayload if the chat is in open state and not initialized | | WebChat.hide() | Hide the chat widget | | WebChat.isVisible() | Get the shown/hidden state of the widget |

Styles

hierarchy:

.conversation-container
  |-- .header
        |-- .title
        |-- .close-function
        |-- .loading
  |-- .messages-container
        |-- .message
              |-- .client
              |-- .response
        |-- .replies
              |-- .reply
              |-- .response
        |-- .snippet
              |-- .snippet-title
              |-- .snippet-details
              |-- .link
        |-- .imageFrame
        |-- .videoFrame
  |-- .sender
        |-- .new-message
        |-- .send

| Class | Description | |-------------------------|---------------------------------------------------------------------| | .widget-container | The div containing the chatbox of the default version | | .widget-embedded | div of the embedded chatbox (using embedded prop) | | .full-screen | div of the fullscreen chatbox (using fullScreenMode prop) | | .conversation-container | the parent div containing the header, message-container and sender | | .messages-container | the central area where the messages appear | | .sender | div of the bottom area which prompts user input | | .new-message | the text input element of sender | | .send | the send icon element of sender | | .header | div of the top area with the chatbox header | | .title | the title element of the header | | .close-button | the close icon of the header | | .loading | the loading status element of the header | | .message | the boxes holding the messages of client and response | | .replies | the area that gives quick reply options | | .snippet | a component for describing links | | .imageFrame | a container for sending images | | .videoFrame | a container for sending video |

Usage with Docker

Since you have to install the package from GitHub, npm will clone the repo to the global .npm directory before building the module in your node_modules directory. For this reason docker will have trouble installing the package, of course the global .npm directory doesn't exist in the container. To solve this simply add the following line in your Dockerfile before the RUN npm install command

RUN mkdir -p /root/.npm

Contributors

@PHLF @znat @TheoTomalty @Hub4IT @dliuproduction