# 플레이어 데이터 수집

Pushwoosh는 플레이어가 누구이며 게임에서 무엇을 하는지 알아야 합니다. 이벤트는 행동을 기록하고, 태그는 각 플레이어의 현재 상태를 보관합니다.

<Aside type="tip" title="AI Assistant에게 이벤트와 태그 생성 맡기기">
[AI Assistant](/ko/product/pushwoosh-ai/ai-assistant/)는 이 페이지의 이벤트와 태그를 애플리케이션에 생성할 수 있습니다. 이 페이지 링크를 보내고 태그를 User-specific으로 만들어 달라고 요청하세요. 각 변경 사항을 승인하기 전에 확인하세요.
</Aside>

<span id="identify-players-by-user-id" />

## User ID로 플레이어 식별하기

<Aside type="caution" icon="setting" title="개발자 지원 필요">
User ID 설정은 게임 코드를 변경하는 작업입니다. [User ID 수집](/ko/developer/first-steps/collecting-user-ids/#setuserid-sdk-method)을 개발자와 공유하세요.
</Aside>

Pushwoosh는 플레이어의 모든 디바이스를 하나의 User ID에 연결하므로, 세그먼트와 Journey는 한 사람을 한 명의 플레이어로 취급합니다. 플레이어가 로그인하기 전에 디바이스가 기록한 이벤트와 User-specific 태그는 이전 ID에 그대로 남습니다. Device-specific 태그는 디바이스와 함께 이동합니다.

기본적으로 Pushwoosh는 각 디바이스의 하드웨어 ID(HWID)를 해당 디바이스의 User ID로 사용합니다. 이 경우 두 디바이스에서 플레이하는 한 명의 플레이어가 두 명으로 집계됩니다. 로그인하는 플레이어에서 이를 방지하려면 자체 계정 ID를 해당 플레이어의 User ID로 설정하세요.

1. 사용할 ID를 선택합니다. 게임이 이미 각 플레이어에게 부여하는 계정 ID를 사용하세요.
2. 플레이어가 로그인할 때 이 ID로 `setUserId`를 호출하도록 개발자에게 요청합니다.
3. 결과를 확인합니다. 테스트 디바이스에서 게임에 로그인한 다음, **오디언스** → **사용자 탐색기**를 열고 **사용자 ID**로 검색해 계정 ID를 입력합니다. 플레이어의 프로필이 열립니다.

로그인하지 않는 플레이어는 HWID를 User ID로 유지하며, Pushwoosh가 이를 대신 설정합니다.

User ID와 디바이스의 관계에 대해 자세히 알아보려면 [사용자 (User ID)](/ko/product/pushwoosh-knowledge-hub/users-userids/)를 참조하세요.

<span id="set-up-the-events-to-track" />

## 추적할 이벤트 설정하기

Pushwoosh는 이벤트를 통해 플레이어가 무엇을 하는지 파악합니다. 이벤트를 먼저 만드세요. [세그먼트](/ko/tutorials/industry-playbooks/mobile-games/build-the-segments/)는 플레이어가 발생시킨 이벤트를 기준으로 플레이어를 그룹화하고, [Journey](/ko/tutorials/industry-playbooks/mobile-games/build-the-journeys/)는 이벤트가 발생하면 시작됩니다.

무엇이든 만들기 전에 이벤트와 그 속성을 함께 계획하세요. [게임 앱용 권장 이벤트](/ko/product/audience-data-and-segmentation/events/recommended-events-for-gaming-apps/)에는 속성이 포함된 바로 쓸 수 있는 게임 이벤트가 나와 있으며, [사용자 지정 이벤트](/ko/product/audience-data-and-segmentation/events/custom-events/)에서는 직접 이벤트를 정의하는 방법을 설명합니다.

이벤트에는 두 종류가 있습니다.

* [기본 이벤트](#default-events): 디바이스 등록, 앱 열기, 구매 등. SDK가 이 이벤트를 전송하므로 Control Panel에서 만들 필요가 없습니다.
* [사용자 지정 이벤트](#custom-events): 레벨 완료, 보상 수령, 상점 열기 등. 개발자가 [게임에서 이 이벤트를 전송](#send-the-events-from-the-game)하며, Pushwoosh는 각 이벤트가 처음 도착할 때 이를 생성합니다. 속성 유형을 직접 선택하려면 먼저 Control Panel에서 이벤트를 만드세요. [사용자 지정 이벤트](/ko/product/audience-data-and-segmentation/events/custom-events/)와 [자동으로 생성되는 이벤트](/ko/product/audience-data-and-segmentation/events/#events-created-automatically)를 참조하세요.

<span id="default-events" />

### 기본 이벤트

SDK가 이 이벤트를 대신 전송합니다. 이 플레이북의 대부분의 Journey, 즉 온보딩, 윈백, 구매 혜택에 이 이벤트가 필요합니다.

* [`PW_DeviceRegistered`](/ko/product/audience-data-and-segmentation/events/default-events/#pw_deviceregistered): 디바이스가 첫 푸시 토큰을 받았습니다. SDK는 게임이 `registerForPushNotifications`를 호출할 때만 토큰을 요청하며, 이 호출은 iOS에서 권한 요청 창도 표시합니다. 토큰은 플레이어의 응답과 관계없이 도착합니다. 게임이 첫 실행 이후에 권한을 요청하면 이벤트는 설치 시점이 아니라 그 시점에 발생합니다. 신규 플레이어를 포착하려면 대신 `Tutorial started` 이벤트를 사용하세요.
* [`PW_ApplicationOpen`](/ko/product/audience-data-and-segmentation/events/default-events/#pw_applicationopen): 플레이어가 게임을 열었습니다. 아직 플레이 중인 플레이어와 플레이를 중단한 플레이어를 찾아 다시 불러오는 데 필요합니다.
* [`PW_InAppPurchase`](/ko/product/audience-data-and-segmentation/events/default-events/#pw_inapppurchase): 플레이어가 게임에서 무언가를 구매했습니다. 결제 플레이어와 비결제 플레이어를 구분하는 데 필요합니다. 예를 들어 한 번도 결제하지 않은 플레이어에게만 첫 구매 혜택을 제공할 수 있습니다. 개발자는 iOS SDK에서 구매 추적을 켜거나 코드에서 구매를 전송하며, Android에서는 항상 코드에서 전송합니다. iOS에서는 App Store Connect에 구성된 상품에 대해서만 발생합니다.
* 선택 사항: [`PW_UserIdle`](/ko/product/audience-data-and-segmentation/events/default-events/#pw_useridle): 플레이어가 설정한 시간(최소 30초) 동안 화면을 터치하지 않으면 발생합니다. 플레이어가 막혔을 때 인앱 힌트를 표시하는 Journey를 시작합니다. 개발자가 SDK 구성에서 활성화합니다.
* 선택 사항: [`PW_ApplicationExit`](/ko/product/audience-data-and-segmentation/events/default-events/#pw_applicationexit): 플레이어가 게임을 떠나 10~30초 안에 돌아오지 않으면 발생합니다. 진행 중간에 떠난 플레이어를 위한 윈백 Journey를 시작합니다. 개발자가 SDK 구성에서 활성화합니다.

SDK가 이벤트를 처음 전송하면 해당 이벤트가 **오디언스** → **이벤트**에 표시됩니다.

다른 기본 이벤트를 목록에 미리 추가하려면(예: 게임 업데이트가 출시되기 전에 세그먼트를 만들려는 경우):

1. **오디언스** → **이벤트**를 열고 **이벤트 생성**을 클릭합니다.
2. **기본 이벤트**를 선택합니다.
3. 이벤트를 선택하고 **활성화**를 클릭합니다.

3단계의 목록에는 `PW_UserIdle`과 `PW_ApplicationExit`이 없습니다. 이 두 이벤트는 SDK가 처음 전송한 후에만 **오디언스** → **이벤트**에 표시됩니다.


이 이벤트와 기타 기본 이벤트에 대한 자세한 내용은 [기본 이벤트](/ko/product/audience-data-and-segmentation/events/default-events/)를 참조하세요.

<span id="custom-events" />

### 사용자 지정 이벤트

사용자 지정 이벤트는 레벨 완료처럼 게임에서 일어나는 일을 기록합니다. 게임에 필요한 이벤트는 사용자가 선택하고, 개발자가 전송하며, 사용자는 이벤트가 도착하는지 확인합니다.

<span id="choose-the-events-to-track" />

#### 추적할 이벤트 선택하기

게임에 필요한 이벤트와 각 이벤트가 담을 속성을 선택하세요. 예를 들어 `Level completed`에는 `level_id`가 있습니다. 표의 예시는 그대로 사용하거나, 이름을 바꾸거나, 직접 추가할 수 있습니다. 실행하는 Journey에 필요한 이벤트만 추적하세요.

| 이벤트 | 발생 시점 | 주요 속성 | 활용 |
| --- | --- | --- | --- |
| [New level](/ko/product/audience-data-and-segmentation/events/recommended-events-for-gaming-apps/#new-level) | 플레이어가 새 레벨에 도달함 | `level_id` (String) | 선택 사항: 자체 마일스톤 세그먼트 |
| [Level completed](/ko/product/audience-data-and-segmentation/events/recommended-events-for-gaming-apps/#level-completed) | 플레이어가 레벨을 완료함 | `level_id` (String) | 참여도 높은 비결제자 및 막힌 플레이어 세그먼트, 막힌 플레이어 지원 Journey |
| Level failed | 플레이어가 레벨에 실패함 | `level_id` (String) | 막힌 플레이어 세그먼트 및 Journey |
| Tutorial started | 플레이어가 게임 내 튜토리얼을 시작함 | `tutorial_name` (String) | 온보딩 Journey, 튜토리얼 이탈 세그먼트 |
| [Tutorial completed](/ko/product/audience-data-and-segmentation/events/recommended-events-for-gaming-apps/#tutorial-completed) | 플레이어가 게임 내 튜토리얼을 완료함 | `tutorial_name` (String), `completion` (Boolean) | 온보딩 Journey, 푸시 권한 흐름 |
| [Virtual currency earned](/ko/product/audience-data-and-segmentation/events/recommended-events-for-gaming-apps/#virtual-currency-earned) | 플레이어의 게임 내 재화 잔액이 늘어남 | `currency_name` (String), `quantity` (Integer) | 선택 사항: 자체 재화 기반 세그먼트 |
| [Achievement unlocked](/ko/product/audience-data-and-segmentation/events/recommended-events-for-gaming-apps/#achievement-unlocked) | 플레이어가 업적을 달성함 | `achievement_name` (String), `level` (Integer) | 업적 사냥꾼 세그먼트 |
| Daily reward claimed | 플레이어가 일일 보상을 수령함 | `day_number` (Integer) | 일일 보상 알림 Journey |
| Live event joined | 플레이어가 라이브 이벤트에 참여함 | `event_id` (String) | 라이브 이벤트 Journey의 전환 목표 |
| Store opened | 플레이어가 게임 내 상점을 엶 | `section` (String) | 상점 이탈 Journey |

<Aside type="tip" title="게임에 튜토리얼이 없나요?">
이 플레이북에서 `Tutorial started`와 `Tutorial completed`가 언급되는 모든 곳에서, 대신 모든 신규 플레이어가 처음 수행하는 두 가지 행동(예: 첫 레벨 시작과 완료)에 대한 자체 이벤트를 사용하세요.

* 첫 번째 이벤트는 온보딩 Journey를 시작하고, 두 번째 이벤트는 플레이어가 완료했음을 알립니다. `Tutorial completed`와 함께 쓰이는 `completion` 조건은 건너뛰세요.
* SDK는 자체 첫 실행 이벤트를 전송하지 않으므로, 두 이벤트 모두 게임이 전송하는 사용자 지정 이벤트여야 합니다.
</Aside>

<span id="send-the-events-from-the-game" />

#### 게임에서 이벤트 전송하기

<Aside type="caution" icon="setting" title="개발자 지원 필요">
이벤트 전송은 게임 코드를 변경하는 작업입니다. [개발자용 이벤트](/ko/developer/guides/audience-and-segmentation/events/)와 [게임 이벤트 예시](/ko/developer/guides/audience-and-segmentation/events/custom-events-examples#gaming-apps)를 개발자와 공유하세요. 개발자는 행동이 일어나는 순간 `postEvent`로 각 이벤트를 전송합니다. 구매와 보상 지급은 플레이어의 `userId`와 함께 게임 서버에서 전송해야 합니다.
</Aside>

게임이 전송할 이벤트와 각 이벤트가 담을 속성을 개발자와 합의하세요. 이벤트와 속성의 이름은 정확히 일치해야 합니다.

예를 들어, 게임은 `level_id` 속성과 함께 `Level completed`를 다음과 같이 전송합니다.

<Tabs>
<TabItem label="Android">
```java
TagsBundle attributes = new TagsBundle.Builder()
    .putString("level_id", "12")
    .build();

InAppManager.getInstance().postEvent("Level completed", attributes);
```
</TabItem>
<TabItem label="iOS">
```swift
PWInAppManager.shared().postEvent("Level completed", withAttributes: ["level_id": "12"])
```
</TabItem>
</Tabs>

게임 백엔드나 토너먼트 서비스처럼 이미 자체 웹훅을 보내는 서버에서 이벤트가 발생하는 경우, 이벤트는 `postEvent` 대신 [인바운드 웹훅](/ko/product/integrations/inbound-webhook/)을 통해 Pushwoosh에 도달할 수 있습니다. Control Panel에서 이 서버가 보내는 필드를 Pushwoosh 이벤트에 매핑하면, 해당 이벤트는 다른 이벤트처럼 Journey를 시작할 수 있습니다.

이벤트가 도착했는지 확인하려면 **오디언스** → **사용자 탐색기**를 열고 테스트 플레이어를 찾은 다음 **이벤트 기록** 탭을 여세요.


<span id="track-revenue-as-pw_conversion" />

### PW_Conversion으로 매출 추적하기

`PW_Conversion`은 모든 구매의 금액과 통화를 하나의 형식으로 기록합니다. Journey의 매출 목표와 [RFM 세분화](/ko/product/audience-data-and-segmentation/segmentation/rfm-segmentation/)의 지출 등급에 필요합니다. RFM 세분화는 플레이어를 최근 구매 시점, 구매 빈도, 구매 금액에 따라 그룹화합니다.

iOS SDK가 추적하는 구매는 `__amount`와 `__currency` 속성을 담고 있으므로 자동으로 `PW_Conversion`에 반영됩니다. Android 구매에는 다음 중 하나가 필요합니다.

* 게임이 iOS와 Android 모두에서 실행된다면, Android 구매를 SDK의 구매 메서드 대신 `postEvent`를 통해 숫자형 `__amount`와 `__currency` 속성이 있는 `PW_InAppPurchase`로 전송하도록 개발자에게 요청하세요. 그러면 동일한 자동 매핑이 두 플랫폼을 모두 처리합니다.
* 게임이 Android에서만 실행된다면, 새 코드 없이 구매를 직접 매핑하세요. 하나의 이벤트에는 매핑이 하나만 유지되므로, iOS 구매가 있는 게임에서 수동 매핑을 하면 자동 매핑이 대체됩니다.

구매를 직접 매핑하려면:

1. **오디언스** → **이벤트**를 열고 전환 이벤트 설정을 엽니다.
2. `PW_InAppPurchase`를 전환 이벤트로 추가합니다.
3. **가격**과 **통화**를 담은 속성을 선택합니다.
4. **적용**을 클릭합니다.

<Aside type="caution">
거래마다 한 가지 경로만 사용하세요. 코드에서 같은 구매에 대해 `PW_Conversion`도 전송하면 Pushwoosh는 별도의 전환 이벤트 두 개를 기록합니다.
</Aside>

모든 설정 옵션은 [전환 이벤트](/ko/product/audience-data-and-segmentation/events/conversion-events/)를 참조하세요.

<span id="track-subscriptions-from-the-stores" />

### 스토어에서 구독 추적하기

게임에서 VIP 패스나 배틀 패스 같은 구독을 판매한다면, Pushwoosh는 App Store와 Google Play에서 구독 상태 변경을 받습니다. 각 변경은 `PW_Subscription*` 이벤트로 도착합니다. 예:

* `PW_SubscriptionStart`: 플레이어가 구독합니다.
* `PW_SubscriptionCancel`: 플레이어가 자동 갱신을 끕니다.
* `PW_SubscriptionBillingIssue`: 갱신 결제가 실패합니다.

이 이벤트로 Journey를 시작하세요. 예를 들어 취소된 패스가 만료되기 전에 알림을 보낼 수 있습니다.

<Aside type="caution" icon="setting" title="개발자 지원 필요">
게임은 구매할 때마다 플레이어의 Pushwoosh HWID를 전달해야 합니다.

* iOS에서는 `appAccountToken`으로 전달합니다.
* Android에서는 `obfuscatedAccountId`로 전달합니다. 게임은 SDK의 `getSubscriptionAccountId()` 값을 전달하며, 이 값은 HWID만이 아니라 Application Code와 HWID를 합친 값입니다.

이 값이 없으면 Pushwoosh는 알림을 받지만 이벤트를 기록하지 않으며, 이전에 구매한 구독은 나중에 매칭할 수 없습니다. [App Store 구독 추적](/ko/product/integrations/app-store-subscription-tracking/)과 [Google Play 구독 추적](/ko/product/integrations/google-play-subscription-tracking/)을 개발자와 공유하세요.
</Aside>

이 이벤트는 구독만 다룹니다. 코인 팩 같은 일회성 구매는 계속 `PW_InAppPurchase`로 도착합니다.

<span id="store-player-data-in-tags" />

## 태그에 플레이어 데이터 저장

[태그](/ko/product/audience-data-and-segmentation/user-data-tags/)는 플레이어의 레벨이나 결제 여부처럼 Pushwoosh가 플레이어 프로필에 저장하는 값입니다. 이벤트는 일어난 일을 기록하고, 태그는 현재 상태를 보관합니다. 태그를 사용하면 다음을 할 수 있습니다.

* 특정 값을 가진 플레이어에게만 메시지를 보냅니다. 예를 들어 결제 플레이어에게만 혜택을 보냅니다.
* 메시지 텍스트에 값을 넣습니다. 예를 들어 플레이어의 레벨을 넣습니다. [Journey 구축](/ko/tutorials/industry-playbooks/mobile-games/build-the-journeys/)을 참조하세요.

태그는 선택 사항입니다. 이 플레이북의 Journey는 이벤트와 Pushwoosh가 직접 설정하는 기본 태그로 실행되므로, 처음에는 자체 태그를 건너뛰어도 됩니다. 플레이어를 그룹화하는 방법을 더 늘리고 싶을 때 추가하세요. [태그 기반 세그먼트](/ko/tutorials/industry-playbooks/mobile-games/build-the-segments/#segments-by-tags)를 참조하세요.

### 자체 태그

개발자가 게임에서 태그 값을 전송하거나, [CSV 파일에서 가져올](/ko/product/audience-data-and-segmentation/user-data-tags/update-tags-via-csv/) 수 있습니다. 개발자가 태그를 처음 전송하면 Pushwoosh는 이를 User-specific 태그로 생성합니다. 태그 유형을 직접 선택하려면 먼저 Control Panel에서 태그를 만드세요. [태그로 사용자 데이터 관리하기](/ko/product/audience-data-and-segmentation/user-data-tags/tags/)를 참조하세요.

다음 태그는 예시입니다. 게임의 용어에 맞게 이름을 바꾸고 직접 추가하세요.

| 태그 | 유형 | 예시 | 활용 |
| --- | --- | --- | --- |
| `player_level` | Integer | `12` | 진행 단계별로 메시지 필터링 |
| `is_paying_user` | Boolean | `true` | 결제 플레이어와 비결제 플레이어용 메시지 분리 |
| `soft_currency_balance` | Integer | `1500` | 잔액이 적은 플레이어에게 재화 팩 제안 |
| `vip_tier` | String | `gold` | VIP 플레이어에게 전용 혜택과 얼리 액세스 제공 |
| `favorite_mode` | String | `pvp` | 플레이어가 좋아하는 모드의 라이브 이벤트 공지 |

Control Panel에서 태그를 만들 때는 기본값대로 [**사용자별**](/ko/product/audience-data-and-segmentation/user-data-tags/tags/#tag-scope-general-vs-user-specific)을 켜 둔 상태로 유지하세요. 그러면 Pushwoosh는 User ID마다 하나의 값을 보관하므로, 값은 플레이어의 디바이스 중 하나가 아니라 플레이어에게 속합니다. **사용자별**을 끄면 각 디바이스가 자체 값을 보관합니다. [User ID로 플레이어 식별하기](/ko/tutorials/industry-playbooks/mobile-games/collect-player-data/#identify-players-by-user-id)를 참조하세요.

### 기본 태그

Pushwoosh는 모든 디바이스에 대해 다음 [기본 태그](/ko/product/audience-data-and-segmentation/user-data-tags/tags/#default-tags)를 저장하므로 직접 만들 필요가 없습니다.

* **Language**: 디바이스의 언어입니다. Pushwoosh는 이를 사용해 각 플레이어에게 해당 언어로 된 메시지를 보냅니다.
* **Last Application Open**: 디바이스에서 게임을 마지막으로 연 시점입니다. 플레이를 중단한 플레이어를 찾는 데 사용하세요.
* **Push Alerts Enabled**: 디바이스 설정에서 알림이 허용되어 있는지 여부입니다. 아직 알림을 허용하지 않은 플레이어에게만 인앱 메시지를 표시하는 데 사용하세요.
* **First Install**: 디바이스에 게임을 처음 설치한 시점입니다. 설치 기념일에 사용하세요.
* **Country**: 디바이스의 국가입니다. 한 지역의 플레이어에게만 혜택이나 라이브 이벤트 공지를 보내는 데 사용하세요.