2

我正在尝试使用 Microsoft Graph 创建 Microsoft 团队站点的完整克隆,方法是对团队站点进行基本克隆,然后使用 API 复制和配置所有内容。

我的第一个任务是复制 Planner。我已经复制了所有可用的计划、存储桶和任务。

我的问题是我无法弄清楚:

1)该计划属于旧团队中的哪个选项卡/位置

2)如何将新计划放入新团队中的所述选项卡/位置

public async Task<IEnumerable<Channel>> GetChannels(string accessToken, string teamId) {

    string endpoint = $"{GraphRootUri}/teams/{teamId}/channels";
    HttpResponseMessage response =
        await ServiceHelper.SendRequest(HttpMethod.Get, endpoint, accessToken); //old functionality of stolen method - ignore these two lines

    string destinationTeamID = "Teamid";

    //find all plans
    endpoint = $"{GraphRootUri}/groups/{teamId}/planner/plans";
    HttpResponseMessage responsePlans = await ServiceHelper.SendRequest(HttpMethod.Get, endpoint, accessToken);
    var plansIn = await ParseList<Planner>(responsePlans);

    //the following two sections are just me seeing if I can find references to the plans
    endpoint = $"{GraphRootUri}/teams/{teamId}/channels";
    HttpResponseMessage responseChannels = await ServiceHelper.SendRequest(HttpMethod.Get, endpoint, accessToken);
    var inChannels = await responseChannels.Content.ReadAsStringAsync();

    endpoint = $"{GraphRootUri}/teams/{teamId}/channels/mychannellocation/tabs";
    HttpResponseMessage responseTabs = await ServiceHelper.SendRequest(HttpMethod.Get, endpoint, accessToken);
    var inTabs = await responseTabs.Content.ReadAsStringAsync();

    //the following code copies the plans, buckets and tasks
    foreach (Planner plan in plansIn) {

        //first we get everything from the previous team plan

        //grab tasks from the previous plan
        endpoint = $"{GraphRootUri}/planner/plans/{plan.id}/tasks";
        HttpResponseMessage responseTasks = await ServiceHelper.SendRequest(HttpMethod.Get, endpoint, accessToken);
        var inTasks = await ParseList<plannerTask>(responseTasks);

        //get all buckets
        endpoint = $"{GraphRootUri}/planner/plans/{plan.id}/buckets";
        HttpResponseMessage responseBuckets = await ServiceHelper.SendRequest(HttpMethod.Get, endpoint, accessToken);
        var inBuckets = await ParseList<plannerBucket>(responseBuckets);

        endpoint = $"{GraphRootUri}/planner/tasks";
        //HttpResponseMessage responseTasks = await ServiceHelper.SendRequest(HttpMethod.Get, endpoint, accessToken);
        //  .content .Deserialize<plannerPlan>(); ;

        //then we start to create everything in the new team
        //create the plan in the new team
        endpoint = $"{GraphRootUri}/planner/plans";
        var sendPlanResponse =
            await ServiceHelper.SendRequest(HttpMethod.Post, endpoint, accessToken, new plannerStub(plan, destinationTeamID));
        var newPlanString = await sendPlanResponse.Content.ReadAsStringAsync();
        //get the created plan
        var newPlan = JsonConvert.DeserializeObject<Planner>(newPlanString);

        //create buckets in the new team
        Dictionary<string, string> bucketIdMap = new Dictionary<string, string>();
        foreach (plannerBucket bucket in inBuckets) {
            endpoint = $"{GraphRootUri}/planner/buckets";
            var outBucket = new plannerBucketStub(bucket, newPlan.id);
            var sendBucketResponse =
                await ServiceHelper.SendRequest(HttpMethod.Post, endpoint, accessToken, new plannerStub(plan, destinationTeamID));
            //get the created Bucket
            var newBucket = JsonConvert.DeserializeObject<plannerBucket>(await sendPlanResponse.Content.ReadAsStringAsync());
            bucketIdMap[bucket.id] = newBucket.id; //so we can send the tasks to our new bucket

        }

        //create tasks in the new team
        foreach (plannerTask task in inTasks) {
            endpoint = $"{GraphRootUri}/planner/tasks";
            task.bucketId = bucketIdMap[task.bucketId];
            task.planId = newPlan.id;
            var sendBucketResponse = await ServiceHelper.SendRequest(HttpMethod.Post, endpoint, accessToken, task);

        }

        //put planner in appropriate tab - stuck at this point
        endpoint = $"{GraphRootUri}/teams/{newPlan.id}/channels/";

    }
}

之前的代码是我目前所拥有的,有谁知道我怎样才能找到旧规划师的住所以及如何将新规划师放在新团队的同一个地方?

现在的目标球队是第一支球队的克隆。

我最好的猜测是使用规划器的“上下文”,但我找不到任何关于此的文档。有谁知道如何解决这个问题?编辑。我试过使用上下文没有效果,我正式迷路了。

顺便说一句,如果有人找到了一个完整克隆 Microsoft Teams 站点的代码存储库,我太厚了找不到,请告诉我

对于给我的问题足够时间阅读本文的任何人,非常感谢您的帮助,此时任何建议将不胜感激。

4

2 回答 2

1

在 Teams 和 Planner 集成中,指向计划的链接由 Teams 维护,因此最好的办法是查看那里,看看是否可以在某处找到计划 ID。不幸的是,我不熟悉这些 API。

在 Planner 上,有两个可选属性可帮助导航回 Teams。首先是 Plan 的上下文,其中包含“displayNameSegments”属性。这应该与团队/频道名称结构相匹配。第二个是 PlanDetails 上的 contextDetails,其中包含团队的 URL。这些属性仅在测试版中可用。它们不能保证被填写,并且它们可能不准确。

于 2019-02-04T06:53:20.237 回答
1

查找标签位置

您可以通过解析返回的结果来检测 Channel Tab 的位置/v1.0/teams/{group-id}/channels/{channel-id}/tabs。结果teamsTab数组将以相反的顺序包含选项卡(第一个选项卡最后):

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#teams('{{id}}')/channels('{id}')/tabs",
  "value": [
    {
      "id": "{id}",
      "displayName": "Tab #2",
      "webUrl": "{url}",
      "configuration": {
        "entityId": null,
        "contentUrl": null,
        "removeUrl": null,
        "websiteUrl": null,
        "wikiTabId": 1,
        "wikiDefaultTab": true,
        "hasContent": false
      }
    },
    {
      "id": "{id}",
      "displayName": "Tab #1",
      "webUrl": "{url}",
      "configuration": {
        "entityId": "{plan-id}",
        "contentUrl": "{url}",
        "removeUrl": "{url}",
        "websiteUrl": "{url}",
        "dateAdded": "2019-02-04T17:38:11.079Z"
      }
    }
  ]
}

请记住,对话和文件实际上不是选项卡,它们的位置是固定的。因此,两者都不会出现在/tabs结果中。您的代码应该假定您的标签顺序实际上从 UI 中的第三个标签位置开始。

设置制表位

为了复制固定选项卡的顺序,您需要按照您想要的顺序添加选项卡。如果您需要重新排序现有选项卡,您需要先删除它们,然后按照您想要的顺序重新创建它们。

于 2019-02-04T18:03:10.083 回答