How can I request the user's location in API.ai? - dialogflow-es

I'm creating an agent using api.ai and using a PHP script as a webhook. The documentation doesn't make it clear on how to do it, but I'm wanting to request permission to the user's coarse location so they won't have to provide their location for requests.
I've tried echo-ing the JSON they mention, and putting it in as a custom payload for the default welcome intent, but neither of those seem to prompt me for permission to use my location.
How do I ask a user for permission to get their location?
EDIT: If I set my PHP script to respond to intent.welcome with the following JSON:
{
"data": {
"google": {
"expectUserResponse": true,
"systemIntent": {
"intent": "actions.intent.PERMISSION",
"data": {
"#type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
"optContext": "To provide an accurate experience, ",
"permissions": ["DEVICE_PRECISE_LOCATION"]
}
}
}
}
}
The app asks me "To provide an accurate experience, , I'll just need to get your street address from Google. Is that ok?"
However if I say "yes", then the app keeps asking things like "Sorry, could you say that again?", so I can't actually get it to do anything.

You need to create a new Intent with the Event set to actions_intent_PERMISSION. (See image below.)
When this Event is triggered, your webhook will be called with the JSON originalRequest.data.device.location field in the request body populated with the location information you've requested.

Related

MS Bot Framework Direct Line API 3.0: Get starting message

I published a bot using the Azure bot framework to the Azure cloud servers, and made an application that uses the Direct Line API 3.0 to send user responses and receive bot messages through HTTP requests. Everything works except that I'm not sure how to get the starting message of the bot at the start of the conversation. I open the conversation with the /v3/directline/conversations endpoint, but I'm not sure how to receive the first message of the bot (that is normally sent without any user interaction). A message request after opening the conversation doesn't include any bot responses, but the next message request after sending the first user input includes the first two messages of the bot (starting message and response to the user).
EDIT: From reading this I came to the conclusion that it will be easier to just use a custom event as a trigger for the welcome message. I updated my bot as follows to reflect this within bot composer, adding a new CUSTOM event trigger with a test response message:
However, I still can't seem to trigger this event via the Direct Line API. Currently, I send a request as follows, following the event activity structure:
{
"type": "event",
"channelId": "directline",
"from": { "id": "UnityUserId", "name": "Unity User 1" },
"value": "test",
"name": "welcome"
}
I then get a response with ID, normally indicating that the request was successfull. However, upon requesting the bot response messages, I get the following:
{
"activities": [
{
"type": "event",
"id": "5FZsHpWBxm1hjhWQYY7gr-eu|0000000",
"timestamp": "2022-04-09T14:39:15.90169Z",
"serviceUrl": "https://directline.botframework.com/",
"channelId": "directline",
"from": {
"id": "UnityUserId",
"name": "Unity User 1"
},
"conversation": {
"id": "5FZsHpWBxm1hjhWQYY7gr-eu"
},
"value": "test",
"name": "welcome"
}
],
"watermark": "0"
}
Indicating that the bot has no responses, which doesn't seem quite right when looking at the bot composer screenshot above. Is there something wrong with my current method?
Regards
The onMembersAdded event usually does the trick. Sample code is in https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-send-welcome-message?view=azure-bot-service-4.0&tabs=csharp
I thought I remembered seeing the bot's welcome message when using Direct Line, so I tried to quickly repro it again. I connected a simple echo bot via Direct Line. Then I created a conversation, sent a simple message, and then retrieved all activities (all via REST calls), and the bot's welcome message was indeed present in the response, as you can see in this screenshot:
Perhaps you should use these Direct Line 3.0 API reference docs as opposed to the one you linked above. I followed these steps using the basic Echo bot sample, Postman, and a bot resource in Azure for simple and easy testing, but you could use a full application if you wish.

How to get the user id from Slack to bot service

