Creating Team with Microsoft.Graph dotnet SDK - microsoft-graph-api

With the msgraph-sdk-dotnet I create a unified group.
var newGroup = await graphClient.Groups.Request().AddAsync(new Group
{
GroupTypes = new List<string> { "Unified" },
DisplayName = name,
Description = description,
MailEnabled = true,
SecurityEnabled = false,
Visibility = "Private",
});
Next I want to add a Team to it. The docs provide me with the HTTP request to create a team (PUT /groups/{id}/team), but I would rather continue using the statically typed SDK.
What is the easiest way to use the SDK in order to create a Team?

You'll add a team like this:
graphClient.Groups[groupPage[8].Id].Team.Request().PutAsync(team)
This will be available in the next release.
https://github.com/microsoftgraph/msgraph-sdk-dotnet/pull/352

Related

Not able to get Team Id

I am creating a Microsoft Team using application permission via graph API. The team is getting created successfully but I am not getting any response.
I am using the Graph SDK. Below is my code. This is the reference I am following.
var team = new Team
{
DisplayName = "standardhealthcareHospital",
Description = "standardhealthcareHospital",
Members = new TeamMembersCollectionPage()
{
new AadUserConversationMember
{
Roles = new List<String>()
{
"owner"
},
AdditionalData = new Dictionary<string, object>()
{
{"user#odata.bind", "https://graph.microsoft.com/v1.0/users('a5808510-0abf-46ba-a0c1-9cdb7c374e4a')"}
}
}
},
AdditionalData = new Dictionary<string, object>()
{
{"template#odata.bind", "https://graph.microsoft.com/v1.0/teamsTemplates('standard')"}
}
};
var teamCreated = await graphClient.Teams
.Request()
.AddAsync(team);
Can anyone tell me what am I missing here? How can I get the Id of the team which just got created?
Thanks in advance.
You are not missing anything but as per the Github Post that I created, creating a team using Graph SDK doesn't give you the team details which got created. It is by design.
You can simply make a call filtering using the displayName on the /groups endpoint. Team Id is nothing but the group id.
https://graph.microsoft.com/v1.0/groups?$filter=displayName eq 'Bgroup'
Result:

Microsoft graph calling/communication SDK not working with MediaSession

I am making calls to teams user using Graph Communication SDK with local machine.I am using ngork for making local machine endpoints public. I can make call to teams user without using MediaSession but when I use Media Session call is not reaching to teams user and it is not giving any error.Need help to find out issue.I am referring examples from this doc- https://github.com/microsoftgraph/microsoft-graph-comms-samples/tree/master/Samples/V1.0Samples/LocalMediaSamples
Working Call:
var mediaToPrefetch = new List<MediaInfo>();
var call = new Call()
{
Targets = new[] { target },
MediaConfig = new ServiceHostedMediaConfig { PreFetchMedia = mediaToPrefetch },
RequestedModalities = new List<Modality> { Modality.Audio, Modality.Video, Modality.VideoBasedScreenSharing },
TenantId = joinCallBody.TenantId,
};
var statefulCall = await this.Client.Calls().AddAsync(call, scenarioId: scenarioId).ConfigureAwait(false);
Non Working Call:
var mediaSession=this.CreateMediaSession();
var mediaToPrefetch = new List<MediaInfo>();
var call = new Call()
{
Targets = new[] { target },
MediaConfig = new ServiceHostedMediaConfig { PreFetchMedia = mediaToPrefetch },
RequestedModalities = new List<Modality> { Modality.Audio, Modality.Video, Modality.VideoBasedScreenSharing },
TenantId = joinCallBody.TenantId,
};
var statefulCall = await this.Client.Calls().AddAsync(call, scenarioId: scenarioId,mediaSession:mediaSession).ConfigureAwait(false);
Those samples refer to application-hosted media bots: https://learn.microsoft.com/en-us/microsoftteams/platform/bots/calls-and-meetings/requirements-considerations-application-hosted-media-bots
Did you follow all the steps to register the bot app? https://github.com/microsoftgraph/microsoft-graph-comms-samples/tree/master/Samples/V1.0Samples/LocalMediaSamples/PolicyRecordingBot#bot-registration
You need to explicitly add permissions to access media, and later to grant by an administrator of the azure account.
If you did all that, could you please share what kind of exception/error are you getting?

Programmatically adding SharePoint Library Teams Tab to Microsoft Teams Channel

