How to get full location from Microsoft Graph CalendarView Delta API request? - microsoft-graph-api

We found two different behaviours creating an event using Outlook Desktop and Outlook Web (OWA).
Consider create an event A with Outlook Desktop and event B with Outlook Web (OWA) with two "rooms" (location).
Result of event created with Outlook Desktop:
"locations": [
{
"displayName": "Room 1; Room 2",
"locationType": "default",
"uniqueId": "Room 1; Room 2",
"uniqueIdType": "private"
}
],
Result of event created with Outlook Web OWA:
"locations": [
{
"displayName": "Room 1",
"locationType": "conferenceRoom",
"uniqueId": "room1#xxx.onmicrosoft.com",
"uniqueIdType": "directory",
"locationUri": "room1#xxx.onmicrosoft.com",
"address": {
"street": "",
"city": "",
"state": "",
"countryOrRegion": "",
"postalCode": ""
},
"coordinates": {}
},
{
"displayName": "Room 2",
"locationUri": "room2#xxx.onmicrosoft.com",
"locationType": "conferenceRoom",
"uniqueId": "room2#xxx.onmicrosoft.com",
"uniqueIdType": "directory",
"address": {
"street": "",
"city": "",
"state": "",
"countryOrRegion": "",
"postalCode": ""
},
"coordinates": {}
}
],
Why when the event is created with Outlook Desktop the "locations" field comes shorten? Is it a bug?
How to always get the full "locations" (like Outlook Web OWA result), no matter with what Outlook version?
Thank you.

The location resource will on return populated properties. So if the application that created the Event doesn't specify an address, coordinates, or locationUri, then the API won't return them.

Related

How to create Microsoft Team via Microsoft Graph API with Owners specified by User Email rather than User ID?

