What is the purpose of session.endConversation() - botframework

I am developing a bot in node.js using the Microsoft Bot Framework. Once my user has completed their action with my bot; I am calling session.endConversation(). However, I am not sure really what this is doing. My assumption when calling this code would be that it would clear out session data; so if the user interacts with the bot again; they will essentially be starting over.
However, when I call endConversation(), the user data is still there:
session.endConversation("Thank you for your business!");
console.log("User Data:");
console.log(session.userData);
The documentation just says, "ends the conversation" but doesn't describe what in fact that means.
I guess my question is; what is this function doing and when you are finished with a conversation, what should the approach be to handle the users conversation data?

According to this post:
As a result, when a conversation or dialog has come to an end, it’s a best practice to explicitly call endConversation, endDialog, or endDialogWithResult. endConversation both clears the current dialog stack and resets all data stored in the session, except userData. Both endDialog and endDialogWithResult end the dialog, clear out dialogData, and control to previous dialog in the stack. Unlike endDialog, endDialogWithResult allows you to pass arguments into the previous dialog, which will be available in the second parameter of the first method in the waterfall (typically named results).

Related

Simple question about waiting on an AJAX call

I need a Javascript function that serves the purpose shown below. I simply want to wait on the response from the server.
console.log('Before getting the city name.');
zip_code = '60601';
city_name = function_that_slowly_gets_city_name_from_server(zip_code);
console.log(city_name);
console.log('After getting the city name.');
Output in console:
Before getting the city name.
Chicago
After getting the city name.
I do not want the answer ('Chicago') sent to the console in a callback function. I understand that async:false is now taboo with $.ajax(), but I still need for it to work as shown above. I cannot find posts that provide a consistent, straightforward answer.
FOLLOW UP:
I've found many answers on StackOverflow that say synchronous calls are evil. Yet, is there a way to do it anyway?
Based on your comment, your use-case is a quick method of disabling user-interaction while the AJAX call is occurring to ensure the user can't do anything bad (e.g. start a duplicate request/race condition or navigate to a different part of the app, etc.). So maybe locking the thread ain't such a bad idea then, especially for an internal app that doesn't need a ton of frills?
But Here's the Problem:
The user can continue to queue events even during a locked thread. That means that any actions the user takes while a synchronous request is occurring (such as submitting a form) will continue to line up in the background, and will then begin firing as soon as the initial request is finished. So the threat of your user double or triple clicking out of impatience (or even just accidentally) -- and as a result causing duplicate calls to the database -- is very real and likely (for reference, I can double click in ~120ms pretty easily).
The same thread is also responsible for things that might surprise you, such as certain browser-level hotkeys or even exiting the tab at all, meaning yes, you could actually significantly delay the user from closing the application, though that's not likely for a low-traffic database. However, it's certainly not impossible, and it's definitely not desirable, even for an application that doesn't need all the frills of a commercial product.
So What Should I Do as a Quick Solution Instead?:
Well if you still need a quick solution that can effectively freeze the entirety of your application in one go, then depending on your existing code, this shouldn't be too bad either.
Make the request async, as is the default and standard. But before that request fires, select all elements typically in charge of event handling, disable them with the "disabled" attribute, and then re-enable them in the callback. Something like this:
var userStuff = $("input, button, submit, form");
userStuff.prop("disabled", true);
$.ajax({
// other ajax request settings ...
// ...
// ...
complete: (data) => {
userStuff.prop("disabled", false);
}
});
The elements contained within userStuff are just common elements that typically have some event-handling to them. It's up to you to determine if those elements are sufficient for your application, or if your application is so large that such a query could itself have a performance impact. But assuming that checks out, this will prevent the user from interacting with/queueing anything until the request has finished.
I Don't Care. Give me the Sync:
Well in that case, why not just use async: false as mentioned in your OP? I'm somewhat speculating here, but I believe it's not just async: false that's deprecated, but all means of synchronous XMLHttpRequest (which I believe $.ajax still uses under the hood), and I don't think there's any other synchronous alternative to that. So anything you do with synchronous network in mind is going to be evil, but at least in Chrome 89.0, $.ajax({async: false}) still works for me.

