Office 365 Groups and
Tasks API - Getting Started
DRAGAN PANJKOVCONSULTANT, K2 NE, GERMANY
MVP (OFFICE SERVERS AND SERVICES)
www.dragan-panjkov.com
DRAGAN PANJKOV
Microsoft MVP – Office Servers and Services
Working with SharePoint since 2007
Speaking at community events since 2008
Speaking at conferences since 2009
Consultant at K2 NE (www.k2.com)
Previously: PlanB.; Microsoft; Lanaco
Website and blog: www.dragan-panjkov.com
Twitter: @panjkov
Key benefits of Groups
• Single definition
• Public by default
• Sharing to non-members
• Self-service
• Context and history
• Simple to manage
Microsoft Graph API
https://graph.microsoft.com/
USERS FILES MAIL CALENDARGROUPS
Insights and relationships from Microsoft Graph
TASKS
Building your app
Register app in Azure portalNative
Web app
Single page app
Configure app permissionsGroups.Read.All
Groups.ReadWrite.All
Get token using OAuth2.0 flow
Use OpenID Connect for SSO
Build your code using Microsoft Graph
Provisioning Groups
var g = new Group {
DisplayName = "My Group",
MailNickname = "MyGroup",
SecurityEnabled = false,
MailEnabled = true,
Description = "A nice group",
GroupTypes = new[] { "Unified" },
};
g = await graphService.Groups.Request().AddAsync(g);
Access data across Office 365 and Microsoft at one single endpoint
Read and write to the Tasks API at:
https://graph.microsoft.com/beta/groups/<id>/plans
https://graph.microsoft.com/beta/plans/<id>/tasks
https://graph.microsoft.com/beta/me/tasks
Retrieve $metadata document at:
https://graph.microsoft.com/beta/$metadata
Supports multiple OAuth 2.0 flows
Use common HTTP verbs like GET/POST/PATCH/DELETE
Plan
Owns
Contains
Planner Tasks API (Beta)
Microsoft Graph for Plans
and Tasks
Microsoft GraphPlans
Tasks
Microsoft Graph accessible through RESThttps://graph.microsoft.com/beta/me/plans
https://graph.microsoft.com/beta/me/tasks
https://graph.microsoft.com/beta/plans/<planId>/tasks
General Plan Notes
When you create an Office 365 Group a plan is created automatically
This process can take up to 48 hours to complete
The plan in an Office 365 Group is named the same as the Office 365 Group and you cannot modify the name
Only one plan can exist in an Office 365 Group
1 Overview
Microsoft Graph
https://graph.microsoft.com/beta/plans
https://graph.microsoft.com/beta/plans/{plan_id}
https://graph.microsoft.com/beta/plans/{plan_id}/tasks
https://graph.microsoft.com/beta/tasks/{task_id}
HTTP GET request to collection or entity endpoint
Microsoft Graph only returns JSON responsespublic async Task<List<MyPlan>> GetPlans(){
var plansResult = new List<MyPlan>();var accessToken = await GetGraphAccessTokenAsync();var restURL = string.Format("{0}me/plans/", SettingsHelper.GraphResourceUrl);try{
using (HttpClient client = new HttpClient()){
var accept = "application/json";client.DefaultRequestHeaders.Add("Accept", accept);client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
using (var response = await client.GetAsync(restURL)){
if (response.IsSuccessStatusCode){
var jsonresult = JObject.Parse(await response.Content.ReadAsStringAsync());
foreach (var item in jsonresult["value"]){
plansResult.Add(new MyPlan{
//TO DO});
}}
}}
}catch (Exception el){
el.ToString();}return plansResult;
}
public async Task<List<MyTask>> GetTasks(string planid){
var tasksResult = new List<MyTask>();var accessToken = await GetGraphAccessTokenAsync();var restURL = string.Format("{0}plans/{1}/tasks", SettingsHelper.GraphResourceUrl, planid);try{
using (HttpClient client = new HttpClient()){
var accept = "application/json";
client.DefaultRequestHeaders.Add("Accept", accept);client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
using (var response = await client.GetAsync(restURL)){
if (response.IsSuccessStatusCode){
var jsonresult = JObject.Parse(await response.Content.ReadAsStringAsync());
foreach (var item in jsonresult["value"]){
tasksResult.Add(new MyTask{
id = item["id"].ToString(),title = item["title"].ToString(),percentComplete = !string.IsNullOrEmpty(item["percentComplete"].ToString()) ? Convert.ToInt32(item["percentComplete"].ToString()) : 0,planId = planid,Etag = !string.IsNullOrEmpty(item["@odata.etag"].ToString()) ? item["@odata.etag"].ToString() : ""
});}
}}
}}catch (Exception el){
el.ToString();}
return tasksResult;}
HTTP POST to collection endpoint to add an entity
private async Task CreatePlan(MyPlan myPlan, string groupId){
var accessToken = await GetGraphAccessTokenAsync();var restURL = string.Format("{0}plans/", SettingsHelper.GraphResourceUrl);dynamic postPlanJSON = new JObject();postPlanJSON.title = myPlan.title;postPlanJSON.owner = groupId;
try{
using (HttpClient client = new HttpClient()){
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var requestMessage = new HttpRequestMessage(HttpMethod.Post, restURL);requestMessage.Content = new StringContent(postPlanJSON.ToString(), System.Text.Encoding.UTF8, "application/json");using (var response = await client.SendAsync(requestMessage)){
if (response.IsSuccessStatusCode)return;
elsethrow new Exception("add plan error: " + response.StatusCode);
}}
}catch (Exception el){
el.ToString();}
}
HTTP POST to collection endpoint to add an entitypublic async Task CreateTask(MyTask myTask){
var accessToken = await GetGraphAccessTokenAsync();var restURL = string.Format("{0}/tasks", SettingsHelper.GraphResourceUrl);dynamic postTaskJSON = new JObject();postTaskJSON.title = myTask.title;postTaskJSON.percentComplete = myTask.percentComplete;postTaskJSON.planId = myTask.planId;try{
using (HttpClient client = new HttpClient()){
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var requestMessage = new HttpRequestMessage(HttpMethod.Post, restURL);requestMessage.Content = new StringContent(postTaskJSON.ToString(), System.Text.Encoding.UTF8, "application/json");using (var response = await client.SendAsync(requestMessage)){
if (response.IsSuccessStatusCode)return;
elsethrow new Exception("add task error: " + response.StatusCode);
}}
}catch (Exception el){
el.ToString();}
}
Plans can only be deleted by their owners
Authenticate with the plan owner to delete a plan
The plan in an Office 365 Group is created when you create an Office 365 group
Plans in Office 365 Groups are owned by the Office 365 Group itself
An Office 365 Group owner does not own the plans in an Office 365 Group
You cannot authenticate as an Office 365 Group, so it is not possible to delete a plan owned by an Office 365 Group
HTTP DELETE to specific entity endpointpublic async Task DeleteTask(string id, string eTag){
var accessToken = await GetGraphAccessTokenAsync();var restURL = string.Format("{0}tasks/{1}", SettingsHelper.GraphResourceUrl, id);try{
using (HttpClient client = new HttpClient()){
var accept = "application/json";
client.DefaultRequestHeaders.Add("Accept", accept);client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);client.DefaultRequestHeaders.Add("If-Match", eTag);
using (var response = await client.DeleteAsync(restURL)){
if (response.IsSuccessStatusCode)return;
elsethrow new Exception("delete task error: " + response.StatusCode);
}}
}catch (Exception el){
el.ToString();}
}
Top Related