Watson Assistant API v2 & session expiration - ibm-cloud

We're building an app that uses the API v2 to interact with Watson Assistant. We're aware that the "state" of the conversation (among others: the position in the dialog tree) is now kept on the service side using the session_id key.
The problem: the session expires (5 to 60 minutes depending on the pricing plan).
Is there a way to either resurrect an expired session or save the conversation state so that it can be restored ?
We've tried to save and restore the global & skills contexts but they don't hold the conversation state.
Thanks for your help.

The current inactivity timeout period is plan-specific
- lite and standard 5 minutes
- plus and premium 1 hour
In the coming days, you will be able to change that value for plus and premium up to 24 hours. Lite and Standard you will only be able to decrease to a lower value if you want to close sessions faster.
You can always save context at the application level but currently there is not a way under the V2 API to save where the user is in the dialog so that you can pass it back after exceeding the allowed session inactivity timeout period.

Complementing what #oscar.ny mentioned, it's also plan-specific and you could potentially change the timeout timing on the Settings -> Timeout limit field -> Change the value and close, it saves automatically.
Something that I've done before in the past was sending an empty message when the event of 5min inactive happened. This event would call the function that would hit the API message method to send an "Are you still here, I was talking about xyz". Where xyz was the latest message sent to the user to maintain the session.
Ref:
change Timeout limit

Related

GA4 Measurement Protocol returns events not the users

We've set Google Analytics GA4 event transfer via Measurement Protocol. We followed documentation fully - https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag
Everything was fine in test GA counter, but after moving on production counter events stopped getting into interface (though keep being sent to connected Google BigQuery).
To be clear, we can see that events are counted, but not users.
0 for users, 25 for events
We changed only API secret and Measurement ID in our configuration. The major difference between test and prod counters: production is linked to Google AdWords and GoogleBigQuery.
Would be very grateful for any ideas and insights in that case.
I have same problem. You need to set engagement_time_msec parameter.
For example:
"engagement_time_msec": "1"
More: https://support.google.com/analytics/thread/117981433/events-sent-from-measurement-protocol-do-not-set-active-users?hl=en
The Measurement Protocol V4 is for GA4 properties(which is also the
one you are using).
According to the official document:
https://support.google.com/analytics/answer/9408920 It says "Google
Analytics 4 properties counts users who engaged with your app/site for
any non-zero amount of time during the previous 30 minutes".
GA4 uses "engagement_time_msec" parameter to identify user interaction
time. This explains why you can see the number of events but not the
number of users. If you want users sent from MP to be counted as
active user, simply add the "engagement_time_msec" parameter to your
event.
I think this is "by design". Even this screenshot in the official docs shows Users in last 30 minutes: 0 https://developers.google.com/analytics/devguides/collection/protocol/ga4/verify-implementation?client_type=gtag#realtime
As far as I can tell it's not possible to enable Session Hits Count for events triggered via the new measurement protocol (or whatever is necessary to get active users/sessions).
It might be possible to find a workaround for this issue:
using Tag Manager
using the undocumented url format (https://www.thyngster.com/app-web-google-analytics-measurement-protocol-version-2)

How to disable login after multiple failed attempts in Flutter

I have built a flutter app where user is created at backend WEB, in App users can only Login.
What I want to do is if the user attempts multiple failed attempt to login assume for 3 times, I want Login to get disabled for 5 minutes to the user.
help me how to approach it and the best suitable solution.
1.) Create a variable (global variable/ provider) "failed attempts".
2.) On failed attempt increase value =+ 1.
-> When user typed the correct password, delete the current count.
3.) When user failed 3 times -> save CurrentTime in the preference.
4.) Check it before attempting to login again.
-> Current time < (5 Minutes) compared to saved time
-> show popup "Sorry, you have to wait 5 minutes".
As nvoigt pointed out, you can/should store the variables in the backend, to increase security.
I would suggest using storage to store the DateTime of the last failed attempt after N number of failed attempts & checking if current time has passed X days or Y Hours or Z minutes and so on...
Note:
While I am suggesting using the storage for this, it is just out of convinience for you to implement & get going. It is not reliable as the user can change device's date & time settings or can reset/clear storage data.
In case if you are looking for a more secure approach with the same technique use something like firebase DB & Internet time instead of local storage & device time.
What I want to do is if the user attempts multiple failed attempt to login assume for 3 times, I want Login to get disabled for 5 minutes to the user.
This logic must be placed in the backend. When you call the login method on the backend, the backend has to keep track of how many unsuccessful tries there were and then lock the account for a specified time. Make sure you send a specific error code about the account being locked for the period to the frontend, so the frontend can display it and notify the user that trying to login is pointless.
There is no need to block the frontend from trying though. A malicious attacker will work around your protection anyway and a normal user may have reasons to try again (maybe with a different account).
You can use Timer class (link) and set needed delay to it. Block button at incorrect login action and after time runs out set it available again.

