Dialogflow fulfillment with Please wait functionality - dialogflow-es

I am working on custom event integration which will call one by one three event as I am using third party API which is taking more then 11 sec, I need a functionality where user will receive message from first intent saying "Please wait", meanwhile our 2nd and 3rd intent will wait for the API response, as soon as we get the response from our API we will return it to Dialogflow Agent.
In the below code I want to send message(Please wait) from the Demo intent then the other two custom event will call intent(followOne, followUpTwo) this intent will be process for specific time, after that it will send one more message with actual API response.
async function Demo(agent){
// here we call our API and wait to get an response and will set that response in Redis server
await customsleep(1500);
agent.add('Please wait');
agent.setFollowupEvent('followUpOne');
}
async function followOne(agent){
await customsleep(4500);
agent.setFollowupEvent('followUpTwo');
}
async function followUpTwo(agent){
// in this intnet will get response from Redis server which we stored from intnet Demo, This response will return to the user
await customsleep(4700);
agent.add('here we go');
}
Is there anyway to implement this kind of functionality where we can send message(Please wait). Once we get the response from API we can return it to the Dialogflow Agent.

To my knowledge you can't send any message while following up an event. (it will be ignore)
If you want to provide a message you should :
Step 1 :
- call the third party api
- send a message with a quick reply : "Please Wait" + qr: "Click here to display the answer"
Step 2 :
- check if the third party api has answered
- yes : return the answer
- no : follow up a waiting event

Related

Asynchronous response to Task module fetch

I'm wondering if there is a way to asynchronously respond to MS Teams Task module fetch events. By asynchronous I mean that we would lose the original context of the request because we sent the original request to another service. So one service to receive the requests and another to actually process the events.
I tried to build a new context using TurnContext.getConversationReference along with TurnContext.SendActivity. While this successfully sent the "continue" task module body using the original turnContext, it didn't work using the new context that I created with conversation reference.
// Service A - simply ack the request and formats and enqueues the request to a queue
const conversationReference = TurnContext.getConversationReference(context.activity);
// send this conversationReference as part of the payload to another service
// Service B - dequeues from the queue and processes the request
await botFrameworkAdapter.continueConversation(conversationReference, async (newContext) => {
const response = await newContext.sendActivity({
type: "invokeResponse",
value: { status: 200, body: taskCardResponse },
});
});
Task module is being launched through when a user clicks on a messaging extension. When this is launched, messaging extension task fetch is triggered. The backend then returns a form in task module for the user to fill out and submit.
This is the original implementation and in the new approach, we can't simply return the form to the modal because we don't have access to the original request in the service B.
Diagram of Current vs Future interaction between services
Per the discussion in comments above, the code in the bot to launch the message extension can simply pass via querystring anything that is needed to actual web content page that is launched, and it can do whatever is necessary with what it receives.

How step.prompt(OAUTH_PROMPT) move automatically to next function in waterfall dialog in botbuilder version 4 in node js?

Currently, I am using the OAuthPrompt in Microsfot BotBuilder V4 NodeJs SDK. The OAuthPrompt is mainly used for bot authentication with Azure, but after logging in to azure through the bot, I am not able to move to next function in the waterfall dialog until I send another message to the bot. If I send a message after login, then continueDialog() is called, so next function in waterfall dialog is invoked.
How do I automatically move to the next function in the waterfall dialog without sending another message to bot?
/**
* Waterfall step that prompts the user to login if they have not already or their token has expired.
* #param {WaterfallStepContext} step
*/
async oauthPrompt(step: any) {
await step.prompt(OAUTH_PROMPT);
}
/**
* Waterfall step that informs the user that they are logged in and asks
* the user if they would like to see their token via a prompt
* #param {WaterfallStepContext} step
*/
async loginResults(step: any) {
let tokenResponse = step.result;
if (tokenResponse != null) {
await step.context.sendActivity('You are now logged in.');
return await step.prompt(CONFIRM_PROMPT, 'Do you want to view your token?', ['yes', 'no']);
}
// Something went wrong, inform the user they were not logged in
await step.context.sendActivity('Login was not sucessful please try again');
return await step.endDialog();
}
After the oauthPrompt() is called, the login card is displayed in bot. But after that loginResults() function is not automatically invoked until I send another message. Both functions are in same waterfall dialog?
Can anyone tell me how to call loginResults without sending another message to the bot, please?
This is actually normal (and expected) behavior for the emulator. There is a lot that goes into the 'why' that I won't touch.
In short, tho, the emulator is looking for a specific kind of callback that it won't ever receive because of how emulator works with respect to OAuth. Because it never receives this callback the login step doesn't know to advance to the next step and, subsequently, waits for something to prompt it (i.e. user input).
This is only a "problem" in emulator. When you run this in other channels it shouldn't be an issue.
Hope of help!

Using an Azure Web Function to receive a Twilio SMS Message

