寻求家长同意
如果 /age-gate/check
的 status
字段返回 CHALLENGE
值,响应中的 challengeId
字段包含 k-ID 引擎中 Consent Challenge
的 ID。此时应显示一个窗口,允许玩家寻求家长同意。
同意挑战
同意挑战代表玩家请求家长同意的过程。关于同意挑战的更多信息会从 /age-gate/check
API 返回。
/age-gate/check
API 返回一个一次性密码(OTP),家长可以通过浏览 https://k-id.com/code 输入该密码,还会返回一个可以渲染为二维码的 URL。同意挑战窗口应显示二维码和一次性密码,以及一个输入框,允许玩家输入可以授予同意的家长或监护人的电子邮件地址。
显示同意挑战窗口后,游戏应定期调用 /challenge/await
API,使用从 /age-gate/check
响应中返回的挑战 ID。家长将在家庭门户中收到同意请求,可以通过电子邮件、二维码或通过窗口中显示的 URL 输入代码来批准同意。根据传入的超时参数值,请求将在最多 180 秒后超时。还可以传入 0 秒的超时值,这不会阻塞并返回当前 的挑战状态。调用返回后,如果挑战仍在处理中,后续调用中的响应状态字段将返回 POLL_TIMEOUT
。如果同意通过 k-ID 家长门户获得,调用将返回状态 PASS
,如果请求被拒绝,则返回 FAIL
。
如果家长或监护人使用二维码或一次性密码在 k-ID 家长门户中授予了同意,则游戏工作流程中无需执行其他操作。如果玩家提供了家长或监护人的电子邮件地址,则游戏应将该电子邮件地址作为参数传递给 /challenge/email
API,系统将向该地址发送预配置的电子邮件,邮件中包含一个链接,家长可以通过该链接进入家庭门户并批准同意。电子邮件的配置选项可以在发布者门户中设置。
void UKidWorkflow::CheckForConsent(const FString& ChallengeId, FDateTime StartTime, int32 Timeout,
TFunction<void(bool, const FString &)> OnConsentGranted)
{
const int ChallengeAwaitTimeout = 0;
FString Url = FString::Printf(TEXT("%s/challenge/await?challengeId=%s&timeout=%d"),
*BaseUrl, *ChallengeId, ChallengeAwaitTimeout);
HttpRequestHelper::GetRequestWithAuth(Url, AuthToken,
[this, ChallengeId, StartTime, Timeout, OnConsentGranted]
(FHttpResponsePtr Response, bool bWasSuccessful)
{
bool bConsentGranted = false;
if (bWasSuccessful && Response.IsValid())
{
TSharedPtr<FJsonObject> JsonResponse;
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(Response->GetContentAsString());
if (FJsonSerializer::Deserialize(Reader, JsonResponse))
{
FString Status = JsonResponse->GetStringField(TEXT("status"));
if (Status == TEXT("PASS"))
{
FString SessionId = JsonResponse->GetStringField(TEXT("sessionId"));
FString ApproverEmail = JsonResponse->GetStringField(TEXT("approverEmail"));
// At this point, the player has been granted consent and
// the email of the parent or guardian who granted consent is available
// in the approverEmail field. This can be used for customer service
// requests later.
//
StoreParentEmailForLaterUse(SessionId, ApproverEmail);
OnConsentGranted(true, SessionId);
return;
}
else if (Status == TEXT("FAIL"))
{
OnConsentGranted(false, TEXT(""));
return;
}
}
FDateTime CurrentTime = FDateTime::UtcNow();
FTimespan ElapsedTime = CurrentTime - StartTime;
// Retry if the elapsed time is less than the overall timeout
if (ElapsedTime.GetTotalSeconds() < Timeout)
{
GetWorld()->GetTimerManager().SetTimer(ConsentPollingTimerHandle, [this, ChallengeId, StartTime, Timeout, OnConsentGranted]()
{
CheckForConsent(ChallengeId, StartTime, Timeout, OnConsentGranted);
}, ConsentPollingInterval, false);
}
else
{
OnConsentGranted(false, TEXT(""));
}
}
else
{
OnConsentGranted(false, TEXT(""));
}
});
}
玩家在等待同意期间可以做什么?
对于某些游戏,在家长授予同意之前,玩家应完全停止继续游戏,并且窗口应为模态。在其他游戏中,可能允许未成年玩家在请求家长同意的同时继续玩一段时间,然后再被拒绝访问。在这种情况下,等待家长同意期间,游戏有责任避免收集玩家数据,或禁止访问其他可能需要同意的功能。
待处理的同意挑战
当 /age-gate/check
API 返回 CHALLENGE
状态时,返回的挑战 ID 应存储在本地存储中,直到挑战处于活动状态。当游戏启动时,如果存在活动的挑战,游戏应再次显示之前的同意挑战窗口。在从本地存储中检索挑战 ID 后,应调用 /challenge/get
API 以检索当前挑战的信息,包括一次性密码和二维码 URL,并再次向用户显示挑战窗口。
等待家长响应的时长
游戏必须确定等待同意授予的时间长度以及如果该时间过期应该如何处理。等待时长可以较短(10 分钟)或较长(24 小时或更长)。在此期间,可能会多次调用 /challenge/await
API。每次调用 /challenge/await
之间至少应有 5 秒的间隔。此外,/challenge/await
可能会返回 HTTP 代码 429,并在 HTTP 响应中带有 Retry-After
头。游戏在进行 k-ID API 调用时应始终检查此头。
同意挑战的过期
同意挑战应在 7 天后过期。
获取家长的电子邮件地址
如果同意被授予,并且 /challenge/await
在 status
字段中返回 PASS
,则家长的电子邮 件地址会在 approverEmail
字段中返回。游戏可以将此信息存储起来,以备将来客户服务时使用。
测试家长同意
可以在不经过家庭门户的家长同意流程的情况下测试 API 中的家长同意。为此,您可以调用 /test/set-challenge-status
来设置同意挑战的状态。您可以将状态设置为 PASS
或 FAIL
。您还必须在请求体中传递 age
和 jurisdiction
。可选地,您可以传递一个电子邮件地址,该地址将返回在 approverEmail
字段中。下一次使用相同的 challengeId
调用 challenge/await
时,将返回您分配的信息。这使您能够快速测试游戏中的家长同意场景。