How to load previous chat history once page is reloaded while using azure bot framework directline web chat - chatbot

Is it possible to load previous conversation with the bot in web chat using microsoft's azure bot framework?
For example: If the user has a conversation with the bot which has 15 messages in total and then the user decides to refresh the page. Can the chatbot automatically load the previous 15 messages of the transcript while maintaining the state.
Currently, I'm trying to save the conversation id as a cookie and load that value of the cookie on to the chat. So every time the directline session loads, I pass the conversationId as well as watermark parameter.
window.WebChat.renderWebChat(
{
directLine: window.WebChat.createDirectLine({
secret: '{{DLToken}}',
webSockets: true,
conversationId: chatId,
watermark: "0"
}),
styleSet,
store,
renderMarkdown: markdownIt.render.bind(markdownIt),
},
document.getElementById('webchat')
);
For this I'm getting a 403 error:
{code: "BadArgument", message: "Security token not valid for this conversation"}

Related

Discuss - How to make an application registration and OTP generation/verify service to be RESTful

We are developing a portal application where an already existing customer can register their account to see the details of their account (something like you have a credit card and then you register on Bank's portal to see the transactions details - here you are already a customer of the Bank). So when a user is coming very first time for registration then this whole registration flow is not authenticated (as user still doesn't have a username and Password- one will have this after the registration)
We also want that a customer can not have concurrent registrations i.e. if a customer opens multiple tabs (or uses Postman to call our registration API) then only one request should be allowed to register and all other be rejected. For this we have used a registration_session.
So when the first request comes, we find the customer from our master record and generates a GUID/UUID and save it as a registeration_session value against CustomerId as key in Redis (with set expiration). So if any other registration request comes for the same customer then we first search the Redis to see if there is a registeration_session value against the CusrtomerId, and if it exists we will reject this request saying that registration is already in progress.
Now my first question is this: is this behavior is Stateless or not for RESTful APIs? as I am kind of maintaining a request context via registration_session on the server. One may argue that I am not maintaining the application state, true; but if we see it like this: every other registration request has to check the status of any previous registration request - then this means we are no longer having statelessness as per REST principles as now two requests for registrations are no longer independent of each other.
Next requirement is of OTP generation and verify. During registration, we ask the user to identify oneself via an OTP sent to their mobile number (we already have their mobile number from their customer record). A user may request to resend a token multiple times but if use provides wrong input for 3 times, we will put the user's account in locked status. Also we want that once user has verified the OTP check successfully, then any other OTP generation request for the same registration session should not be allowed - as once OTP is verified successfully then to generate OTP again is futile operation (a malicious user may still want to do this via Postman/curl)
Now server has to maintain following information for OTP:
retry count for OTP verification, as the moment it reaches 3, account is to be locked.
verification status for OTP i.e. once it is verified, other request to generate the OTP for same registration session is not allowed
and my second question is this: Is it again violates the REST stateless principal, as it seems we are maintaining the context for requests and every request is dependent on the context of the previous request?
Or is there a gap in my understanding of application state and stored context and above mentioned scenarios do not break Restfulness of an API? OR we can not design Restful APIs for the above mentioned requirements?
Note: I have read enough questions on REST and Context state on SO, but none offered a solution that eliminates my confusion for the specific scenarios that I have asked.

Facebook graph API, Assign system user to a page

We have Page-Access-Token with all the permissions available (just for testing purposes), we also have a Business System User token and this is the steps we are trying to do
1: We connect our business to the facebook page as an agency using this api call
/me/agencies?access_token=${PAGE_ACCESS_TOKEN}&business=${BUSINESS_ID}&permitted_tasks=['ADVERTISE']
we will become partners with the page successfully.
2: we try to assign our business System user to the page that we just connected our business to using this api call
/me/assigned_users?business=${BUSINESS_ID}&user=${SYSTEM_USER_ID}&access_token=${PAGE_ACCESS_TOKEN}
but this request will fails and we get this response
error: {
message: 'Invalid parameter',
type: 'OAuthException',
code: 100,
error_subcode: 1752100,
is_transient: false,
error_user_title: '‎User is not Business Scoped‎',
error_user_msg: '‎The user ID provided is not business scoped. Please provide a business or a system user ID‎',
fbtrace_id: 'AMSzq06ES6nymFDFD31JWAk'
}
we know that it's possible for the System User to be assigned to the page because you can do that in the businees.facebook.com but we want to do it using graph api
Things we confirmed
The System User ID and Business ID are both correct
The Business is already connected to the page as we mentioned in the step 1, and we confirmed that by looking at Page Roles from the page settings we saw our page as an agency for the page
Things we saw that were interesting
if the page owner have role in the business the second api call would end up successfully and the system user will be assigned to the page
So, How can we assign our system user to the pages that connect to our business
Found a workaround, I created a Business Asset Group, added the system user to this group in the business.facebook.com then through Graph Api I could add the page to this group and the system user now have control over the page just like how I want it.