I'm trying to get an Azure Web Function to receive a Twilio SMS message - and failing!
I've created a Web Function to successfully send SMS messages - now I want to listen and react to responses.
I've set up a web function as per the below. Its pretty simple at the moment, and is supposed to parrot back the original message:
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
var data = await req.Content.ReadAsStringAsync();
var formValues = data.Split('&')
.Select(value => value.Split('='))
.ToDictionary(pair => Uri.UnescapeDataString(pair[0]).Replace("+", " "),
pair => Uri.UnescapeDataString(pair[1]).Replace("+", " "));
// Perform calculations, API lookups, etc. here
var response = new MessagingResponse()
.Message($"You said: {formValues["Body"]}");
var twiml = response.ToString();
twiml = twiml.Replace("utf-16", "utf-8");
return new HttpResponseMessage
{
Content = new StringContent(twiml, Encoding.UTF8, "application/xml")
};
}
In Twilio, I've configured the phone to use web hooks:
I've deployed the Web Function, however when I try testing by sending a message, I get the following error in the Twilio logs:
11200 There was a failure attempting to retrieve the contents of this URL
Msg Unsupported Media Type
Message: The WebHook request must contain an entity body formatted as JSON.
Does anyone have any experience in how to fix this error?
I just got this working with Twilio's SMS services. In the Azure Portal, if you go to the function, then go to Integrate, change the mode to Standard. This forces the Azure function to return a normal HTTP response and you can control the content type. If you use application/xml it will work fine.
Okay, the current solution to this is .... it can't be done in Azure Web Functions. An Azure Web Function expects a JSON payload. Twilio Webhooks are an XML value/pair. So, the web function will reject the webhook call.
The best/easiest approach is to use a WebAPI or MVC Controller as per the Twilio example. I tried a sample version and had my Twilio Webhooks working to reply to an SMS in about 15 minutes from start to finish.
To debug, I'd use a tool such as Postman or Fiddler to manually replay (or create from scratch) an identical request to what you're expecting from Twilio. You can then see what kind of response you get and not have to solely rely on Twilio's error message.
From the error code, I'd imagine that the problem is either:
Your URL set up in the Twilio number configuration isn't actually reaching your function.
Your function is taking too long to respond. Twilio will throw 11200 if it doesn't get a response in a certain time.
Your response is formatted incorrectly. This is where the aforementioned strategy can help you diagnose the issue.

Twilio Functions - post data from multiple sms messages?

I have a function that posts the content from an incoming sms message to a third party api. So, a customer sends us a message and Twilio posts the message to the api. But, I want to add an extra step. So, when a user sends us a message, I want Twilio to reply asking for an email then post the message along with the email from the second message to the api. Unless we get that second message, nothing should be posted to the api. Any ideas on how to do something like that?
I was looking through the docs and saw something about the Message instance resource but I'm not sure if that will do it.
const https = require('https');
exports.handler = function(context, event, callback) {
let twiml = new Twilio.twiml.MessagingResponse();
twiml.message("Your message has been recieved.");
let postData = JSON.stringify({
....
});
let postOptions = {
...
};
let req = https.request(postOptions, function(res) {
res.setEncoding('utf8');
res.on('data', function(chunk) {
console.log(chunk);
callback(null, twiml);
});
});
req.write(postData);
req.end();
};
Twilio developer evangelist here.
In order to take two steps like that, you'd need to save the message from the first message somewhere while you wait for the second message. Since the second message will come in via a new HTTP request, you can't save this within a function anywhere, you'd want to use some sort of third party store. Then you'd write your function to check for the existence of the first message in that store, if it exists, then send both messages to the API, if it doesn't then store the first message and respond to the user with your second question.
Alternatively, you could use the Twilio API to look up all the previous messages that the user has sent to you. If there are no previous messages, then this is definitely the first message they have sent. If there is a previous message then you need to determine whether it was an initiating message for this conversation, possibly by how long ago it was or a heuristic on the content, and then decide whether to send both the messages on to your API or ask for the next response.
Let me know if that helps at all.

Twilio Client Making a Call status

I am writing a node.js application to make a call or send sms to users.
However, after making a call or sending SMS, I wish to know its status.
client.makeCall({
to:'+358xxxxxxxxx',
from: '+15005550006',
url: "https://demo.twilio.com/welcome/voice/",
}, function(err, responseData) {
}
I know on responseData, but its status indicates 'Queued'
I wish to know the real call status after the actual call takes place.
Is there anyway to do so?
I haven't used twilio node.js client, but here's some that might help you -
You are not getting the call status because the voice call or SMS wont complete immediately when the API call is returned. You need to make subsequent requests again until the status is complete (polling) or configure twilio/pass parameters so that twilio will notify you when the call is actually complete (push).
To let twilio push the status to your server, pass application_sid or status_callback field while making the call request as explained in the API doc http://www.twilio.com/docs/api/rest/making-calls.
To manually request the call status, do the get request from the client after few seconds (or whatever time you think call takes to complete) perhaps using a timer until you get the status you want. http://www.twilio.com/docs/api/rest/call
Something like below: (Note: I have not tested or verified this)
client.calls(<sid>).get(function(err, call) {
console.log(call.status);
});

Resources