I am creating a simple bot using Azure LUIS and this is my first one. I made some decent progress after doing some research and also now integrated with Slack as channel to test it.
The bot functionality is working fine, but I am looking to identify the user. So that I can personalize the bot conversation and also to pull the user specific information from his profile table.
Is there anyway, that I can get a UID or any reference ID of the slack user and so I can store that in my user table along with user profile?
So next time, when the user greets the bot, the bot can say "Hello, John." instead of justing say "Hello."
Thanks!
Yes. You can use the channelData object to get the ApiToken, and user values. For example, in C#, you could use turnContext.Activity.ChannelData to get those values in JSON:
{{
"SlackMessage": {
"token": "............",
"team_id": "<TEAM ID>",
"event": {
"type": "message",
"text": "thanks",
"user": "<USER WHO MESSAGED>",
"channel": "............",
"channel_type": "channel"
},
"type": "event_callback",
"event_id": ""............",
"event_time": 1553119134,
"authed_users": [
"............",
"<USER WHO MESSAGED>"
]
},
"ApiToken": "<ACTUAL TOKEN HERE>"
}}
Then, using those two pieces of information, you can then retrieve info from Slack.
https://slack.com/api/users.info?token=<ACTUAL TOKEN HERE>&user=<USER WHO MESSAGED>&pretty=1
And get a response that has the info you need:
{
"ok": true,
"user": {
"id": "<USER WHO MESSAGED>",
"team_id": "<TEAM ID>",
"real_name": "Dana V",
Ideally, you would would probably want to have bot user state setup and check that first, then if not there, then make the API call to Slack, then store in state. Therefore further requests don't need to go to Slack, but will just pull from the state store.
Basically, you could/should do this in the onTurn event. First, create your user state storage such as here.
Then you could check for that value and write to it if not populated. This example on simple prompts, might be helpful. You won't need to prompt for your user's name, as this example does, but does read/write username from state. You could still use dialogs, but you won't need them for the name prompting as you are doing that dynamically.
You can see here where username is being set and here where it is being retrieved. In this case, it is in the dialogs, but again; you would/could just do in the turn context (using logic to get and if not there, set).
I found the solution by priting the whole session object, which is having all the required informaiton. This could be same as mentioned by Dana above, but after debugging, this follwing made simple without making any changes.
var slackID = session.message.address.user.id
With above, I am able to identify the user.
Thanks.

fallback intent not invoked from Carousel (Actions on Google)

I am connecting Actions on Google (on my Android) to my webhook via API.AI
When a user orders, say pizza online, API.AI creates a fallback intent and the webhook sends a json with Carousel.
This works fine. If user clicks on Carousel item, the response is sent to webhook too.
I am responding to that click by asking "How many pizzas" and use a suggestion chip.
However, no fallback intent is activated in API.AI and the app crashes.
Earlier, I was giving a simple text response to carousel select "Thanks for the order" and it was working.
Can someone help me solve this problem?
I realize that the problem is not in API.AI or fallback intent but in JSON I am sending. If I reply to user's selection in Carousel with a simple text/speech response it works. It also works if I send a Carousel chip again. However, if I try to send a list or card, it crashes. Perhaps, I don't have right json formatting for them.
If someone has any json sent by their webhook (working with API.AI) for list/suggestion chip or card, it would be very helpful!
#matthewayne When I send the following as a reply (json), it works:
speech = "Thank you. People also looked at these:"
print(speech)
webhook_result={
"speech": speech,
"contextOut": [
{
"name": "_actions_on_google_,complementary",
"lifespan": 100,
"parameters": {}
}
],
"data": {
"google": {
"expectUserResponse": True,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": speech
}
}
],
"suggestions": []
},
"systemIntent": {
"intent": "actions.intent.OPTION",
"data": {
"#type": "type.googleapis.com/google.actions.v2.OptionValueSpec",
"carouselSelect": {}
}
}
}
}
}
I also populate carouselSelect with list of things in carousel. But if I change it to listSelect, and respond, it crashes.
When I say crash, it means that Google says that my app has stopped responding.
It would be very helpful to have a template or sample listResponse json.
After a carousel response is sent to the user the next request that will be sent will likely be a list selection event. You need to handle this either:
in API.AI (by creating an intent with the event actions_intent_OPTION, docs here)
or
in your webhook using the Google Assistant client library (docs here).

Getting the email id from the Outlook REST API when sending email