Desired Behaviour
Create a Microsoft Team, with specified Owners and Members, in a Power Automate Flow using the HTTP connector to make requests to the Microsoft Graph API.
Actual Behaviour
This code shows how you can create a Microsoft Team whilst specifying it's Owners by User ID.
{
"template#odata.bind": "https://graph.microsoft.com/v1.0/teamsTemplates('standard')",
"displayName": "My Sample Team",
"description": "My Sample Team’s Description",
"members": [
{
"#odata.type": "#microsoft.graph.aadUserConversationMember",
"roles": [
"owner"
],
"user#odata.bind": "https://graph.microsoft.com/v1.0/users('0040b377-61d8-43db-94f5-81374122dc7e')"
}]
}
Source
For reference, the Graph API docs entry for Get a user (which is used to specify the Owner in the code above), specifies the endpoint syntax as:
GET /users/{id | userPrincipalName}
Currently, I do not have access to users' id or userPrincipalName.
What I've Tried
I am using a Power Automate Flow with the SharePoint For a selected item trigger.
The list includes two columns of type Person where Owners and Members are specified.
In order to get a list of Owners, I am using the SharePoint connector's Get item action on the selected item and then using an Apply to each control to iterate over each columns' values.
Below is the Raw Output of Get Item - the Owners column array is TeamOwner_x002f_s.
You can see that each object only has DisplayName and Email and not User ID or userPrincipalName:
{
"statusCode": 200,
"headers": {
"Transfer-Encoding": "chunked",
"Vary": "Origin,Accept-Encoding",
"X-SharePointHealthScore": "1",
"X-MS-SPConnector": "1",
"X-SP-SERVERSTATE": "ReadOnly=0",
"DATASERVICEVERSION": "3.0",
"SPClientServiceRequestDuration": "68",
"SPRequestGuid": "letters-and-numbers",
"request-id": "letters-and-numbers",
"MS-CV": "letters-and-numbers.0",
"Strict-Transport-Security": "max-age=31536000",
"X-FRAME-OPTIONS": "SAMEORIGIN",
"Content-Security-Policy": "frame-ancestors 'self' teams.microsoft.com *.teams.microsoft.com *.skype.com *.teams.microsoft.us local.teams.office.com *.powerapps.com *.yammer.com *.officeapps.live.com *.office.com *.stream.azure-test.net *.microsoftstream.com;",
"MicrosoftSharePointTeamServices": "numbers-and-dots",
"X-Content-Type-Options": "nosniff",
"X-MS-InvokeApp": "1; RequireReadOnly",
"Timing-Allow-Origin": "*",
"x-ms-apihub-cached-response": "false",
"Cache-Control": "max-age=0, private",
"Date": "Sun, 04 Jul 2021 06:42:53 GMT",
"P3P": "CP=\"SOME CODES HERE\"",
"X-AspNet-Version": "4.0.30319",
"X-Powered-By": "ASP.NET",
"Content-Type": "application/json; charset=utf-8",
"Expires": "Sat, 19 Jun 2021 06:42:54 GMT",
"Last-Modified": "Sun, 04 Jul 2021 06:42:54 GMT",
"Content-Length": "3938"
},
"body": {
"#odata.etag": "\"2\"",
"ItemInternalId": "1",
"ID": 1,
"Title": "View",
"Year": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference",
"Id": 2,
"Value": "2023"
},
"Year#Id": 2,
"ProgramType": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference",
"Id": 0,
"Value": "Program Type 01"
},
"ProgramType#Id": 0,
"ProgramName": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference",
"Id": 1,
"Value": "02"
},
"ProgramName#Id": 1,
"TeamOwner_x002f_s": [
{
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
"Claims": "i:0#.f|membership|user_1#my-tenant.onmicrosoft.com",
"DisplayName": "User Name 1",
"Email": "user_1#my-tenant.onmicrosoft.com",
"Picture": "https://my-tenant.sharepoint.com/sites/ExampleTeam/_layouts/15/UserPhoto.aspx?Size=L&AccountName=user_1#my-tenant.onmicrosoft.com",
"Department": null,
"JobTitle": null
},
{
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
"Claims": "i:0#.f|membership|user_2#my-tenant.onmicrosoft.com",
"DisplayName": "User Name 2",
"Email": "user_2#my-tenant.onmicrosoft.com",
"Picture": "https://my-tenant.sharepoint.com/sites/ExampleTeam/_layouts/15/UserPhoto.aspx?Size=L&AccountName=user_2#my-tenant.onmicrosoft.com",
"Department": null,
"JobTitle": null
}
],
"TeamOwner_x002f_s#odata.type": "#Collection(Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser)",
"TeamOwner_x002f_s#Claims": [
"i:0#.f|membership|user_1#my-tenant.onmicrosoft.com",
"i:0#.f|membership|user_2#my-tenant.onmicrosoft.com"
],
"TeamOwner_x002f_s#Claims#odata.type": "#Collection(String)",
"Team_x0020_Member_x002f_s": [
{
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
"Claims": "i:0#.f|membership|user_3#my-tenant.onmicrosoft.com",
"DisplayName": "User Name 3",
"Email": "user_3#my-tenant.onmicrosoft.com",
"Picture": "https://my-tenant.sharepoint.com/sites/ExampleTeam/_layouts/15/UserPhoto.aspx?Size=L&AccountName=user_3#my-tenant.onmicrosoft.com",
"Department": null,
"JobTitle": null
}
],
"Team_x0020_Member_x002f_s#odata.type": "#Collection(Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser)",
"Team_x0020_Member_x002f_s#Claims": [
"i:0#.f|membership|user_3#my-tenant.onmicrosoft.com"
],
"Team_x0020_Member_x002f_s#Claims#odata.type": "#Collection(String)",
"Status": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference",
"Id": 0,
"Value": "Details Added"
},
"Status#Id": 0,
"Modified": "2021-07-04T03:57:16Z",
"Created": "2021-07-04T03:51:18Z",
"Author": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
"Claims": "i:0#.f|membership|user_1#my-tenant.onmicrosoft.com",
"DisplayName": "User Name 1",
"Email": "user_1#my-tenant.onmicrosoft.com",
"Picture": "https://my-tenant.sharepoint.com/sites/ExampleTeam/_layouts/15/UserPhoto.aspx?Size=L&AccountName=user_1#my-tenant.onmicrosoft.com",
"Department": null,
"JobTitle": null
},
"Author#Claims": "i:0#.f|membership|user_1#my-tenant.onmicrosoft.com",
"Editor": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
"Claims": "i:0#.f|membership|user_1#my-tenant.onmicrosoft.com",
"DisplayName": "User Name 1",
"Email": "user_1#my-tenant.onmicrosoft.com",
"Picture": "https://my-tenant.sharepoint.com/sites/ExampleTeam/_layouts/15/UserPhoto.aspx?Size=L&AccountName=user_1#my-tenant.onmicrosoft.com",
"Department": null,
"JobTitle": null
},
"Editor#Claims": "i:0#.f|membership|user_1#my-tenant.onmicrosoft.com",
"{Identifier}": "Lists%252fMy%2bList%2bName%252f1_.000",
"{IsFolder}": false,
"{Thumbnail}": {
"Large": null,
"Medium": null,
"Small": null
},
"{Link}": "https://my-tenant.sharepoint.com/sites/ExampleTeam/_layouts/15/listform.aspx?PageType=4&ListId=list-id-here&ID=1&ContentTypeID=content-type-id-here",
"{Name}": "View",
"{FilenameWithExtension}": "View",
"{Path}": "Lists/My List Name/",
"{FullPath}": "Lists/My List Name/1_.000",
"{VersionNumber}": "2.0"
}
}
Question
Is it possible to specify Team members by Email in the Graph API request?
Or do I need to somehow get the User ID of each user specified (and if so, what is the best way to do that)?
Update
I tried this HTTP connector GET request in the hopes it would return User ID for each Person:
https://graph.microsoft.com/v1.0/sites/site-id-here/lists/list-id-here/items/item-id-here?expand=fields(select=TeamOwner%5Fx002f%5Fs)
But it returned even less information:
"fields": {
"#odata.etag": "\"letters-and-numbers,2\"",
"TeamOwner_x002f_s": [{
"LookupId": 9,
"LookupValue": "User Name 1",
"Email": "user_1#my-tenant.onmicrosoft.com"
},
{
"LookupId": 27,
"LookupValue": "User Name 2",
"Email": "user_2#my-tenant.onmicrosoft.com"
}
]
}
API docs reference for this approach
Get specific column values of a listItem
GET https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items/{item-id}?expand=fields(select=Column1,Column2)
You can get the user information from Microsoft Graph itself, what you can try out is List Users with filter parameter.
like this:
GET https://graph.microsoft.com/v1.0/users?$filter(mail eq 'user_1#my-tenant.onmicrosoft.com')
OR
You can list all users and do a mail/displayName search(Ctrl+F) on results at graph explorer.
By these you will be able to get userPrincipalName as well as id.
Permission required:-
One of the following permissions is required to call this API.
Delegated (work or school account) - User.ReadBasic.All,
User.Read.All, User.ReadWrite.All, Directory.Read.All,
Directory.ReadWrite.All, Directory.AccessAsUser.All
Delegated
(personal Microsoft account) - Not supported.
Application - User.Read.All, User.ReadWrite.All, Directory.Read.All,
Directory.ReadWrite.All
Thanks.

