# Сбор данных об игроках

Pushwoosh должен знать, кто ваши игроки и что они делают в игре. События фиксируют действия, а теги хранят текущее состояние каждого игрока.

<Aside type="tip" title="Поручите AI Assistant создать события и теги">
[AI Assistant](/ru/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](/ru/developer/first-steps/collecting-user-ids/#setuserid-sdk-method) с вашими разработчиками.
</Aside>

Pushwoosh связывает все устройства игрока с одним User ID, поэтому ваши сегменты и Journey считают одного человека одним игроком. События и User-specific теги, которые устройство записало до входа игрока в аккаунт, остаются за его прежним ID. Device-specific теги переходят вместе с устройством.

По умолчанию Pushwoosh использует аппаратный ID устройства (HWID) в качестве его User ID. Тогда игрок, который играет на двух устройствах, считается двумя игроками. Чтобы этого не происходило с игроками, которые входят в аккаунт, установите в качестве их User ID ваш собственный ID аккаунта:

1. Выберите ID. Возьмите ID аккаунта, который ваша игра уже присваивает каждому игроку.
2. Попросите разработчиков вызывать `setUserId` с этим ID, когда игрок входит в аккаунт.
3. Проверьте результат. Войдите в игру на тестовом устройстве, затем откройте **Аудитория** → **Карточка пользователя**, выберите поиск по **ID пользователя** и введите ID аккаунта. Откроется профиль игрока.

Игроки, которые никогда не входят в аккаунт, сохраняют HWID в качестве User ID, и Pushwoosh устанавливает его за них.

Подробнее о том, как User ID связаны с устройствами, читайте в статье [Пользователи (User ID)](/ru/product/pushwoosh-knowledge-hub/users-userids/).

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

## Настройка отслеживаемых событий

Через события Pushwoosh узнаёт, что делает игрок. Создайте их в первую очередь: [сегменты](/ru/tutorials/industry-playbooks/mobile-games/build-the-segments/) группируют игроков по событиям, которые они вызвали, а [Journey](/ru/tutorials/industry-playbooks/mobile-games/build-the-journeys/) запускаются, когда происходит событие.

Спланируйте и события, и их атрибуты, прежде чем что-либо строить. В статье [Рекомендуемые события для игровых приложений](/ru/product/audience-data-and-segmentation/events/recommended-events-for-gaming-apps/) перечислены готовые игровые события с атрибутами, а в статье [Пользовательские события](/ru/product/audience-data-and-segmentation/events/custom-events/) объясняется, как определить свои.

События бывают двух видов:

* [События по умолчанию](#default-events): регистрация устройства, открытие приложения, покупка и ещё несколько. Их отправляет SDK, и создавать их в Control Panel не нужно.
* [Пользовательские события](#custom-events): уровень пройден, награда получена, магазин открыт и другие. Ваши разработчики [отправляют их из игры](#send-the-events-from-the-game), а Pushwoosh создаёт каждое событие, когда оно приходит впервые. Чтобы самостоятельно выбрать типы атрибутов, сначала создайте событие в Control Panel. См. [Пользовательские события](/ru/product/audience-data-and-segmentation/events/custom-events/) и [Автоматически создаваемые события](/ru/product/audience-data-and-segmentation/events/#events-created-automatically).

<span id="default-events" />

### События по умолчанию

SDK отправляет эти события за вас. Они нужны для большинства Journey в этом плейбуке: онбординга, возврата игроков и предложений о покупке.

* [`PW_DeviceRegistered`](/ru/product/audience-data-and-segmentation/events/default-events/#pw_deviceregistered): устройство получило свой первый push-токен. SDK запрашивает токен, только когда игра вызывает `registerForPushNotifications`, что на iOS также показывает запрос разрешения, и токен приходит независимо от ответа игрока. Если игра запрашивает разрешение не при первом запуске, а позже, событие срабатывает в этот момент, а не при установке. Чтобы отлавливать новых игроков, используйте вместо него событие `Tutorial started`.
* [`PW_ApplicationOpen`](/ru/product/audience-data-and-segmentation/events/default-events/#pw_applicationopen): игрок открыл игру. Оно нужно, чтобы находить игроков, которые продолжают играть, и тех, кто перестал, чтобы вернуть их.
* [`PW_InAppPurchase`](/ru/product/audience-data-and-segmentation/events/default-events/#pw_inapppurchase): игрок что-то купил в игре. Оно нужно, чтобы отличать платящих игроков от неплатящих, например чтобы предлагать первую покупку только тем, кто ещё ни разу не платил. На iOS разработчики включают отслеживание покупок в SDK или отправляют покупки из кода, а на Android всегда отправляют их из кода. На iOS событие срабатывает только для продуктов, настроенных в App Store Connect.
* Необязательно: [`PW_UserIdle`](/ru/product/audience-data-and-segmentation/events/default-events/#pw_useridle): срабатывает, когда игрок перестаёт касаться экрана на заданное вами время, не меньше 30 секунд. Запускает Journey, который показывает in-app подсказку, когда игрок застрял. Разработчики включают его в конфигурации SDK.
* Необязательно: [`PW_ApplicationExit`](/ru/product/audience-data-and-segmentation/events/default-events/#pw_applicationexit): срабатывает, когда игрок выходит из игры и не возвращается в течение 10–30 секунд. Запускает Journey возврата для игроков, которые уходят посреди сценария. Разработчики включают его в конфигурации SDK.

Событие появляется в разделе **Аудитория** → **События** после того, как SDK отправит его впервые.

Чтобы добавить в список любое другое событие по умолчанию заранее, например чтобы построить сегмент до выхода обновления игры:

1. Откройте **Аудитория** → **События** и нажмите **Создать событие**.
2. Выберите **Событие по умолчанию**.
3. Выберите событие и нажмите **Активировать**.

Список на шаге 3 не содержит `PW_UserIdle` и `PW_ApplicationExit`. Они появляются в разделе **Аудитория** → **События** только после того, как SDK отправит их впервые.


Подробнее об этих и других событиях по умолчанию читайте в статье [События по умолчанию](/ru/product/audience-data-and-segmentation/events/default-events/).

<span id="custom-events" />

### Пользовательские события

Пользовательские события фиксируют то, что происходит в игре, например прохождение уровня. Вы выбираете, какие события нужны игре, разработчики их отправляют, а вы проверяете, что они приходят.

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

#### Выбор отслеживаемых событий

Выберите события, которые нужны вашей игре, и атрибуты каждого из них, например `level_id` для `Level completed`. В таблице приведены примеры: используйте их как есть, переименуйте или добавьте свои. Отслеживайте только те события, которые нужны запускаемым вами Journey.

| Событие | Когда срабатывает | Ключевые атрибуты | Для чего нужно |
| --- | --- | --- | --- |
| [New level](/ru/product/audience-data-and-segmentation/events/recommended-events-for-gaming-apps/#new-level) | Игрок достигает нового уровня | `level_id` (String) | Необязательно: ваши собственные сегменты по этапам |
| [Level completed](/ru/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](/ru/product/audience-data-and-segmentation/events/recommended-events-for-gaming-apps/#tutorial-completed) | Игрок завершает обучение в игре | `tutorial_name` (String), `completion` (Boolean) | Journey онбординга, сценарий запроса разрешения на push |
| [Virtual currency earned](/ru/product/audience-data-and-segmentation/events/recommended-events-for-gaming-apps/#virtual-currency-earned) | Баланс игровой валюты игрока пополняется | `currency_name` (String), `quantity` (Integer) | Необязательно: ваши собственные сегменты по валюте |
| [Achievement unlocked](/ru/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 | Игрок присоединяется к live-ивенту | `event_id` (String) | Цель конверсии в Journey live-ивента |
| Store opened | Игрок открывает игровой магазин | `section` (String) | Journey для ушедших из магазина без покупки |

<Aside type="tip" title="В вашей игре нет обучения?">
Используйте собственные события для двух первых действий каждого нового игрока, например начала и прохождения первого уровня, вместо `Tutorial started` и `Tutorial completed` везде, где о них говорится в этом плейбуке.

* Первое событие запускает Journey онбординга, а второе сообщает ему, что игрок закончил. Пропустите условие `completion`, которое идёт вместе с `Tutorial completed`.
* SDK не отправляют собственного события первого запуска, поэтому оба события должны быть пользовательскими и отправляться вашей игрой.
</Aside>

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

#### Отправка событий из игры

<Aside type="caution" icon="setting" title="Требуется помощь разработчика">
Отправка событий — это изменение в коде игры. Поделитесь страницами [События для разработчиков](/ru/developer/guides/audience-and-segmentation/events/) и [примеры игровых событий](/ru/developer/guides/audience-and-segmentation/events/custom-events-examples#gaming-apps) с вашими разработчиками. Они отправляют каждое событие через `postEvent` в момент, когда происходит действие. Покупки и начисление наград должны приходить с игрового сервера вместе с `userId` игрока.
</Aside>

Договоритесь с разработчиками, какие события отправляет игра и какие атрибуты есть у каждого из них. Названия событий и атрибутов должны совпадать в точности.

Например, так игра отправляет `Level completed` с атрибутом `level_id`:

<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>

Если событие происходит на сервере, который уже отправляет собственные веб-хуки, например на бэкенде игры или в сервисе турниров, оно может попасть в Pushwoosh через [входящий веб-хук](/ru/product/integrations/inbound-webhook/), а не через `postEvent`. Вы сопоставляете присылаемые им поля с событием Pushwoosh в Control Panel, и это событие может запускать Journey, как любое другое.

Чтобы проверить, что событие пришло, откройте **Аудитория** → **Карточка пользователя**, найдите тестового игрока и откройте вкладку **История событий**.


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

### Отслеживание выручки через PW_Conversion

`PW_Conversion` записывает сумму и валюту каждой покупки в едином формате. Оно нужно для цели по выручке в Journey и для уровней трат в [RFM-сегментации](/ru/product/audience-data-and-segmentation/segmentation/rfm-segmentation/), которая группирует игроков по давности, частоте и сумме покупок.

Покупки, которые отслеживает iOS SDK, попадают в `PW_Conversion` сами, потому что содержат атрибуты `__amount` и `__currency`. Для покупок на Android нужен один из вариантов:

* Если ваша игра работает и на iOS, и на Android, попросите разработчиков отправлять покупки на Android как `PW_InAppPurchase` с числовыми атрибутами `__amount` и `__currency` через `postEvent` вместо метода покупки из SDK. Тогда одно и то же автоматическое сопоставление охватит обе платформы.
* Если ваша игра работает только на Android, сопоставьте покупки сами, без нового кода. У события может быть только одно сопоставление, поэтому в игре с покупками на iOS ручное сопоставление заменило бы автоматическое.

Чтобы сопоставить покупки самостоятельно:

1. Откройте **Аудитория** → **События** и откройте настройки конверсионных событий.
2. Добавьте `PW_InAppPurchase` в качестве конверсионного события.
3. Выберите атрибуты, в которых хранятся **Цена** и **Валюта**.
4. Нажмите **Применить**.

<Aside type="caution">
Используйте только один способ для каждой транзакции. Если ваш код также отправляет `PW_Conversion` для той же покупки, Pushwoosh запишет два отдельных конверсионных события.
</Aside>

Все варианты настройки описаны в статье [События-конверсии](/ru/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`. Игра передаёт значение `getSubscriptionAccountId()` из SDK, то есть Application Code вместе с HWID, а не один HWID.

Без этого Pushwoosh получает уведомление, но не записывает событие, а подписки, купленные раньше, потом не удастся сопоставить. Поделитесь статьями [Отслеживание подписок из App Store](/ru/product/integrations/app-store-subscription-tracking/) и [Отслеживание подписок Google Play](/ru/product/integrations/google-play-subscription-tracking/) с вашими разработчиками.
</Aside>

Эти события касаются только подписок. Разовые покупки, например набор монет, по-прежнему приходят как `PW_InAppPurchase`.

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

## Хранение данных об игроках в тегах

[Тег](/ru/product/audience-data-and-segmentation/user-data-tags/) — это значение, которое Pushwoosh хранит в профиле игрока, например уровень игрока или то, платил ли он. Событие фиксирует, что произошло, а тег хранит текущее состояние. Теги помогают:

* Отправлять сообщение только игрокам с определённым значением, например предложение только платящим игрокам.
* Подставлять значение в текст сообщения, например уровень игрока. См. [Создание Journey](/ru/tutorials/industry-playbooks/mobile-games/build-the-journeys/).

Теги необязательны. Journey в этом плейбуке работают на событиях и на тегах по умолчанию, которые Pushwoosh устанавливает сам, поэтому поначалу можно обойтись без собственных тегов. Добавьте их, когда понадобится больше способов группировать игроков. См. [Сегменты по тегам](/ru/tutorials/industry-playbooks/mobile-games/build-the-segments/#segments-by-tags).

### Ваши собственные теги

Разработчики отправляют значения тегов из игры, или вы можете [импортировать их из CSV-файла](/ru/product/audience-data-and-segmentation/user-data-tags/update-tags-via-csv/). Pushwoosh создаёт тег, когда разработчики отправляют его впервые, как User-specific тег. Если хотите сами выбрать тип тега, сначала создайте его в Control Panel. См. [Управление данными пользователей с помощью тегов](/ru/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` | Анонсировать live-ивенты для режима, который нравится игроку |

Когда создаёте тег в Control Panel, оставьте [**Для пользователя**](/ru/product/audience-data-and-segmentation/user-data-tags/tags/#tag-scope-general-vs-user-specific) включённым, как это сделано по умолчанию. Тогда Pushwoosh хранит одно значение на каждый User ID, и значение принадлежит игроку, а не одному из его устройств. Если **Для пользователя** выключено, каждое устройство хранит собственное значение. См. [Идентификация игроков по User ID](/ru/tutorials/industry-playbooks/mobile-games/collect-player-data/#identify-players-by-user-id).

### Теги по умолчанию

Pushwoosh хранит эти [теги по умолчанию](/ru/product/audience-data-and-segmentation/user-data-tags/tags/#default-tags) для каждого устройства, поэтому создавать их не нужно:

* **Language**: язык устройства. Pushwoosh использует его, чтобы отправлять каждому игроку сообщение на его языке.
* **Last Application Open**: когда игру последний раз открывали на устройстве. Используйте его, чтобы находить игроков, которые перестали играть.
* **Push Alerts Enabled**: разрешены ли уведомления в настройках устройства. Используйте его, чтобы показывать in-app сообщение только игрокам, которые ещё не разрешили уведомления.
* **First Install**: когда игру впервые установили на устройство. Используйте его для годовщин установки.
* **Country**: страна устройства. Используйте его, чтобы отправлять предложение или анонс live-ивента только игрокам из одного региона.