用图形创建团队后我是否必须等待

时间:2021-04-13 15:33:26

标签: c# azure microsoft-graph-api microsoft-teams microsoft-graph-teams

我正在使用来自我们 Web 应用程序的 MS Graph API 在客户的系统中创建一个 MS Teams 团队并设置一些文件夹。但是如果我在创建团队后不强加硬编码等待,我会随机得到错误。我按显示的顺序调用以下端点:

//Create new Team and get basic info
POST teams
GET teams/{team-id}/primaryChannel
GET teams/{team-id}
GET teams/{team-id}/channels/{channel-id}/filesFolder

//Sometimes unknown users must be invited to join org as guest
POST invitations

//Everyone but the owner is added as a guest
POST teams/{team-id}/members

//This is done in a batch, because there is one folder per team guest + one for owner
POST groups/{team-id}/drive/items/{channel-folder-id}/children

//Team members' folders are permitted to them only. So all permissions are deleted and a single user added back
GET groups/{folder-id}/drive/items/{folder-id}/permissions
DELETE groups/{team-id}/drive/items/{folder-id}/permissions/{permission-id}
POST groups/{folder-id}/drive/items/{item-id}/invite

我会偶尔收到来自以下方面的禁止和/或错误请求响应:

POST teams/{team-id}/members
DELETE - groups/{team-id}/drive/items/{item-id}/permissions/{permission-id}

显然 403 的返回状态是错误,因为应用程序肯定有权执行该操作。

在创建团队后强制等待 60 秒似乎可以解决此问题。但是,我目前正在我们的 Teams 环境中进行测试,并且担心具有较大 Teams 设置的客户需要更长的等待时间。我在其他地方看到文档说你应该等待最多 15 分钟才能使用从组创建的团队(但我不确定这是否适用于创建普通团队)。

有谁知道我一般应该为什么样的延迟做好准备,如果有任何端点我可以 ping 看看团队是否可以使用?

2 个答案:

答案 0 :(得分:1)

我在我身边进行了测试,并遇到了与您相同的问题。 403错误应该是你提到的一个bug,因为我也有操作的权限。但是您提到将访客用户添加到所有者,我用糟糕的请求响应对其进行了测试,我认为这是设计使然。

由于您可以在等待 60 秒后请求成功,因此我认为解决方案是在您的代码中添加一个 while 循环以多次请求图形 API。在 while 循环中,如果请求失败,则等待 10 秒然后再次请求(如评论中提到的 Flydog57)。但是你还需要在你的代码中添加一个当请求总是失败时中断循环的机制,以避免无限循环。

答案 1 :(得分:1)

Azure AD、Teams 和 Exchange 都是不同的系统,需要某种有时需要一些时间的同步。

每当您要在其中一个系统中创建某些内容时,请准备好访问它需要一些时间。

我遇到的最尴尬的行为之一是,当您通过 Exchange Remote Powershell 创建组时,您将立即返回组对象。此对象具有 Azure 对象 ID。但是,如果您立即转到 Graph 并为该组发出请求,您将收到 404。此外,查看 Azure 门户也未显示任何内容。但是,如果您等待一段时间(最少 30 秒,最多 20 分钟),该组会突然出现。

如果您通过 Graph 在 Azure 中创建用户,这同样适用。如果你这样做,你会得到一个带有 azure id 的对象。如果您立即尝试将此用户添加到组或目录角色,也可能会出现错误,但此处的超时通常低于 2 秒,而我从未见过超过 10 秒的内容。

因此,对于我将在 Graph 中创建一些内容并立即尝试使用它的所有内容,我构建了一些辅助方法,该方法会尝试多次,每次调用之间的超时时间较短:

internal static class Multiple
{
    public static Task Try<TException>(int maxRetries, TimeSpan interval, Func<Task> task)
        where TException : Exception
    {
        return Try<TException>(maxRetries, interval, task, exception => true);
    }

    public static async Task Try<TException>(int maxRetries, TimeSpan interval, Func<Task> task, Func<TException, bool> isExpectedException)
        where TException : Exception
    {
        do
        {
            try
            {
                await task().ConfigureAwait(false);
                return;
            }
            catch (Exception ex) when (ex.GetType() == typeof(TException) && isExpectedException((TException)ex))
            {
                maxRetries--;

                if (maxRetries <= 0)
                    throw;

                await Task.Delay(interval);
            }
        } while (true);
    }
}

类的用法如下:

await Multiple.Try<ServiceException>(20, TimeSpan.FromSeconds(1), async () =>
{
    educationClass = await serviceClient.Education.Classes[groupId.ToString()].Request().GetAsync();
}, ex => ex.Error.Code == "Request_ResourceNotFound");

这个助手将调用内部方法最多 20 次,超时时间为 1 秒。此外,抛出的异常必须具有给定的错误代码。如果超过重试次数或抛出不同的错误,调用将重新抛出原始异常,必须在更高级别上处理。

请注意,Graph 接口背后是一个高度分布式的系统,它有时需要一些时间才能使所有内容同步。