# Analytics REST API

> Send Analytics events from non-Unity games through the REST API.

不使用 Unity 的开发者可以通过 Web 终端或 REST API 访问 API。REST API 提供更大的灵活性，让您可以利用喜欢的语言和游戏开发引擎来自动执行工作流程。

Analytics 提供以下 REST API：

* [Analytics](https://services.docs.unity.com/analytics/v1)

## 最佳实践

### 生成随机且具有唯一性的 userID

REST API 提供以下方法来生成随机且具有唯一性的 userID：

`https://collect.analytics.unity3d.com/api/analytics/collect/v1/uuid`

请参阅[此处](https://services.docs.unity.com/analytics/v1#/paths/~1api~1analytics~1collect~1v1~1uuid/get)的 API 文档。

userID 是用户唯一的 ID。如果您正在使用 Unity Gaming Services（Unity 游戏服务）或其他在用户生命周期开始时生成 userID 的解决方案，请使用该 userID 发送到 Analytics REST API。如果您在游戏中没有自己的 userID，建议生成通用唯一标识符 (UUID) 来创建一个。您需要将返回的值存储在客户端本地，并将其重复用于来自该特定客户端的所有未来 Collect 调用。**不要更改**您所使用的内容。

拥有 ID 后，即可通过此值来标识用户。但是，可能会有法律限制或许可限制禁止将明显的 userID 存储在第三方。解决这种问题的变通方法通常是创建此 ID 的哈希并将其用作集成 userID；这样可以避免需要再次存储 userID。

### 将事件提交到 Collect API 终端

如果无法通过 SDK 发送事件（例如，从游戏服务器发送的事件，或非 Unity 游戏的事件），则 Collect REST API 会记录事件并将其直接发送到 Unity。

`https://collect.analytics.unity3d.com/api/analytics/collect/v1/projects/{projectId}/environments/{environmentName}`

请参阅[此处](https://services.docs.unity.com/analytics/v1#/paths/~1api~1analytics~1collect~1v1~1projects~1%5C%7BprojectId%5C%7D~1environments~1%5C%7BenvironmentName%5C%7D/post)提供的 API 文档。

要记录事件，请对 Collect API 执行 HTTP POST 以记录事件。此 POST 应采用 UTF-8 编码。请将 HTTP 请求标头设置为 `Content-Type: application/json`，并使用以下 URL 格式之一：

要获取环境名称，请转到项目的 **Dashboard（后台）> Projects（项目）> Project Settings（项目设置）> Environments（环境）**。

每个环境可以配置一组自定义事件。在请求正文中，指定与事件类型对应的 JSON 文档，如下文所述。

如果状态代码为 **204 No Content（204 无内容）**，表示服务器已成功接收事件，但服务器不想发回任何内容。

如果状态代码是 204 No Content（204 无内容）之外的任何其他代码，表示处理请求时出错。状态代码和消息将描述遇到的问题，例如：**400 Bad Request –“Custom Event Code not recognized”（400 错误请求 –“无法识别自定义事件代码”）**。请查看[此处](https://services.docs.unity.com/analytics/v1/index.html#/paths/~1api~1analytics~1collect~1v1~1projects~1%7BprojectId%7D~1environments~1%7BenvironmentName%7D/post)的详细信息。

要验证事件是否已由我们的服务处理，请参阅 [Event Browser（事件浏览器）](../events/event-browser)以查看来自您游戏的事件。

### 事件有效负载

所有事件都应在请求正文中以 JSON 文档的形式发送到服务器。每个事件类型的文档都不同。

Collect 终端接受两种格式：

1. 单一事件格式
2. 批量事件格式

#### 1.单一事件格式

```cs
{
    "eventName": "specific event code - eg. gameStarted",
    "userID": "ABCD1-4321a879b185fcb9c6ca27abc5387e914",
    "unityInstallationID": "Optional-Installation-ID",
    "unityPlayerID": "Optional-Authenticated-Player-ID",
    "sessionID": "4879bf37-8566-46ce-9f3b-bd18d6ac614e",
    "eventUUID": "374cc674-9785-4772-8cca-d7cdf517a590",
    "eventTimestamp": "yyyy-mm-dd hh:mm:ss.SSS",
    "eventParams": {
        "platform": "WEB",
        "param1": "stringParam",
        "param2": true,
        "param3": 1234,
        "param4": [
            "a",
            "b",
            "c"
        ]
    }
}
```

不需要的参数不必包含在文档中，应忽略它们，而不是发送空参数或 null 参数。**任何时间戳早于 31 天或晚于未来 24 小时的事件都将被拒绝，因为它们超出了有效边界**。

#### 2.批量事件格式

您可以在单次 POST 中发送多个事件。由于连接池具有高效率，因此这是一种较好的做法。应将 POST 长度保持在 5MB 以下；超出此长度的所有内容都可能被拒绝。

每个事件的格式保持不变，但以包含各个事件的 **eventList** 数组进行表示。例如：

```cs
{
  "eventList": [
    {
      "eventName": "clientDevice",
      "userID": "e44db226-5b29-11ec-819e-dca6325ca17a",
      "sessionID": "8ebb023e-6edc-11ec-a519-dca6325ca17a",
      "eventUUID": "02ff8461-8d1d-46bb-94f3-51c81e63b371",
      "eventVersion": 1,
      "eventTimestamp": "2022-01-06 03:29:17.030",
	  "eventParams": {
        "platform": "ANDROID",
        "userCountry": "US",
        "clientVersion": "2.0.3",
        "sdkMethod": "com.unity.services.analytics.Events.Startup"
      }
    },
    {
      "eventName": "gameStarted",
      "userID": "e44db226-5b29-11ec-819e-dca6325ca17a",
      "sessionID": "8ebb023e-6edc-11ec-a519-dca6325ca17a",
      "eventUUID": "a379af6c-4fac-4449-b6c7-925ee87b446e",
      "eventVersion": 1,
      "eventTimestamp": "2022-01-06 03:29:17.040",
      "eventParams": {
        "platform": "ANDROID",
        "userCountry": "US",
        "clientVersion": "2.0.3",
        "sdkMethod": "com.unity.services.analytics.Events.Startup",
        "userLocale": "en_US"
      }
    }
  ]
}
```

注意：批量事件列表中的事件应按其发生的顺序排列。

### 发送 ddnaForgetMe 事件

ddnaForgetMe 事件用于记录玩家请求退出数据收集并删除其数据。UGS Analytics 在收到有效负载后的七天内删除玩家数据。

如果您使用 REST API，但没有自己的 UUID 生成器，则可以使用我们提供的 UUID 生成功能。

如果您发送了此事件，您还必须停止发送用户的数据，否则服务将再次收集用户的数据。

```cs
{
     "eventName": "ddnaForgetMe",
     "eventTimestamp": "2020-01-01 12:00:00",
     "eventUUID": "foo",
     "eventVersion": 1,
     "sessionID": "foo",
     "userID": "foo",
     "eventParams": {
          "clientVersion": "foo",
          "sdkMethod": "foo"
     }
}
```

## 发送 PIPL 同意

中国新的数据隐私法《个人信息保护法》于 2021 年 11 月 1 日生效。个人信息是指可以识别个人身份（例如姓名或地址）并以电子或其他方式存储的数据。敏感的个人信息是指生物特征、性别认同、宗教信仰、病史、财务状况以及十四周岁以下未成年人的任何个人信息。

PIPL 是一项**基于“未明确同意就是拒绝”原则的法规**。我们的 Collect 终端使用 HTTP 标头来标识位于中国的用户的同意状态。

应在适当的情况下对要收集的所有 HTTP 请求使用以下标头：

| 标头            | 描述                                                          |
| ------------- | ----------------------------------------------------------- |
| PIPL\_CONSENT | 此标头的存在将表明玩家已同意数据收集。  不同意的玩家不应在请求中设置此标头。标头的值无关紧要。            |
| PIPL\_EXPORT  | 此标头的存在将表明玩家已同意将其数据发送到中国境外进行处理。  不同意的玩家不应在请求中设置此标头。标头的值无关紧要。 |

响应标头

任何符合 PIPL 要求的 HTTP 请求都应在响应中包含 PIPL\_STATUS 标头，以便通过确认后端采取的操作来帮助进行测试。

| 标头值         | 描述                                  |
| ----------- | ----------------------------------- |
| no\_consent | 指示未通过 PIPL\_CONSENT 请求标头对此请求给予同意。   |
| no\_export  | 指示对于此请求未同意通过 PIPL\_EXPORT 请求标头导出数据。 |

示例代码：

```cs
curl -v --location --request POST "https://collect.analytics.unity3d.com/collect/api/project/{id}/production" \
--header 'Content-Type: application/json' \
--header 'PIPL_CONSENT: true' \
--header 'PIPL_EXPORT: true' \
--data-raw "{
    \"userID\": \"some-id\",
    \"eventName\": \"gameStarted\",
    \"eventVersion\": 1,
    \"eventUUID\":\"some-uuid\",
    \"sessionID\": \"sessionID\",
    \"eventParams\": {
      \"platform\": \"ANDROID\",
      \"clientVersion\": \"testVersion\",
      \"sdkMethod\": \"UA1_SDKLESS\",
      \"userLocale\": \"aa_BB\"
      }
    }
}"
```
