I try to get event list from outlook with using Outlook REST API.
According to Microsoft document firstly; i need to subscribe outlook
Endpoint is: https://outlook.office.com/api/v2.0/me/subscriptions
It needs NotificationURL parameter to send notification when an event is changed.
I should implement a REST API(for NotificationURL) to pass outlook as parameter but i couldn't find any document.
What parameters should get my REST endpoint or what it is type(post,get,put etc...)
i appreciate your help
thank you!
My REST API Specifications that talk with Outlook API
If you wish to get a list of events you do not need to use subscriptions at all. Just use the procedure described here.
Microsoft has push notification api aka webhook for outlook events. For that you need to first register (create subscription for resource) webhook.
check out below code snippet that allows to send notification when any event created or updated on notification url.
doc here https://learn.microsoft.com/en-us/graph/webhooks#notification-endpoint-validation
POST https://graph.microsoft.com/v1.0/subscriptions
Content-type: application/json
{
"changeType": "created,updated",
"notificationUrl": "<YOUR-notification api endpoint>/api/notify",
"resource": "me/events",
"expirationDateTime":"2019-03-3T18:23:45.9356913Z",
"clientState": "myOutlookEvents"
}
You can use clientState to verify endpoint request that comes from MS Graph.
MS will POST data in below format
{
"value": [
{
"subscriptionId":"<subscription_guid>",
"subscriptionExpirationDateTime":2019-03-3T18:23:45.9356913Z",
"clientState": "myOutlookEvents",
"changeType":"created",
"resource":"users/{user_guid}#<tenant_guid>/event/{long_id_string}",
"resourceData":
{
"#odata.type":"#Microsoft.Graph.Event",
"#odata.id":"Users/{user_guid}#<tenant_guid>/event/{long_id_string}",
"#odata.etag":"W/\"CQAAABYAAADkrWGo7bouTKlsgTZMr9KwAAAUWRHf\"",
"id":"<long_id_string>"
}
}
]
}
After this you need to get the event from id that received from graph api
Related
I finished this tutorial https://learn.microsoft.com/en-us/graph/tutorials/azure-functions?tutorial-step=5 everything worked fine until i published my azure Functions in my Azure App.
When i try to make the subscription i get this error "Subscription validation request failed. Notification endpoint must respond with 200 OK to validation request". When i test with ngrok i can create the subscription with no problems but when i replace NgrokURL value for my Azure function Url, not. Is that the right way to create the susbcription? Also i tried to create the subscription in Graph Explorer but i still get this message.
As the same question raised in MSFT Docs Q&A Forum and thanks to the Shwetachoudhary provided the solution that helps other community members:
In the following below code,
content type must be text/plain.
body must include the validation token.
CodeSamples
asp .net mvc sample - Specifically look at the NotificationController.cs file
In the method
[HttpPost]
public async Task<ActionResult> Listen()
{
if (Request.QueryString["validationToken"] != null)
{
var token = Request.QueryString["validationToken"];
return Content(token, "plain/text");
}
'notificationUrl' must be able to respond to the request for validation. Make sure the validation token returns as plain/text as well. Refer to the Notification endpoint validation document provided by Microsoft.
Try isolating the code and calling the same API with Postman or Graph Explorer and see the results.
see update: Partial Solution
I'm using dailogflow and twilio to make whatsapp chatbot.
Text messages appears normally in both dialogflow and whatsapp.
Images appears only in dialogflow chatbot, but it is not working in whatsapp chatbot and makes error in twilio
This is the part of code which I'm adding to Inline Editor of DialogFlow fulfillment:
agent.add(new Card({
title: `Title: this is a card title`,
imageUrl: 'http://examplesitelink.com/image_name.png',
})
below the error message which I receive in twilio
MESSAGE
The URI scheme, of the URI null, must be equal (ignoring case) to 'http', 'https', 'ws', or 'wss'
......
HTTP retrieval failure
......
Possible Causes
Web server returned a 4xx or 5xx HTTP response to Twilio
Misconfigured Web Server
Network disruptions between Twilio and your web server
No Content-Type header attached to response
Content-Type doesn't match actual content, e.g. an MP3 file that is being served with Content-Type: audio/x-wav, instead of Content-Type: audio/mpeg
Is there anything I can do to solve this problem?
Partial Solution
Below a partial solution
I became able to send images to whats app via dialogflow fulfillment
First, in the 'package.json' I added twilio in dependencies, "twilio": "3.37.1" (check the latest version on npm twilio)
Second I added below code to send an image to whatsapp using its url, and it works
const client = require('twilio')('YOUR_ACCOUNT_SID', 'YOUR_AUTH_TOKEN'); /* change YOUR_ACCOUNT_SID and YOUR_AUTH_TOKEN to your own twilio account data */
client.messages
.create({
to: 'whatsapp:+13233633791', /* change it to your the number which you want to send the image to*/
from: 'whatsapp:+18007778888', /* change it to your the number which twilio sandbox provide, you can find it here: https://www.twilio.com/console/sms/whatsapp/sandbox */
body: "Hi Joe! Please find your boarding pass attached. Flight OA2345 departs at 11 pm PST.",
mediaUrl: 'https://emerald-coral-3661.twil.io/assets/2-OwlAir-Upcoming-Trip.PNG',
})
.then((message) => console.log(message.sid));
the problem now is:
In previous code, to is required, which means I have to specify the number which I want to send the image to, that looks odd, but the code will not work if I didn't specify to.
What I need to know is, how can I change: to: 'whatsapp:+13233633791', to any code can send the message to the current user who use whatsapp
I have also faced the same problem of not being able to send the media messages to any user that is using the chatbot currently. I found the solution to that in a youtube video, in which they have extracted the receiver mobile no. from the request object like below -
const data = request.body.originalDetectIntentRequest.payload;
const To = data.From;
const From = data.To;
Here the request object is the one you get when you create your dialogflow agent using the code below 'req' here-
app.post("/", express.json(), (req, res) => {
-------------------
-------------------
function handler() {
----------
}
intentMap.set("intent", handler);
}
We are trying to create an approval workflow using Teams, Flow, and Assembla and are running into a bit of trouble.
We have a few of the pieces successfully setup however we are unable to initiate a POST action from a card in Teams.
In teams we can successfully create a card using the incoming webhook connector with this result.
This is created with the following JSON body from a POST action in Flow
{
"##type": "MessageCard",
"##context": "http://schema.org/extensions",
"summary": "This is the summary property",
"themeColor": "f46b42",
"sections": [
{
"startGroup": true,
"title": "**Pending Review**",
"activityTitle": "Ticket Title",
"activitySubtitle": "Requested by: ",
"facts": [
{ "name": "Date submitted:", "value": "06/27/2017, 2:44 PM" },
{ "name": "Details:",
"value": "This ticket is ready for review." }
]
},
{
"potentialAction": [
{
"##type": "HttpPOST",
"name": "Approve",
"target": "ANOTHER-POST-URL-IS-HERE"
},
{
"##type": "HttpPOST",
"name": "Deny",
"target": "ANOTHER-POST-URL-IS-HERE"
}
]
}
]
}
We have another Flow url as the target for both buttons on the card. To test this url we are able to successfully post via POSTMAN and continue the approval workflow.
When clicking the button on the Team card the Flow at the post url is in no way notified at all. No run on Flow is triggered. In teams a very generic "There was a problem submitting your changes. Try again in a minute." error is displayed.
After researching I ran across the connectors.md file on the Microsoft Teams github page and noticed this lovely part of the documentation
It seems odd to me that right below them mentioning that POST actions may not be supported the documentation goes on in length to show examples of using POST and ActionCard actions in a card on teams.
So my question is this, is there any way to get an HttpPOST action to work from a custom card in Teams to a Microsoft Flow POST URL?
Thanks!
Update:
Upon further testing we have determined that HttpPOST actions
work with just about any post url we can come up with except
Microsoft Flow Request URLs. They are exceptionally long urls so maybe
that has something to do with it?
Here's an example Flow request url.
https://prod-43.westus.logic.azure.com:443/workflows/f86b928acd3d4ecab849f677974f7816/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=ZBxr5GFKQhMp4JXWGmec_L6aqgcaqvCOKUWOf2li-xQ
When running teams in a web browser we are able to see the request
first posts to a api.teams.skype.com url and returns a generic
"ProviderError". Other non-flow urls also do the same but return
success.
This was a head-scratcher for us - as you surmised, this should have worked. The Teams, Flow, and Outlook teams troubleshooted this today and found out what was going on.
The URL you are posting to, https://prod-43.westus.logic.azure.com[...] has an embedded bearer token (the value of the sig parameter in the URL). When you POST to that URL via CURL, Fiddler, Postman, etc. it works because that token is present.
However, when you click on a HttpPOST button in an actionable message, Outlook adds its own JWT token in the HTTP header, meaning that the HTTP POST has both a sig= bearer token in the URL and a JWT token in the HTTP header. Flow detects this and rejects the HTTP POST as invalid (while we don't currently support JWT tokens, we plan to, and treat this case as invalid to maintain forward compatibility).
This use case will work in the future. In the meantime, one workaround to try would be to have the actionable message buttons POST to your endpoints, e.g. https://yoursite.com/accept and https://yoursite.com/deny (validating the JWT as much as you like) and have these endpoints POST to Flow directly without the JWT.
Please let us know if that works.
BTW, the text you found is a documentation bug that has since been fixed:
Sorry for the confusion.
I have successfully set up Google Pub/Sub to use Gmail API Watch feature as described here: https://developers.google.com/gmail/api/guides/push to watch INBOX label in my gmail account.
Once new message arrive I instantly get a push notification in valid format like:
{ message:
{ data: '.......',
attributes: {},
message_id: '1248700053943' },
subscription: '.....' }
After I base64decode data I get email and historyId. Then, as suggested, I request gmail.users.history.list API (via API console) with startHistoryId set to the historyId from the push notification. And then get just empty response without any details:
GET https://www.googleapis.com/gmail/v1/users/me/history?startHistoryId=4658879&key={YOUR_API_KEY}
200 OK
- Show headers
{
"historyId": "4658894"
}
So historyId from a notification does not seems valid.
Seems Gmail users.watch API is not working properly, and sends wrong historyId, or I'm just missing something?
Looks like I misunderstood how users.history.list works, and the flow should be something like described below:
Remember historyId from the response of users.watch request.
On push notification call users.history.list with previously remembered historyId as startHistoryId instead of new one from notification, and get list of recent changes.
Remember historyId from notification, and goto 2.
If we look on the response of any call to users.history.list, historyId is always present, it's a marker of latest history change. Push notification brings latest historyId, so if we request users.history.list with it (as in the question), we got empty array of history, and the server drops this empty "history" field from the response, that's why we get this:
{
"historyId": "4658894"
}
But not this:
{
"history": [ ],
"historyId": "4658894"
}
More details provided in sync guide: https://developers.google.com/gmail/api/guides/sync#partial
So we can't easily get details of the new message arrived to INBOX from push notification, and need to deal with history mining and synchronization to find it.
How do I stop watching the entire channel? The API reference reproduced below requires a resourceId, seemingly implying that it only stops watching the event specific to the resourceId. For my purposes, I would think that a channelId is enough and therefore uncertain what to put for resourceId. The field is not optional.
POST https://www.googleapis.com/calendar/v3/channels/stop
Authorization: Bearer {auth_token_for_current_user}
Content-Type: application/json
{
"id": "4ba78bf0-6a47-11e2-bcfd-0800200c9a66",
"resourceId": "ret08u3rv24htgh289g"
}
It turns out that the resourceId has nothing to do with the event that caused the push notification. In your app, you should store both the channelId and resourceId and provide it as required to stop notifications. Still not sure why Google requires two ids for a single purpose. Seems redundant.