Not getting any webhook notification for Microsoft O365 Management APIs

I have created the below webhooks and all are enabled.:
[
{
"contentType": "Audit.AzureActiveDirectory",
"status": "enabled",
"webhook": {
"authId": "12345",
"address": "https://978b7cfb66d9.ngrok.io/callback/",
"expiration": "",
"status": "enabled"
}
},
{
"contentType": "Audit.General",
"status": "enabled",
"webhook": {
"authId": "12345",
"address": "https://978b7cfb66d9.ngrok.io/callback/",
"expiration": "",
"status": "enabled"
}
},
{
"contentType": "Audit.SharePoint",
"status": "enabled",
"webhook": {
"authId": "12345",
"address": "https://978b7cfb66d9.ngrok.io/callback/",
"expiration": "",
"status": "enabled"
}
}
]
I don't see any notifications coming when there are changes made in sharepoint. Anything in particular need to change?
From the access token, I do see correct app permissions:
"roles": [
"ServiceHealth.Read",
"ActivityFeed.Read"
]
I manually queried to get content and it shows empty.
https://manage.office.com/api/v1.0/{tenant-guid}/activity/feed/subscriptions/content?contentType=Audit.Sharepoint
Looks like the auditing for Office 365 organization is disabled.
Make sure you turn on audit log search.