WaterfallStep design vs. SOLID principales in Bot Framework v4

After moving over from Bot Framework v3 and studying the docs/samples, I'm still not understanding why the WaterfallStep dialog handling in v4 was implemented in such a way.
Why was it chosen to process the result of the previous step in the next step within a waterfall?
Given a waterfall with 3 Steps PromptName, PromptAge and PromptLocation, I see the following:
Method naming: Given the 2nd and 3rd prompt, method naming gets unclear. Naturally we would do AskForAge() or AskForLocation() but this is misleading due to the next point
SOLID Principals: Isn't "single responsibility principal" violated as we do two things in each step? Storing the previous response while asking for the next one in the same method, which ultimately leads in method names like AskForLocationAndStoreAge()
Code duplication: Due to the fact that each step assumes concrete input from its previous step, it can't be reused easily nor can order be changed. Even the simplest samples are hard to read.
I'm looking for some clarification on why the design was chosen this way or what I have missed in the concept.
This question seems largely opinion-based and therefore I don't know that it is appropriate for Stack Overflow. It turns out there is actually a good place to ask these kinds of questions, and it's the BotBuilder GitHub repo. I will attempt to answer it all the same.
Why was it chosen to process the result of the previous step in the next step within a waterfall?
This has to do with how bot conversations work. In its most basic form, without any dialogs or state or anything, a bot works by answering questions or otherwise responding to messages from the user. That is to say, a bot program's entire lifespan is to receive one message, process it, and provide a response while the message it received is still "active" in some sense. Then every following message the bot receives from the user is processed in the same way as though the first message was never received, like the message is being processed by an entirely new instance of the program with no memory of previous messages.
To make bot conversations feel more continuous, bot state and dialogs are needed. With dialogs and specifically prompt dialogs, the bot is now able to ask the user a question rather than just answer questions the user asked. In order to do this, the bot needs to store information about the conversation somewhere so that when the next message is received from the user the new "instance" of the bot program will know that the message from the user should be interpreted as a response to the question that the previous instance of the program asked. It's like leaving a note for someone working the next shift to let them know about something that happened during the previous shift that they need to follow up on.
Knowing all this, it seems only natural to process the result of the previous step in the next step within a waterfall because of the nature of conversations and dialogs. In a waterfall dialog containing prompts, the bot will receive messages pertaining to the last message the bot sent. So it needs to process the result of the previous step in the next step. It also needs to respond to the message, and in a waterfall that often means asking another question.
Isn't "single responsibility principal" violated as we do two things in each step? Storing the previous response while asking for the next one in the same method, which ultimately leads in method names like AskForLocationAndStoreAge()
As I understand it, the single responsibility principle refers to classes and not methods. If it does refer to methods, then that principle may well be violated or bent in some way in this case. However, it doesn't have to be. You are free to make multiple methods to handle each step, or even to make multiple steps to handle each message. If you wanted, your waterfall could contain a step that processes the result of the previous prompt and then continues on into the next step which makes a new prompt.
Due to the fact that each step assumes concrete input from its previous step, it can't be reused easily nor can order be changed. Even the simplest samples are hard to read.
You ultimately have control over how the input is validated/interpreted so it can be as concrete as you want. The reusability of a dialog or waterfall step has everything to do with how similar the different things you want to do are, the same as in any area of programming. If the samples are hard to read, I recommend raising issues with those samples. Of course, you can still raise an issue with the design of the SDK itself in the appropriate repo, but please do consider including suggestions for the way you think it should be instead.

Pre-fetching logic in Rx

I'm trying implement my own pre-fetching logic in rx.js. Here is example marble diagrams:
I've modeled the problem as follows: There is a stream of hints that lets my program know that a user might want to click a certain link. I want to immediately send a request, but only render the result if the user indeed clicks the link.
Based on this, there are (at least) 3 things that can happen by the time the user clicks the link:
The correct result already returned form the server.
The request is still in progress
(Special) There is no request -- finished or in progress -- because the user somehow didn't trigger a hint first.
Some extra requirements:
Only the latest hint should have a request in progress (i.e. cancel previous requests).
Once the user clicks on a link, new hints should not trigger a request until the result is rendered
New clicks should trigger new requests and cancel the previous request
I've actually found a solution, but it is convoluted, maybe incorrect, and mostly I'd just like to know if there is a better way of doing it (see below).
EDIT: Now implemented in hy-push-state.

