/rasa-node-action-server

NodeJS alternative to Rasa SDK Action Server

Primary LanguageJavaScriptMIT LicenseMIT

Rasa Node Action Server

npm version node dependencies

NodeJS alternative to Rasa SDK Action Server

Why

  • Allow people to write their own action server in JavaScript with NodeJS
  • Does not require the use of Rasa-SDK
  • Simple and not verbose action definition

Install

$ npm install rasa-node-action-server

Quickstart

To start a simple Action Server you can use the following quick start example.

// index.js
const { RasaNodeActionServer, RasaActionEvent } = require("./rasa-node-action-server");

const rnas = new RasaNodeActionServer();

rnas.define("action_hello_world", (action, res) => {
  res
    .addEvent(RasaActionEvent.bot("Hello world, from your action server"))
    .send();
});

rnas.start();

and run

node index.js

The RasaNodeActionServer by default will start an express server on localhost:5055. For more examples, check out the examples folder on Github.

Rasa Custom Connectors

If you want to pass additional parameters to your rasa action inside your request, you should use the metadata field as suggested in the rasa documentation.

Custom Connector Example

For a quick start, you can use the following custom connector which allows the metadata parameter to be forwarded to the server.

# custom_connector.py
import asyncio
import inspect
from sanic import Sanic, Blueprint, response
from sanic.request import Request
from sanic.response import HTTPResponse
from typing import Text, Dict, Any, Optional, Callable, Awaitable, NoReturn

import rasa.utils.endpoints
from rasa.core.channels.channel import (
    InputChannel,
    CollectingOutputChannel,
    UserMessage,
)
import logging

logger = logging.getLogger(__name__)


class RasaNodeChannel(InputChannel):
    """A simple web bot that listens on a url and responds."""

    @classmethod
    def name(self) -> Text:
        return "rnc"

    def blueprint(
        self, on_new_message: Callable[[UserMessage], Awaitable[None]]
    ) -> Blueprint:

        custom_webhook = Blueprint(
            "custom_webhook_{}".format(type(self).__name__),
            inspect.getmodule(self).__name__,
        )

        @custom_webhook.route("/", methods=["GET"])
        async def health(request: Request) -> HTTPResponse:
            return response.json({"status": "ok"})

        @custom_webhook.route("/webhook", methods=["POST"])
        async def receive(request: Request) -> HTTPResponse:
            sender_id = request.json.get("sender") # method to get sender_id
            text = request.json.get("message") # method to fetch text
            input_channel = self.name() # method to fetch input channel
            metadata = self.get_metadata(request) # method to get metadata

            collector = CollectingOutputChannel()

            # include exception handling

            await on_new_message(
                UserMessage(
                    text,
                    collector,
                    sender_id,
                    input_channel=input_channel,
                    metadata=metadata,
                )
            )

            return response.json(collector.messages)

        return custom_webhook

    def get_metadata(self, req) -> Text:
        return req.json.get("metadata") or self.name()

and define it inside the credentials.yml file like this:

rest:

custom_channel.RasaNodeChannel:

rasa:
  url: "http://localhost:5002/api"

You can then test your server by running:

curl -XPOST http://localhost:5005/webhooks/rnc/webhook \
  -H "Content-type: application/json" \
  -d '{"sender": "lykos94",  "message": "Hello bot", "metadata":{}}'

response:

[{"recipient_id":"lykos94","text":"Hello world, from your action server"}]

Methods Reference

RasaNodeActionServer

Constructor

Parameter Type Description Default
port number Optional.The port on which the Action Server will start 5055
port string Optional. The host on which the Action Server will start "localhost"

define(action_name, action_function)

Parameter Type Description Default
action_name string Required. The name of the action to trigger none
action_function function Required. The function to trigger. This function received 2 parameters: action and response none

start()

Function that registers all the action handlers and run the action server

RasaAction

getSender()

Function to retrieve the sender of the action request

getMetadata()

Function to retrieve the metadata of the action request

getDomain()

Function to retrieve the domain of the action request

RasaActionResponse

addEvent(event)

Parameter Type Description Default
event RasaActionEvent Required. A RasaActionEvent with the event type called as function none
// example
res.addEvent(RasaActionEvent.bot("Hello from bot"))

addResponse(response)

Parameter Type Description Default
response object Required. The object to add to a response none
// example
res.addResponse({ test:"Text of the response" })

getDomain()

Function to send the response back to the Rasa server

Maintainers