What is the function of on_new_message and how is it callable in Rasa?
I was trying to create an output channel and found on_new_message function. I am able to create the channel but still wondering what is it doing in Background.
If you want to create an OutputChannel there is no on_new_message function.
The on_new_message function is a callback which gets passed to your InputChannel. You use it to pass the received message to Rasa Core after you have parsed it. A typical workflow might be:
Start Rasa Core which sets your custom InputChannel up.
A user writes a message within an app (e.g. Slack, Telegram)
The app (e.g. Slack, Telegram) forwards this message by calling the endpoint of your InputChannel
You parse the message
You pass the content of the message to Rasa Core by calling on_new_message
You either return the bots answer directly (see RestInput as an example) or you use a separate OutputChannel for that (see class SlackBot for an example)
The documentation of Rasa Core has also a section on how to create custom channels: Creating a new Channel
Related
I am using an exteranl API that do some work for 15min, when it finish it will call any URL you define in your initial request to send the results to.
Is it possible for dialogFlow to accept this result in 15min? Is there like a built-in async response handler in DialogFlow?
If you are calling external APIs via webhook, it would be subject to the maximum webhook timeout limit of 30 seconds. After the response timeout is exceeded, Dialogflow invokes a webhook error or timeout built-in event and continues processing as usual. Therefore, Dialogflow would no longer accept webhook responses more than the set timeout limit.
Note that conversational interfaces are meant to be designed as a continuous message exchange between the end user and the app/bot. If your web service requires more time for executing operations in the background and this cannot be optimized, consider redesigning the conversation flow in such a way that end users don't wait for the app/bot to reply for more than the set webhook timeout limit.
If you have your own custom application (integrated using APIs or Client Libraries), you can instead call/invoke the function that needs 15 minutes of work (let’s call this function_1) from your custom application.
Here’s a basic setup:
User enters a query from the interface of your custom application.
Your custom application sends the user query with the Detect Intent
request to the Dialogflow agent (using APIs or Client Libraries).
After your custom application receives a Detect Intent response from
the agent, you can create code to get the intent name or event name
from the detectIntentResponse.queryResult.match.intent.displayName
or match.event response json respectively and then call/invoke
function_1 based on the intent or event matched.
Once function_1 is finished processing, you can either send a direct response to the
user in your custom application’s interface or send a Detect Intent
request to your agent so it matches an Intent and sends the intent
response back to your custom application.
No, it won't be possible as you describe it. The only way to call external services is through webhooks, but these are thought as calls that return a very specific object which Dialogflow then returns as an answer to the user directly, so they are inherently synchronous.
What you could do instead is think of a workaround. I don't know the specific of what service you're calling, but you could set up a small server to handle the webhook response from dialogflow which doesn't do anything except trigger the call to the external api, and when you get the answer you could process it (put the relevant content inside a "fulfilment" object as per Dialogflow specification) and trigger an event in your agent through the dialogflow API.
so the final process could look something like this.
user asks for e.g. "pizza": the right intent is triggered and the route for that intent calls a webhook server
your webhook server receives the call from dialogflow and calls the external api asking for the list of all pizzas ever created. it returns an empty fulfilment to the server
when the webhook server receives the response after 15 mins it triggers an event in the agent (look into the dialogflow api for your programming language of choice: python, node, java) and injects some parameters in the request, which you can then use to form a sentence in the agent
when I was just starting out I found this very useful to get a grasp of what the platform expects you to do in terms of interacting with external services, take a look at the graph especially which I think makes it clearer
I am struggling with a problem that I have to integrate sending message to Skype users in daily. I've tried using API (https://rasa.com/docs/rasa/pages/http-api#operation/executeConversationAction) to run action and trigger intent but it didn't work. I think the problem here is botframework is not supported output channel because it worked on Telegram.
This is the result when output channel is botframework but it doesn't appear when I set it by telegram
How can I do this task? Thanks.
I believe that the botframework channel is not supported because it doesn't implement a get_output_channel method, which is used for the intent injection.
However, I'm not sure why that is the case, as I'm not familiar with the channel. It would be dependent on the type of communication connection, i.e. if in botframework Rasa is able to send messages to the channel without having received one first. In the channel code, sending a message looks like a POST request, so I would assume that is the case.
I think you could open an enhancement request in the Rasa repo for this.
I've been using Redis's Pub/Sub a bit in my application and so far it has been great. I am able to send out a Publish out of Laravel to a different backend process that is able to Subscribe, and eventually Publish an event back to Laravel.
The use case for the user looks like:
submit a form -> wait for a response (a few minutes) -> proceed with transaction
On the backend:
the form posts to a route, then to a controller that publishes this to a subscribed 3rd party (channel one), and eventually that 3rd party publishes back (channel two)
Main Issue: I don't know where the appropriate place to be for subscribing to the (channel two) and processing what gets published there.
Ideally, I'd be able to process Publish requests in two ways:
Letting the user know that their form has been processed and they can move onto the next step (probably with an update to a property a Vue component)
Storing information from the publish into my database.
In the docs, they have it in a Command, which if I try to use here would look like so:
public function handle()
{
Redis::subscribe('channel-two', function ($message) {
// update the client so that the user moves on
// send $message contents to the database
});
}
but that doesn't really seem ideal for me since I want this channel subscribed to 24/7, always listening. Even if it is in a Command, it is still apparent how I would best update the client.
Where in my Laravel project should I be subscribing at? Is there a best practice to respond to these events?
Redis::subscribe is used in a command like in that example for listening on a given channel continuously.
From the docs:
First, let's setup a channel listener using the subscribe method. We'll place this method call within an Artisan command since calling the subscribe method begins a long-running process:
You'll want to run the command using a process manager like supervisor or pm2, much the same as the docs describe running queue listeners.
I would like to create a command on slack that after being invoked returns result to the issuer and also writes another message to specific channel.
Is this possible?
In the docs I've found that I can set in_channel property but I would like to specify response being sent to specific channel or even limit command invocation to specific channel.
Yes, you can achieve that with a standard slash commmand. The slash command triggers your app which can then return the results to the user and also send a message to another channel with chat.postMessage (provided your all has the necessary permissions).
Limiting the slash command invocation to specific channels is possible, but only works for public channels, because Slack will tell your app the name if the public channel it was invoked in, but not the name of a private channel.
For public channels your app will get the channel ID from where the slash command was invoked with every request. Your app can use that information to decide whether the command is permitted or not and respond accordingly.
For private channels you only get privategroup as channel name, but not the real name or group ID. You can of course use this info to exclude usage of the command in all private channels, but not for specific ones.
Here is an example of the request your app gets from Slack:
token=gIkuvaNzQIHg97ATvDxqgjtO
team_id=T0001
team_domain=example
enterprise_id=E0001
enterprise_name=Globular%20Construct%20Inc
channel_id=C2147483705
channel_name=test
user_id=U2147483697
user_name=Steve
command=/weather
text=94070
response_url=https://hooks.slack.com/commands/1234/5678
trigger_id=13345224609.738474920.8088930838d88f008e0
I am creating a bot using MS Bot framework - NodeJs. The below information needs to be captured for logging (Using the bot.use method i.e. IMiddleware).
Receive:
a. UserId
b. UserInput (text)
c. ConversationId
Send:
1. Name of Intent or dialog name that handled this (that handled the user input text)
2. Bot output text
3. ConversationId
4. UserId
I am unable to get the required detail for the 'send'. Can anyone provide me some suggestions on this.
Thanks.
I believe your main struggle is to log the name of intent or dialog. You won't know it in your send middleware if you haven't captured it during the routing phase. Once the Bot Framework figured out where to send the incoming message, it just invokes that function.
These two articles may help you get what you want. Just recently I played with capturing the conversation's breadcrumbs and also logging a full transcript:
http://www.pveller.com/smarter-conversations-part-3-breadcrumbs/
http://www.pveller.com/smarter-conversations-part-4-transcript/
If you need to build a reliable capture engine, I would suggest that you didn't use the session.privateConversationData like I did and instead built your own storage/log infrastructure to push the events to. Just stream them out with a timestamp and conversationId and reconcile on the other end later. The asynchronous nature of everything the bot framework does internally will be haunting you along the way so that's why. Plus, once you scale out beyond testing on a few users and your bot spans multiple processes, you will be out of the single-threaded event loop.