Office 365 API - Get meeting room location and capacity

I'm doing an integration of mobile app with the Office 365 Calendar. I want to show room capacity and location on the screen. I trying to find an API to get meeting room info (this info is available on website when selecting room as user).
I tried both Outlook REST API (version 2.0) and Microsoft Graph but found nothing in the docs on how to get such info.
Where I can find such API if it exists?
I know this is an old question but you can do it using the List Places API in Graph API: https://learn.microsoft.com/en-us/graph/api/place-list?view=graph-rest-1.0&tabs=http
GET https://graph.microsoft.com/v1.0/places/microsoft.graph.room
RESPONSE:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#places/microsoft.graph.room",
"value": [
{
"id": "3162F1E1-C4C0-604B-51D8-91DA78989EB1",
"emailAddress": "cf100#contoso.com",
"displayName": "Conf Room 100",
"address": {
"street": "4567 Main Street",
"city": "Buffalo",
"state": "NY",
"postalCode": "98052",
"countryOrRegion": "USA"
},
"geoCoordinates": {
"latitude": 47.640568390488626,
"longitude": -122.1293731033803
},
"phone": "000-000-0000",
"nickname": "Conf Room",
"label": "100",
"capacity": 50,
"building": "1",
"floorNumber": 1,
"isManaged": true,
"isWheelChairAccessible": false,
"bookingType": "standard",
"tags": [
"bean bags"
],
"audioDeviceName": null,
"videoDeviceName": null,
"displayDevice": "surface hub"
},
{
"id": "3162F1E1-C4C0-604B-51D8-91DA78970B97",
"emailAddress": "cf200#contoso.com",
"displayName": "Conf Room 200",
"address": {
"street": "4567 Main Street",
"city": "Buffalo",
"state": "NY",
"postalCode": "98052",
"countryOrRegion": "USA"
},
"geoCoordinates": {
"latitude": 47.640568390488625,
"longitude": -122.1293731033802
},
"phone": "000-000-0000",
"nickname": "Conf Room",
"label": "200",
"capacity": 40,
"building": "2",
"floorNumber": 2,
"isManaged": true,
"isWheelChairAccessible": false,
"bookingType": "standard",
"tags": [
"benches",
"nice view"
],
"audioDeviceName": null,
"videoDeviceName": null,
"displayDevice": "surface hub"
}
]
}

Create thread in Microsoft Teams with Subject

