Rasa Node Action Server

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-serverQuickstart
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"}]