Watson assistant api calls details

We have developed a watson assistant chatbot and integrated with client application. Now we want know how many times each user calling watson service from client application and its billing details per person.
I have enabled the user metrics option using below approach and Active users graph is updated with user count.
But I want to know the per user api calls details, I have checked in viewLogs(IMPROVE TAB) and Usage tab in billing section and its not showing the per user api calls and billing details.
Please let me know where i can get the details of each user api calls details.
https://console.bluemix.net/docs/services/conversation/logs.html#user_id
"context" : {
"metadata" : {
"user_id": "{UserID}"
}
}
There is no UI to show chats from a specific user. Instead, as described here you must use the REST API via curl to retrieve logs.
However when using user_id you cannot filter for a specific user. I have tried actually doing this but I am not able to retrieve logs for a specific user_id.
You can retrieve logs filtered for a customer_id and therefore I recommend you set both user_id and customer_id to the same value, and filter using customer_id.
To set customer_id do as the SDK docs say and add a 'headers' object to the payload sent to Assistant with X-Watson-Metadata with value customer_id. For example in NodeJS:
payload.headers = {'X-Watson-Metadata': `customer_id=CUSTOMER_ID`}
assistant.message(payload, (err, data) => {
Then you can retrieve logs for a specific customer from Assistant by filtering by customer_id:
curl -X GET -u "apikey:KEY" 'https://gateway.watsonplatform.net/assistant/api/v1/workspaces/WORKSPACE/logs?version=2018-09-20&filter=customer_id::CUSTOMER_ID'

Is there a way to maintain context permanently ? such as an API key

I'm using API.AI with a backend in Golang to create a chatbot that queries an API. This API needs a API key.
This API key is user specific, it does not reply the same answer for different users.
I understand that context in API.AI can persist informations but it lasts only for a session.
Is there a way to memorize indefinitely (more or less) an information ?
Thank you all
API.AI doesn't store most dynamic data beyond the session as you've already indicated. For data as secure as API or authentication keys I'd recommend a secure database or datastore outside of API.AI and using user IDs for the platform's your working with through API.AI to connect the user to their API/authentication key (API.AI passes through information about where the request is coming from the originalRequest attribute of the JSON sent with every webhook request).
For instance you can retrieve the ID of a user who accesses your API.AI agent through the Google Assistant with originalRequest.data.user.user_id, Slack users with originalRequest.data.user and Facebook users with originalRequest.data.sender.id

API authentication from a facebook messenger bot conversation

What is the best way to authenticate with an external API from a conversation with a bot on the facebook messenger platform?
For a broad example, I would like a user of my bot to create items on their own profiles of an external website. Is there a way to get login information from the user, or connect my bot to the external website, without the user explicitly sending a message to the bot with their username and password?
What I found in the documentation under User Profile API:
You can personalize the conversation using the person's name or profile pic from the User Profile API. In order to get this information, make a GET request to https://graph.facebook.com/v2.6/?fields=first_name,last_name,profile_pic&access_token=. Read more details in the Send API reference.
This isn't quite what I'm looking for but it helps. Here's more info from the docs:
User Profile API
Request
curl -X GET "https://graph.facebook.com/v2.6/<USER_ID>?fields=first_name,last_name,profile_pic&access_token=<PAGE_ACCESS_TOKEN>"
Response
{
"first_name": "Peter",
"last_name": "Chang",
"profile_pic": "https://fbcdn-profile-a.akamaihd.net/hprofile...70ec9c19b18"
}
It depends how they come in.
If they come from your website, you can use the Send to Messengee button from within their account. Use the pass through param to link your account to the user thread.
Here's an excerpt from the documentation:
The plugin takes in a pass-through parameter defined by you. This parameter is sent back to you via a callback. You can use this to link the authentication event to a person and/or transaction. For example, a person may enter an online flow for a specific transaction and click the Send-to-Messenger button. You can pass in data to know which user and transaction was tied to the authentication event. You should encode and encrypt this parameter.
If they come directly to your bot, you would have to present them with a login of some sort (your login) from within the conversation. This would happen in a link to an mobile web URLs.