I'm currently trying to create a Microsoft teams thread (within a channel) via the Microsoft Graph API.
I'd like thread to have a subject/title and I'm sending the following request (from the graph explorer)
POST https://graph.microsoft.com/beta/teams/{teamId}/channels/{channelId}/chatThreads
with the following payload
{
"rootMessage": {
"body": {
"contentType": 1,
"content": "<h1>Hello world</h1>"
},
"subject": "Welcome Aboard!"
}
}
However the thread that gets created doesn't have any title as you can see on the following screen capture.
So the question is: how can I create a chat thread with a subject from the Microsoft Graph API?
Edit: here is the payload I get for the message "title from teams" (which was created from the UI), note is contains a subject attribute.
{
"replyToId": null,
"etag": "1537198542791",
"messageType": "message",
"createdDateTime": "2018-09-17T15:35:42.791Z",
"lastModifiedDateTime": null,
"deleted": false,
"subject": "title from teams",
"summary": null,
"importance": "normal",
"locale": "en-us",
"id": "1537198542791",
"from": {
"application": null,
"device": null,
"user": {
"id": "c2e8df37-c6a7-4d88-89b1-feb4f1fda7c5",
"displayName": "Vincent Biret",
"identityProvider": "Aad"
}
},
"body": {
"contentType": "text",
"content": "wvwvwevw"
},
"attachments": [],
"mentions": [],
"reactions": []
}
There is no "subject" for a post in Microsoft Teams. These are chat threads, not email threads. The only content is the body:
{
"rootMessage": {
"body": {
"contentType": 1,
"content": "<h1>Hello world</h1>"
}
}
}

How to create customer & items in quickbook through api in rails?

I want to create invoice in my Quickbooks account through API from my rails application, but it requires to add customer and item before creating invoice. But I can't get the idea how to add customer and items through API. Can you suggest me???
Thanks.
Start here:
https://developer.intuit.com/
Follow the docs (https://developer.intuit.com/docs/0100_accounting) and implement OAuth to connect to QuickBooks Online.
Create customers by HTTP POSTing a JSON request to QuickBooks Online:
https://developer.intuit.com/docs/api/accounting/Customer
The JSON request will look something like this:
{
"BillAddr": {
"Line1": "123 Main Street",
"City": "Mountain View",
"Country": "USA",
"CountrySubDivisionCode": "CA",
"PostalCode": "94042"
},
"Notes": "Here are other details.",
"Title": "Mr",
"GivenName": "James",
"MiddleName": "B",
"FamilyName": "King",
"Suffix": "Jr",
"FullyQualifiedName": "King Groceries",
"CompanyName": "King Groceries",
"DisplayName": "King's Groceries",
"PrimaryPhone": {
"FreeFormNumber": "(555) 555-5555"
},
"PrimaryEmailAddr": {
"Address": "jdrew#myemail.com"
}
}
You'll get back something like this:
{
"Customer": {
"Taxable": true,
"BillAddr": {
"Id": "112",
"Line1": "123 Main Street",
"City": "Mountain View",
"Country": "USA",
"CountrySubDivisionCode": "CA",
"PostalCode": "94042"
},
"Notes": "Here are other details.",
"Job": false,
"BillWithParent": false,
"Balance": 0,
"BalanceWithJobs": 0,
"CurrencyRef": {
"value": "USD",
"name": "United States Dollar"
},
"PreferredDeliveryMethod": "Print",
"domain": "QBO",
"sparse": false,
"Id": "67",
"SyncToken": "0",
"MetaData": {
"CreateTime": "2015-07-23T10:58:12-07:00",
"LastUpdatedTime": "2015-07-23T10:58:12-07:00"
},
"Title": "Mr",
"GivenName": "James",
"MiddleName": "B",
"FamilyName": "King",
"Suffix": "Jr",
"FullyQualifiedName": "King's Groceries",
"CompanyName": "King Groceries",
"DisplayName": "King's Groceries",
"PrintOnCheckName": "King Groceries",
"Active": true,
"PrimaryPhone": {
"FreeFormNumber": "(555) 555-5555"
},
"PrimaryEmailAddr": {
"Address": "jdrew#myemail.com"
},
"DefaultTaxCodeRef": {
"value": "2"
}
},
"time": "2015-07-23T10:58:12.099-07:00"
}
Make sure you save that Id attribute, you'll need that later.
The process for creating Items is similar. Docs:
https://developer.intuit.com/docs/api/accounting/Item
Everything is just standard OAuth requests. Go grab an OAuth library for Rails and you should be all set.

Resources