Is it a good practice to call action within another action (in flux)

I have an action as follows:
SomeActions.doAction1(){
//..dispatch event "started"...
//...do some process....
FewActions.doAnotherAction(); //CAN WE DO THIS
//...do something more....
//..dispatch event "completed"..
}
While the above works with no problems, just wondering, if it is valid according to flux pattern/standard or is there a better way.
Also, I guess calling Actions from Stores are a bad idea. Correct me if I am wrong.
Yes, calling an Action within another Action is a bad practice. Actions should be atomic; all changes in the Stores should be in response to a single action. They should describe one thing that happened in the real world: the user clicked on a button, the server responded with data, the screen refreshed, etc.
Most people get confused by Actions when they are thinking about them as imperative instructions (first do A, then do B) instead of descriptions of what happened and the starting point for reactive processes.
This is why I recommend to people that they name their Action types in the past tense: BUTTON_CLICKED. This reminds the programmer of the fundamentally externally-driven, descriptive nature of Actions.
Actions are like a newspaper that gets delivered to all the stores, describing what happened.
Calling Actions from Stores is almost always the wrong thing to do. I can only think of one exception: when the Store responds to the first Action by starting up an asynchronous process. When the async process completes, you want to fire off a second Action. This is the case with a XHR call to the server. But the better way is to put the XHR handling code into a Utils module. The store can then respond to the first Action by calling a method in the Utils module, and then the Utils module has the code to call the second Action when the server response comes back.

asp.net mvc 3 - sending an email and getting the return for validation a task (registration, form validation...)

I am having a register form that user fill in, once the form fill in, the registration is postponed till the user recieve an email to check that his email is ok, then when he reply the email, the registration is fully proceed.
I would like also the process to be automatic, without the need for the user to entered any number ect, just the need for him to click on the email to confirm, and automatic on my side too.
I want the process to be available to some others task than the registration process as well if possible.
Do I need to do all way check/123456 with the 123456 generated or is there a better way to do, a component, nuget that can do the job ? you experiences return would be helpful
thanks
You appear to be on the right track.
I do a similar thing quite often. It isn't generic since I do not need it but you can change that quite easily.
Once a user registers I send an activation e-mail that contains a link that when clicked navigates to something such as http://domain/member/activate/id where the id is a GUID. That is all I need. I look up the member id and activate it. Chances of someone guessing a new member's id are rather slim and even if they do it is very far from a train smash.
From what I can tell you need something more generic and a bit more security. You could always create some key (like a new GUID) that you store along with the user and then the activation calls: http://domain/member/activate/id?key={the guid}. You could even encrypt the key. But that is up to you.
For something that can be re-used and is more generic you could create an activation component that contains a list of activation ids. But to then activate a specific type of entity (such as user registration or form validation) you would need to have a way to perform that on the back-end. For example, when you call http://domain/activation/activate/id internally is looks up the id and gets the type. The activation request is, of course, created when, e.g., your user registers. You would probably want to store some expiry/timeout since a user may never activate.
For each type you could have an activation mechanism on the relevant controller: member/activate/key or formvalidation/activate/key. So when you activation controller receives a request to activate it has a list of routes conigured per type and the navigates to the relevant route to perform the 'actual' activation.
Another option is to have an in-process component perform activation e.g.: an IActivator interface implemented by a MemberActivator or FormValdationActivator and then have an IActivatorProvider implementation that gives you the relevant provider based on a type (.NET Type or a string type you provider --- that's up to you).
You could even pass an ActivationRequestCommand along to a service bus endpoint if you are so inclined.
So you have many options. HTH
If you are a developer I suggest you at least try to start with the code... then ask again if you get stuck providing a sample of what you've done.
What you are looking to do is basically use a temporary url that posts to a page to complete the registration...

Resources