I am trying to use the Microsoft Rest API to send emails on behalf of our users. When I create a message as a draft, I get back an ID that I can use in future requests for editing, deleting, viewing the full conversation (after it is sent), etc.
I do not want to save it as a draft since I have no reason to, I just want to send it directly. After it is sent, I would still like to view the full conversation. However, if I just send the email (using the /sendmail endpoint), I do not get that ID. Is there anyway to get it? Here is my request:
POST https://outlook.office.com/api/v2.0/Users/email/sendmail
{
"Message": {
"Subject": "Test",
"Importance": "Normal",
"ToRecipients": [{
"EmailAddress": {
"Address": "<email>",
"Name": "<name>"
}
}],
"Sender": {
"EmailAddress": {
"Address": "<email",
"Name": "<name>"
}
},
"Body": {
"ContentType": "HTML",
"Content": "<html>\\n<head>\\n <style>\\n p { color: red; }\\n </style> \\n</head>\\n<body>\\n <p>Test</p>\\n</body>\\n</html>\\n"
}
},
"SaveToSentItems": "true"
}
The HTTP response code is 202, the email sends, but the body is empty (no content, whatsoever).
I don't think this matters, since I can recreate this in Postman, but I am running this in Nodejs using the node-outlook package.
Emails in Exchange via REST and EWS are submitted for transport, but the actual send and subsequent save to the sent items folder are done async. This is why you don't get the id. Transport is who actually writes the email to the sent items folder, not REST.
If you really need to find the item after it has been saved to the sentItems folder, set something like the PR_SEARCH_KEY and then do a view of the sent items folder and seek to that search key value.
Also note when you save a draft, the id that you get back will be different than the id of the item in the sent items folder because the folder Id is part of the id of the item, so that id wouldn't help you anyways.
I don't know which rest api version are you using (i'm using v2.0) but i will try to explain this issue. Sorry for my english i advance.
You have 2 ways to reply a message: on the fly way or the complete way.
On the fly way
Its the easy way, just send a post request to
https://outlook.office.com/api/v2.0/me/messages/{message_id}/reply
or
https://outlook.office.com/api/v2.0/me/messages/{message_id}/replyall
and with the body
{
"Comment": "This is your message in plain text or html code"
}
and thats all.
The problem with this methos that you can only send plain text or HTML, no attachments or anything else. If that's all you need this is your best option.
The complete way
If you need to send an attachment or perform any other action you need to perform these 3 steps:
1. Create a draft from the message you want to reply
Send a post request to
https://outlook.office.com/api/v2.0/me/messages/{message_id}/createreply
This will give you an json object save the "Id" property {draft_id} of this draft for later use.
2. Update the draft
Send a patch request to
https://outlook.office.com/api/v2.0/me/messages/{draft_id}
and with the body
{
"Body": {
"ContentType": "HTML or Text",
"Content": "Your response in plain text or html"
}
}
or any other parameter you want to change.
3. Send the draft
Send a post request to
https://outlook.office.com/api/v2.0/me/messages/{draft_id}/send
And thats it.
If you need more info abut this check https://msdn.microsoft.com/en-us/office/office365/api/mail-rest-operations

Api version change but docs not updated?

I've been trying to do various things through your Mail REST API today and not having much success... My project (using the api) has been running for at least a month now, but requests to your api are failing.
For example:
GET https://outlook.office365.com/EWS/OData/Me/messages (works)
GET https://outlook.office365.com/EWS/OData/Me/inbox (doesn't work)
Looking at the documentation, still says its available.
Trying to send an email using:
POST https://outlook.office365.com/EWS/OData/Me/Messages?MessageDisposition=SendAndSaveCopy also just returns 400 (Bad Request)
Any info about this?
Also, the http status codes returned are not useful at all; almost all errors return as 400's. In one instance, I didn't provide auth creds, and a 400 was returned instead of the appropriate 401. The accompanying status code detail could also be more helpful.
Thanks for the feedback and sorry for the inconvenience. We are currently deploying some non-backwards compatible changes described here, and this is causing your issues. The current set of changes including versioning support, and deploying non-backwards compatible changes won't cause issues for your app in the future. For the queries, that don't work, please use the following:
Accessing Inbox: https://outlook.office365.com/ews/odata/me/folders/inbox
Send email (new action called SendMail):
POST https://outlook.office365.com/ews/odata/me/sendmail
{
"Message":
{
"Subject": "Test message",
"Body":
{
"Content": "This is test message!"
},
"ToRecipients":
[
{ "EmailAddress": { "Address": "John#contoso.com", "Name": "John Doe" }},
{ "EmailAddress": { "Address": "Jane#fabrikam.com", "Name": "Jane Smith" }}
]
},
"SaveToSentItems": true
}
Hope this helps. We are updating the documentation to reflect the changes, and it should be available shortly. Thanks for the feedback on the HTTP status codes, we will review the status codes returned currently and make any fixes required.
Conversation support is in our roadmap but we don't yet have a timeline to share. Currently, you can search using https://outlook.office365.com/ews/odata/Folders/FolderId/Messages?$filter=ConversationId%20eq%20%%27ConversationID%27 but this will only return messages within the specified folder belonging to that conversation.
Let me know if you have any questions or need more info.
Thanks,
Venkat

Resources