Is there a maximum length or amount of time that a user can respond for (in response to an Action on Google intent)

I see there is a limit that a user has to respond by before the conversation ends:
"Your response must occur within about 5 seconds or the Assistant assumes your fulfillment has timed out and ends your conversation."
How long does it take for the app to time out and exit the conversation
But is there a maximum that a user can respond for (type voice)? We want to allow for longer responses (and then access the response text).
Ideally we would like an unlimited response time and the ability to access the raw input (type voice) when received
It would be excellent if we could access the audio from the user's response, but as I understand that is not possible.
As I explained here, you can't have access to the raw audio recordings of interactions with your actions as of now. You only get access to the transcription of the user's utterance.
The quote you've supplied:
"Your response must occur within about 5 seconds or the Assistant assumes your fulfillment has timed out and ends your conversation."
isn't about the user's response. Your webhook fulfillment must complete in 5 seconds, otherwise, your system persona will time out.
As far as the length of users prompt goes; if the user doesn't say anything it will trigger a no-input prompt (on smart speakers) or just close the mic (on smartphones) in around 8 seconds. (I don't know if there's an official resource that proves 8 seconds, this is just my experience)
But once the user starts speaking, it will keep listening until the user stops talking. So you can theoretically have a long prompt from the user. However, I wouldn't recommend this since it would be a terrible user experience if you look at it from a conversation design stand point.

How do I constantly check if something on a server (Parse) has changed without thousands of requests?

I am creating an application which has a follow mechanism where the followed user has to accept the request of a following (similar to private accounts on instagram).
I then want the following user to find out when the other user has checked a million times (every time the following user opens the screen if I did the query in viewDidLoad). However, the problem with this, is that there will be a lot requests which will expensive to me as I will have to pay for the requests to Parse so I want to minimise these queries.
Currently, the best thing I can think of is to check once a day at midnight for example but this doesn't seem very seamless.
Is there a better way of doing this?
For starters consider how stale you are willing to allow an app's view of the world to be and cache the response that long. If a user views that screen every 30 seconds you might only want to actually check with the server 5 minutes after the last successful response (or the last response which had 0 follow requests).
You might consider switching from this sort of "pull" polling where the client decides when to ask the server if anything has changed to a "push" model where the server can inform the client when a change occurs. For example you can send a silent background push notification to a user's devices when they have a follow request, the app can then respond by performing your existing query.
You might still want polling or user triggered requests (like a "pull to refresh" gesture) as a fallback for missed notifications or devices with notifications disabled but you should be able to drastically reduce request volume.

How to track user online status?

I would like to capture the following parameters:
lastAccessedTime - The time when the user visited the site the last time (usually shown during the login process)
isOnline - A boolean to represent if a user is online or not.
a. Would it make sense to have these variables as part of the User table itself or should this be handled via a separate user audit table?
b. If certain SOAP / REST API's expose the functionality via API calls, how do you track the above parameters (e.g. Would you modify the lastAccessedTime in such cases - this might confuse the user if he logs into the portal, isOnline bit also will not make sense if the user does API calls).
I would create a session table that links back to the user. Instead of an isOnline field, I would just run a query for sessions that have been active within the last x amount of time. I would also update that session field with each request, even if that request is coming through an API.
This does create some overhead in pruning the session table, but you also don't clutter up your user table with non-user information, which can't be pruned.
Make the lastTimeActive a field in the user table, and update it with each page access. Your "Users Online" list is all users whose lastTimeActive is within 5 minutes.
I would create another table (userid, lastTimeActive), and frequently update & check the table.
// update
update onlineusers set lastTimeActive = getdate() where userid=1234
// check
delete from onlineusers where lastTimeActive < dateadd(minute,-5,getdate())
The biggest problem with tracking user presence (onine/offline) over HTTP is how to determine when the user has gone offline.
It's easy to determine when the user has come online - the mere presence of an authenticated request assumes that the user is active. However, since HTTP is stateless, the lack of a subsequent request can mean either that the user is gone offline, or that the user is online, but just hasn't done anything specific with your app recently.
Thus the best guess you can make is to have a timeout and if the user has not made a request during that timeout, to switch to offline state.
The simplest implementation would be to have a lastTimeActive, as Jonathan Sampson suggested. However, this won't give you the length of the user session, only an approximation of who's online at this moment.
More complex approach would be to have lastTimeActive and lastTimeLoggedIn. LastTimeLoggedIn is set at the time of first auth request that is more than 5 minutes from a previous auth request. A user is considered online, if there was an authenticated request in the last five minutes. The session length for the user is the time difference between lastTimeActive and lastTimeLoggedIn.
If your app also offers the choice of logging out to the user, you chouls consider that action also as going offline. However, unless your app is a banking app, chances are the users will just close their browser.
Also, avoid any background threads for updating the offline/online status of your users. You should be running the logic above only when there's an explicit request about the status of particular user and you should be updating only the users you were asked for.