I have a dialogflow bot that helps a user order an item from a menu. I would like to spawn multiple instances of the bot, because when two people talk to the bot they are talking to the same instance, and the bot takes both of their inputs into account. What is the correct way of making separate instances for each user?
You can use different session Ids for different users.
Detect Intent Request with the session Id
This is generally a coding problem on your side - usually meaning you're using global variables instead of storing information that needs to be maintained over the session in Context parameters.
Related
I'm about to host a competition where you register via a bot in discord.
And I want to prevent users from submitting and then logging out and in again with a different account and submitting again. And doing that maybe 20 times to get a bigger chance to win.
If there is some way to detect that they are using the same device and make the following submissions invalid?
If not, if someone has a smart idea to prevent multiple submissions?
Discord.js does not have a way to track an specific device yet.
Something clever you could do, is to make the bot give your users a link to make them register via a website that stores a cookie to tell whether you have signed up already or not. You can also use Discord's OAuth2 to get the information from your signed up users to your database.
I am looking at developing a solution with Dialogflow, where the User Interface events (e.g. Typed user input) are going to arrive as http REST events.
The problem with this is that the Dialogflow Client API (Note: This is NOT THE SAME THING as the fulfilment API), looks like it is stateful: https://github.com/googleapis/nodejs-dialogflow
(... But I could be wrong on that...)
And stateful is hard in most (all?) modern serverless paradigms that any sane person is probably using. Mainly - There is no gaurantee that subsequent events will arrive at the same run-time instance.
It's a bit infuriating that although many examples are supplied at the repo above, none of them look like realistic (but small) applications, handling multi-session, multi-turn (even 2-3 turns) user input.
Is the idea that any run-time instance could/would call new dialogflow.SessionsClient(); just once PER RUNTIME initialisation (NOT per session) to initialise the API, and then everything else is done via like await sessionClient.detectIntent(request); ???
Now that I've typed this, I am pretty confident that is right. But if anyone could confirm it would be great!
The underlying Dialogflow Session API itself is stateless - any statefull decisions that are made must be included in your call to detectIntent. The JavaScript library reflects this stateless scenario as well.
The SessionsClient constructor sets up the connection and authentication information, but does not maintain any other conversational state. So you can use the same object to manage multiple conversations.
Note that this still means you need to maintain conversational state (the session id, the values and lifespans returned in contexts, etc) in order to pass it to detectIntent as part of the request.
I have the following intent and followup intents for a user login process:
How can I set a while loop for this login process in order to continue asking user email while user enters email address incorrectly and after he/she enters it correctly the getting password intent triggers?
In my cases after 2 incorrect entry, api.ai will response "Not Available".
Forcing users to respond to a question without giving them recourse to cancel, move to another part of your conversational interface or speak about another subject is user-hostile and I'd recommend doing exactly what Actions on Google forces you to do in this situation: end the conversation after a few failed attempts.
Conversational interfaces are best thought of as designing actual conversations. In a normal conversation asking the same question multiple times regardless of what someones says to you would largely be considered annoying at best. Consider revising your Dialogflow agent to allow logged-out conversations explaining to the user what your agent can offer and why login is required for certain features. If the user repeatedly asks for a feature that requires login but refuses to do so, the conversation should end.
Another note here: I'd recommend against using passwords through conversational interfaces. Most conversational platforms have a way to sign in (e.g. Google Assistant/Actions on Google) or you can safely assume the user is using a device where they have access to a web browser as well (Slack) and you can use a system like OAuth to properly authenticate users.
I am currently developing a strategy for Dialogflow on https://passportjs.org.
From what I've learnt, Dialogflow doesn't authenticate users. So I'm thinking about making a strategy (for passportjs) that identify users from every plateform differently (analyse the originalRequest differently for each plateform).
For example, the Telegram originalRequest has this field:
originalRequest.data.message.from.id
The Telegram says this field is a:
"Unique identifier for this user or bot"
So I think it is safe to use it for authentication and identify every intent of my users fulfilled by my webhook.
I was wondering about the actions-on-google authentication and I found the field originalRequest.data.user.userId.
The documentation says:
"Users can reset this identifier, so don't store important user data keyed off this identifier, because once it's reset, that information is no longer accessible by the user."
So the only reason to not trust the userId is because it can be reset? At the end of the documentation it says:
User ID lifetime - User IDs are reset automatically after 30 days of inactivity or if users unlink their accounts on the device.
And:
"If a registered user's voice isn't recognized by the device or no registered voice exists, then a different ID is used that is unique for just that conversation."
How to differentiate users from one other? Can some IDs be recycled?
The best way to differentiate users from each other is to use the userId field, as you've determined. On the AoG platform, the userId is meant to be used somewhat like a web cookie can be used - if you see it again, you are assured that this is the same user that used it last time. But if you see a new one, you have to assume that you've never seen this user before, even if it means they deleted the cookie.
To be clear - most of the time, the UserId will remain the same and you can expect returning users to have the same ID. This won't be true in only three cases:
They have reset the ID for this Action. So they have deliberately chosen to start over.
They didn't use the Action for 30 days, in which case it makes sense to treat them as a brand new user anyway in most cases.
They were not recognized as a normal user of this device, so they are treated anonymously. (This is the equivalent of the clunky "Do not remember me on this machine" setting you see on websites, which forces a session cookie rather than a persistent cookie.)
The phrasing is poor in the documentation - I think it is meant to remind developers that the user is ultimately in charge of their privacy. And Google both forces you to do the same and adopt policies that do so.
IDs will not be recycled. In fact, they won't even be re-used between different Actions, even for the same Assistant account.
Summary: If you see the same UserId, you can trust it is the same user you saw before. If you see a new one, assume they are a new user.
If you want a more robust way to identify users, you might consider using Account Linking which puts you in control of the identifying token. But that has significant additional overhead.
Be careful when using other authentication methods - Google limits how you're allowed to use them as part of an Action, and expressly forbids them in some cases. See the General Policies for details.
I have a Spotify app and want to persist basic settings per user between sessions. I see the User object has a username field, so it would be easy to do this using my own backend. My question is, is this allowed, without requiring the user to log in, agree to some TOS, etc? Every app I see that persists any data requires me to log in with Facebook.
Usernames are typically obfuscated out in the Spotify API, so they're not the best thing to use. However, the anonymous ID for the user is the same for a given user/app ID combo across multiple machines, so you could use that instead. This sort of thing is what we designed the anonymous ID for, so you're good to go on the ToS front.
I can't find anything that restricts you from load/storing data from your own servers and I've seen 'you'd have to use your own server' suggested in a number of questions.
Not sure why other apps would involve FB - probably to get more info from the user or promote their product.
You should use the User's URI instead of their username though. I would expect it be more stable than the username and less likely to be little Bobby Tables.