使用 Graph 创建团队后是否需要等待

Should I Have to Wait After Creating Team with Graph

我正在使用我们网络应用程序中的 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

我偶尔会收到来自以下的 Forbidden and/or Bad Request 回复:

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

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

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

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

我在我这边测试过,遇到了和你一样的问题。 403错误应该是你说的bug,因为我也有操作的权限。但是您提到将来宾用户添加到所有者,我用错误的请求响应对其进行了测试,我认为这是设计使然。

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

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);
    }
}

class的用法如下:

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 界面背后是一个高度分布式的系统,有时需要一些时间才能使所有内容同步。