I'm trying to add a SharePoint Library tab to a Microsoft Team Channel programmatically through the Microsoft Graph.
Here is the payload I'm sending through the Graph Explorer POST
{
"teamsAppId": "com.microsoft.teamspace.tab.files.sharepoint",
"name": "Documents3",
"sortOrderIndex": "10300",
"configuration": {
"siteUrl": "https://baywet.sharepoint.com/sites/customerhub",
"libraryServerRelativeUrl": "/sites/customerhub/Shared Documents",
"selectedDocumentLibraryTitle": "Documents",
"selectedSiteTitle": "customerhub",
"dateAdded": "2018-10-05T16:56:59.169Z"
}
}
I get a 201 status response, my tab is added to the channel. However whenever somebody tries to upload a file from the Teams UI, they get the following error message The File {filename} is missing. If they click on Open in SharePoint and then upload the file, it works.
If I compare with a tab created through the UI (which works properly) here is the description I get.
{
"id": "a68e34db-9d43-4821-953b-2dec938ce785",
"name": "Document%20Library",
"teamsAppId": "com.microsoft.teamspace.tab.files.sharepoint",
"sortOrderIndex": "10200",
"webUrl": "https://teams.microsoft.com/l/channel/19%3ab2e05a0aae42487485b13e088d5d2f0f%40thread.skype/tab%3a%3aa63916e6-f252-477d-9696-7934980e7e47?label=Document%2520Library&groupId=71ed6a2e-67ca-4930-a3c2-abb25ca29fbf&tenantId=bd4c6c31-c49c-4ab6-a0aa-742e07c20232",
"configuration": {
"entityId": null,
"contentUrl": null,
"removeUrl": null,
"websiteUrl": null,
"siteUrl": "https://baywet.sharepoint.com/sites/customerhub",
"libraryServerRelativeUrl": "/sites/customerhub/Shared Documents",
"libraryId": "706FAD5678484E7B93B0855E52A0BCD9",
"selectedDocumentLibraryTitle": "Documents",
"selectedSiteImageUrl": "https://baywet.sharepoint.com/sites/customerhub/_api/GroupService/GetGroupImage?id='f9d430ca-4de3-42f1-9474-1427bfdb16b0'&hash=636743460492415245",
"selectedSiteTitle": "customerhub",
"dateAdded": "2018-10-05T16:56:59.169Z"
}
}
The only difference being the libraryId configuration value. (you're not supposed to send in the webUrl and id).
This library id doesn't match the library id in SharePoint, or the drive item id in the Graph so my question is: what value am I supposed to set for the libraryId? Is there anything else I am missing?
The following code Creates the team for a known Group ID (365 that When created, created a team site) and adds 3 tabs on the existing channel.
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(GraphClientId)
.WithTenantId(GraphTenantId)
.WithClientSecret(GraphClientSecret)
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var team = new Team
{
MemberSettings = new TeamMemberSettings
{
AllowCreateUpdateChannels = true
},
MessagingSettings = new TeamMessagingSettings
{
AllowUserEditMessages = true,
AllowUserDeleteMessages = true
},
FunSettings = new TeamFunSettings
{
AllowGiphy = true,
GiphyContentRating = GiphyRatingType.Moderate
}
};
Team addedTeam = await graphClient.Groups[GroupID].Team
.Request()
.PutAsync(team);
ECGTeam ecgTeam = new ECGTeam {ProjectNumber= ProjectNumber ,GroupID = GroupID, TeamID = addedTeam.Id };
string channelID = string.Empty;
var channels = await graphClient.Teams[addedTeam.Id].Channels.Request().GetAsync();
channelID = channels[0].Id;
ecgTeam.ChannelID = channelID;
TeamsTab newTab = addTab(targetWebUrl, "WorkingPapers", "Working Papers");
var addedTab = await graphClient.Teams[addedTeam.Id].Channels[channelID].Tabs.Request().AddAsync(newTab);
ecgTeam.TabWorkingPapersID = addedTab.Id;
//DPC documents
newTab = addTab(targetWebUrl, "DPCdocuments", "DPC documents");
addedTab = await graphClient.Teams[addedTeam.Id].Channels[channelID].Tabs.Request().AddAsync(newTab);
ecgTeam.TabDPCdocumentsID=addedTab.Id;
//ContractDocuments //
newTab = addTab(targetWebUrl, "ContractDocuments", "Contract Documents");
addedTab = await graphClient.Teams[addedTeam.Id].Channels[channelID].Tabs.Request().AddAsync(newTab);
ecgTeam.TabContractDocumentsID = addedTab.Id;
//log.LogInformation(addedTab.Id);
Now, If you can help me create a Library for the said site that uses a custom content type, I will buy you coffee :-)
The wealth of good documentation for MS Graph in .NET Core makes me want to cry :-(
I found the solution a while after, sorry for not posting here earlier.
POST https://graph.microsoft.com/beta/teams/{groupId}/channels/{channelId}/tabs
{
"teamsApp#odata.bind": "https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/com.microsoft.teamspace.tab.files.sharepoint",
"name": "test",
"sortOrderIndex": "10400",
"configuration": {
"contentUrl": "https://baywet.sharepoint.com/sites/NYC/test"
}
}
Where contentUrl is the URL of the document library

Google API Calender v3 Event Insert via Service Account using Asp.Net MVC

I have been trying to insert a Google calendar event via Google service account that was created for an app in my dev console, but I am continually getting a helpless 404 response back on the Execute method. In the overview of the dev console I can see that the app is getting requests because there are instances of errors on the calendar.events.insert method. There is no information on what is failing. I need this process to use the Service account process instead of OAuth2 so as to not require authentication each time a calendar event needs to be created.
I have set up the service account, given the app a name, have the p12 file referenced in the project. I've also, gone into a personal calendar and have shared with the service account email address. Also, beyond the scope of this ticket, I have created a secondary app, through an administration account and have granted domain wide access to the service account only to receive the same helpless 404 error that this is now giving.
Error Message: Google.Apis.Requests.RequestError
Not Found [404]
Errors [Message[Not Found] Location[ - ] Reason[notFound] Domain[global]
Any help identifying a disconnect or error would be greatly appreciated.
var URL = #"https://www.googleapis.com/calendar/v3/calendars/testcalendarID.com/events";
string serviceAccountEmail = "createdserviceaccountemailaq#developer.gserviceaccount.com";
var path = Path.Combine(HttpRuntime.AppDomainAppPath, "Files/myFile.p12");
var certificate = new X509Certificate2(path, "notasecret",
X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { Google.Apis.Calendar.v3.CalendarService.Scope.Calendar },
}.FromCertificate(certificate));
BaseClientService.Initializer initializer = new
BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Test App"
};
Google.Apis.Calendar.v3.CalendarService calservice = new Google.Apis.Calendar.v3.CalendarService(initializer);
string timezone = System.TimeZone.CurrentTimeZone.StandardName;
var calendarEvent = new Event()
{
Reminders = new Event.RemindersData()
{
UseDefault = true
},
Summary = title,
Description = description,
Location = location,
Start = new EventDateTime()
{
//DateTimeRaw = "2014-12-24T10:00:00.000-07:00",
DateTime = startDateTime,
TimeZone = "America/Phoenix"
},
End = new EventDateTime()
{
//DateTimeRaw = "2014-12-24T11:00:00.000-08:00",
DateTime = endDateTime,
TimeZone = "America/Phoenix"
},
Attendees = new List<EventAttendee>()
{
new EventAttendee()
{
DisplayName = "Joe Shmo",
Email = "joeshmoemail#email.com",
Organizer = false,
Resource = false
}
}
};
var insertevent = calservice.Events.Insert(calendarEvent, URL);
var requestedInsert = insertevent.Execute();
I had the same problem. The solution was to add an email client, whose calendar event you want to send.
Credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = Scopes,
User = "example_client_email#gmail.com"
}.FromCertificate(certificate));
So I found out that for this to work, You need to make sure that you access the google.Admin account for referencing the service account Client ID of the app you created.
Another thing that helps is making sure the timezone is in the following format "America/Phoenix"
I have now successfully created events through the service account WITHOUT authentication.

Spreadsheets API Can not update a read-only feed

I'm trying to add new spreadsheet if it not exists with GData Spreadsheet API for .NET but it gives me following exception:
Can not update a read-only feed
Here's my code:
var service = new SpreadsheetsService("<my-app>");
service.setUserCredentials("<login>", "<password>");
// Instantiate a SpreadsheetQuery object to retrieve spreadsheets.
SpreadsheetQuery query = new SpreadsheetQuery();
var title = "test";
query.Title = title;
// Make a request to the API and get all spreadsheets.
SpreadsheetFeed feed = service.Query(query);
if (!feed.Entries.Any())
{
var worksheet = new WorksheetEntry(20, 20, title);
service.Insert(feed, worksheet);
}
Through Fiddler I see that I'm doing request to:
GET /feeds/spreadsheets/private/full?title=test
and it goes fine, but I don't see any requests for updating data. I suppose that I should change somehow SpreadsheetQuery to make it capable to write data, but I can't find how.
It's me being inattentive because google documentation on Spreadsheet API says:
It is possible to create a new spreadsheet by uploading a spreadsheet
file via the Google Drive API. The Spreadsheets API does not currently
provide a way to delete a spreadsheet, but this is also provided in
the Google Drive API. For testing purposes, you may create a
spreadsheet manually or upload one.
So I basically installed GoogleDrive API with Nuget. And then added following method for adding file:
private static void AddFile(string title)
{
var clientID = "put here a clientID";
var clientSecret = "put here a clientSecret";
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = clientID,
ClientSecret = clientSecret,
},
new[] { DriveService.Scope.Drive },
"here goes your account",
CancellationToken.None).Result;
// Create the service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Drive API Sample",
});
var body = new Google.Apis.Drive.v2.Data.File();
body.Title = title;
//body.Description = "A test document";
body.MimeType = "application/vnd.google-apps.spreadsheet";
service.Files.Insert(body).Execute();
}
When I run code above at the first time - I received an exception that said
Could not load file or assembly
'Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.16.0
I run these in Package Manager Console:
Uninstall-Package Microsoft.Bcl.Async -Force
Install-Package Microsoft.Bcl.Async
and it worked. Hope it would help somebody who will stumble over the same issue.

Resources